7a6b42
commit 4271989815b5fc933c1e29bc75507c2726dc3738
7a6b42
Author: Julian Seward <jseward@acm.org>
7a6b42
Date:   Tue Nov 20 10:52:33 2018 +0100
7a6b42
7a6b42
    Add some new IROps to support improved Memcheck analysis of strlen etc.
7a6b42
    
7a6b42
    This is part of the fix for bug 386945.  It adds the following IROps, plus
7a6b42
    their supporting type- and printing- fragments:
7a6b42
    
7a6b42
    Iop_Reverse8sIn32_x1: 32-bit byteswap.  A fancy name, but it is consistent
7a6b42
    with naming for the other swapping IROps that already exist.
7a6b42
    
7a6b42
    Iop_PopCount64, Iop_PopCount32: population count
7a6b42
    
7a6b42
    Iop_ClzNat64, Iop_ClzNat32, Iop_CtzNat64, Iop_CtzNat32: counting leading and
7a6b42
    trailing zeroes, with "natural" (Nat) semantics for a zero input, meaning, in
7a6b42
    the case of zero input, return the number of bits in the word.  These
7a6b42
    functionally overlap with the existing Iop_Clz64, Iop_Clz32, Iop_Ctz64,
7a6b42
    Iop_Ctz32.  The existing operations are undefined in case of a zero input.
7a6b42
    Adding these new variants avoids the complexity of having to change the
7a6b42
    declared semantics of the existing operations.  Instead they are deprecated
7a6b42
    but still available for use.
7a6b42
7a6b42
diff --git a/VEX/priv/ir_defs.c b/VEX/priv/ir_defs.c
7a6b42
index 823b6be..3221033 100644
7a6b42
--- a/VEX/priv/ir_defs.c
7a6b42
+++ b/VEX/priv/ir_defs.c
7a6b42
@@ -194,6 +194,14 @@ void ppIROp ( IROp op )
7a6b42
       case Iop_Ctz64:    vex_printf("Ctz64"); return;
7a6b42
       case Iop_Ctz32:    vex_printf("Ctz32"); return;
7a6b42
 
7a6b42
+      case Iop_ClzNat64: vex_printf("ClzNat64"); return;
7a6b42
+      case Iop_ClzNat32: vex_printf("ClzNat32"); return;
7a6b42
+      case Iop_CtzNat64: vex_printf("CtzNat64"); return;
7a6b42
+      case Iop_CtzNat32: vex_printf("CtzNat32"); return;
7a6b42
+
7a6b42
+      case Iop_PopCount64: vex_printf("PopCount64"); return;
7a6b42
+      case Iop_PopCount32: vex_printf("PopCount32"); return;
7a6b42
+
7a6b42
       case Iop_CmpLT32S: vex_printf("CmpLT32S"); return;
7a6b42
       case Iop_CmpLE32S: vex_printf("CmpLE32S"); return;
7a6b42
       case Iop_CmpLT32U: vex_printf("CmpLT32U"); return;
7a6b42
@@ -395,6 +403,7 @@ void ppIROp ( IROp op )
7a6b42
 
7a6b42
       case Iop_CmpNEZ16x2: vex_printf("CmpNEZ16x2"); return;
7a6b42
       case Iop_CmpNEZ8x4:  vex_printf("CmpNEZ8x4"); return;
7a6b42
+      case Iop_Reverse8sIn32_x1: vex_printf("Reverse8sIn32_x1"); return;
7a6b42
 
7a6b42
       case Iop_CmpF64:    vex_printf("CmpF64"); return;
7a6b42
 
7a6b42
@@ -2719,6 +2728,7 @@ void typeOfPrimop ( IROp op,
7a6b42
          UNARY(Ity_I16, Ity_I16);
7a6b42
       case Iop_Not32:
7a6b42
       case Iop_CmpNEZ16x2: case Iop_CmpNEZ8x4:
7a6b42
+      case Iop_Reverse8sIn32_x1:
7a6b42
          UNARY(Ity_I32, Ity_I32);
7a6b42
 
7a6b42
       case Iop_Not64:
7a6b42
@@ -2782,9 +2792,13 @@ void typeOfPrimop ( IROp op,
7a6b42
          BINARY(Ity_I64,Ity_I64, Ity_I128);
7a6b42
 
7a6b42
       case Iop_Clz32: case Iop_Ctz32:
7a6b42
+      case Iop_ClzNat32: case Iop_CtzNat32:
7a6b42
+      case Iop_PopCount32:
7a6b42
          UNARY(Ity_I32, Ity_I32);
7a6b42
 
7a6b42
       case Iop_Clz64: case Iop_Ctz64:
7a6b42
+      case Iop_ClzNat64: case Iop_CtzNat64:
7a6b42
+      case Iop_PopCount64:
7a6b42
          UNARY(Ity_I64, Ity_I64);
7a6b42
 
7a6b42
       case Iop_DivU32: case Iop_DivS32: case Iop_DivU32E: case Iop_DivS32E:
7a6b42
diff --git a/VEX/pub/libvex_ir.h b/VEX/pub/libvex_ir.h
7a6b42
index 17bcb55..93fa5ac 100644
7a6b42
--- a/VEX/pub/libvex_ir.h
7a6b42
+++ b/VEX/pub/libvex_ir.h
7a6b42
@@ -452,12 +452,21 @@ typedef
7a6b42
       Iop_MullS8, Iop_MullS16, Iop_MullS32, Iop_MullS64,
7a6b42
       Iop_MullU8, Iop_MullU16, Iop_MullU32, Iop_MullU64,
7a6b42
 
7a6b42
-      /* Wierdo integer stuff */
7a6b42
+      /* Counting bits */
7a6b42
+      /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of zero.
7a6b42
+         You must ensure they are never given a zero argument.  As of
7a6b42
+         2018-Nov-14 they are deprecated.  Try to use the Nat variants
7a6b42
+         immediately below, if you can.
7a6b42
+      */
7a6b42
       Iop_Clz64, Iop_Clz32,   /* count leading zeroes */
7a6b42
       Iop_Ctz64, Iop_Ctz32,   /* count trailing zeros */
7a6b42
-      /* Ctz64/Ctz32/Clz64/Clz32 are UNDEFINED when given arguments of
7a6b42
-         zero.  You must ensure they are never given a zero argument.
7a6b42
-      */
7a6b42
+      /* Count leading/trailing zeroes, with "natural" semantics for the
7a6b42
+         case where the input is zero: then the result is the number of bits
7a6b42
+         in the word. */
7a6b42
+      Iop_ClzNat64, Iop_ClzNat32,
7a6b42
+      Iop_CtzNat64, Iop_CtzNat32,
7a6b42
+      /* Population count -- compute the number of 1 bits in the argument. */
7a6b42
+      Iop_PopCount64, Iop_PopCount32,
7a6b42
 
7a6b42
       /* Standard integer comparisons */
7a6b42
       Iop_CmpLT32S, Iop_CmpLT64S,
7a6b42
@@ -831,6 +840,9 @@ typedef
7a6b42
       /* MISC (vector integer cmp != 0) */
7a6b42
       Iop_CmpNEZ16x2, Iop_CmpNEZ8x4,
7a6b42
 
7a6b42
+      /* Byte swap in a 32-bit word */
7a6b42
+      Iop_Reverse8sIn32_x1,
7a6b42
+
7a6b42
       /* ------------------ 64-bit SIMD FP ------------------------ */
7a6b42
 
7a6b42
       /* Convertion to/from int */
7a6b42
@@ -1034,8 +1046,9 @@ typedef
7a6b42
       Iop_Slice64,  // (I64, I64, I8) -> I64
7a6b42
 
7a6b42
       /* REVERSE the order of chunks in vector lanes.  Chunks must be
7a6b42
-         smaller than the vector lanes (obviously) and so may be 8-,
7a6b42
-         16- and 32-bit in size. */
7a6b42
+         smaller than the vector lanes (obviously) and so may be 8-, 16- and
7a6b42
+         32-bit in size.  Note that the degenerate case,
7a6b42
+         Iop_Reverse8sIn64_x1, is a simply a vanilla byte-swap. */
7a6b42
       /* Examples:
7a6b42
             Reverse8sIn16_x4([a,b,c,d,e,f,g,h]) = [b,a,d,c,f,e,h,g]
7a6b42
             Reverse8sIn32_x2([a,b,c,d,e,f,g,h]) = [d,c,b,a,h,g,f,e]