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