Mark Wielaard f51111
commit 595341b150312d2407bd43304449bf39ec3e1fa8
Mark Wielaard f51111
Author: Julian Seward <jseward@acm.org>
Mark Wielaard f51111
Date:   Sat Nov 13 19:59:07 2021 +0100
Mark Wielaard f51111
Mark Wielaard f51111
    amd64 front end: add more spec rules:
Mark Wielaard f51111
    
Mark Wielaard f51111
       S  after SHRQ
Mark Wielaard f51111
       Z  after SHLQ
Mark Wielaard f51111
       NZ after SHLQ
Mark Wielaard f51111
       Z  after SHLL
Mark Wielaard f51111
       S  after SHLL
Mark Wielaard f51111
    
Mark Wielaard f51111
    The lack of at least one of these was observed to cause occasional false
Mark Wielaard f51111
    positives in Memcheck.
Mark Wielaard f51111
    
Mark Wielaard f51111
    Plus add commented-out cases so as to complete the set of 12 rules
Mark Wielaard f51111
    {Z,NZ,S,NS} after {SHRQ,SHLQ,SHLL}.  The commented-out ones are commented
Mark Wielaard f51111
    out because I so far didn't find any use cases for them.
Mark Wielaard f51111
Mark Wielaard f51111
diff --git a/VEX/priv/guest_amd64_helpers.c b/VEX/priv/guest_amd64_helpers.c
Mark Wielaard f51111
index 9d61e7a0f..ba71c1b62 100644
Mark Wielaard f51111
--- a/VEX/priv/guest_amd64_helpers.c
Mark Wielaard f51111
+++ b/VEX/priv/guest_amd64_helpers.c
Mark Wielaard f51111
@@ -1823,16 +1823,26 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name,
Mark Wielaard f51111
       /*---------------- SHRQ ----------------*/
Mark Wielaard f51111
 
Mark Wielaard f51111
       if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondZ)) {
Mark Wielaard f51111
-         /* SHRQ, then Z --> test dep1 == 0 */
Mark Wielaard f51111
+         /* SHRQ, then Z --> test result[63:0] == 0 */
Mark Wielaard f51111
          return unop(Iop_1Uto64,
Mark Wielaard f51111
                      binop(Iop_CmpEQ64, cc_dep1, mkU64(0)));
Mark Wielaard f51111
       }
Mark Wielaard f51111
       if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondNZ)) {
Mark Wielaard f51111
-         /* SHRQ, then NZ --> test dep1 != 0 */
Mark Wielaard f51111
+         /* SHRQ, then NZ --> test result[63:0] != 0 */
Mark Wielaard f51111
          return unop(Iop_1Uto64,
Mark Wielaard f51111
                      binop(Iop_CmpNE64, cc_dep1, mkU64(0)));
Mark Wielaard f51111
       }
Mark Wielaard f51111
 
Mark Wielaard f51111
+      if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondS)) {
Mark Wielaard f51111
+         /* SHRQ, then S --> (ULong)result[63] (result is in dep1) */
Mark Wielaard f51111
+         return binop(Iop_Shr64, cc_dep1, mkU8(63));
Mark Wielaard f51111
+      }
Mark Wielaard f51111
+      // No known test case for this, hence disabled:
Mark Wielaard f51111
+      //if (isU64(cc_op, AMD64G_CC_OP_SHRQ) && isU64(cond, AMD64CondNS)) {
Mark Wielaard f51111
+      //   /* SHRQ, then NS --> (ULong) ~ result[63] */
Mark Wielaard f51111
+      //   vassert(0);
Mark Wielaard f51111
+      //}
Mark Wielaard f51111
+
Mark Wielaard f51111
       /*---------------- SHRL ----------------*/
Mark Wielaard f51111
 
Mark Wielaard f51111
       if (isU64(cc_op, AMD64G_CC_OP_SHRL) && isU64(cond, AMD64CondZ)) {
Mark Wielaard f51111
@@ -1881,6 +1891,52 @@ IRExpr* guest_amd64_spechelper ( const HChar* function_name,
Mark Wielaard f51111
       //                     mkU32(0)));
Mark Wielaard f51111
       //}
Mark Wielaard f51111
 
Mark Wielaard f51111
+      /*---------------- SHLQ ----------------*/
Mark Wielaard f51111
+
Mark Wielaard f51111
+      if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondZ)) {
Mark Wielaard f51111
+         /* SHLQ, then Z --> test dep1 == 0 */
Mark Wielaard f51111
+         return unop(Iop_1Uto64,
Mark Wielaard f51111
+                     binop(Iop_CmpEQ64, cc_dep1, mkU64(0)));
Mark Wielaard f51111
+      }
Mark Wielaard f51111
+      if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondNZ)) {
Mark Wielaard f51111
+         /* SHLQ, then NZ --> test dep1 != 0 */
Mark Wielaard f51111
+         return unop(Iop_1Uto64,
Mark Wielaard f51111
+                     binop(Iop_CmpNE64, cc_dep1, mkU64(0)));
Mark Wielaard f51111
+      }
Mark Wielaard f51111
+
Mark Wielaard f51111
+      //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondS)) {
Mark Wielaard f51111
+      //   /* SHLQ, then S --> (ULong)result[63] */
Mark Wielaard f51111
+      //   vassert(0);
Mark Wielaard f51111
+      //}
Mark Wielaard f51111
+      //if (isU64(cc_op, AMD64G_CC_OP_SHLQ) && isU64(cond, AMD64CondNS)) {
Mark Wielaard f51111
+      //   /* SHLQ, then NS --> (ULong) ~ result[63] */
Mark Wielaard f51111
+      //   vassert(0);
Mark Wielaard f51111
+      //}
Mark Wielaard f51111
+
Mark Wielaard f51111
+      /*---------------- SHLL ----------------*/
Mark Wielaard f51111
+
Mark Wielaard f51111
+      if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondZ)) {
Mark Wielaard f51111
+         /* SHLL, then Z --> test result[31:0] == 0 */
Mark Wielaard f51111
+         return unop(Iop_1Uto64,
Mark Wielaard f51111
+                     binop(Iop_CmpEQ32, unop(Iop_64to32, cc_dep1),
Mark Wielaard f51111
+                           mkU32(0)));
Mark Wielaard f51111
+      }
Mark Wielaard f51111
+      //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNZ)) {
Mark Wielaard f51111
+      //   /* SHLL, then NZ --> test dep1 != 0 */
Mark Wielaard f51111
+      //   vassert(0);
Mark Wielaard f51111
+      //}
Mark Wielaard f51111
+
Mark Wielaard f51111
+      if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondS)) {
Mark Wielaard f51111
+         /* SHLL, then S --> (ULong)result[31] */
Mark Wielaard f51111
+         return binop(Iop_And64,
Mark Wielaard f51111
+                      binop(Iop_Shr64, cc_dep1, mkU8(31)),
Mark Wielaard f51111
+                      mkU64(1));
Mark Wielaard f51111
+      }
Mark Wielaard f51111
+      //if (isU64(cc_op, AMD64G_CC_OP_SHLL) && isU64(cond, AMD64CondNS)) {
Mark Wielaard f51111
+      //   /* SHLL, then NS --> (ULong) ~ result[31] */
Mark Wielaard f51111
+      //   vassert(0);
Mark Wielaard f51111
+      //}
Mark Wielaard f51111
+
Mark Wielaard f51111
       /*---------------- COPY ----------------*/
Mark Wielaard f51111
       /* This can happen, as a result of amd64 FP compares: "comisd ... ;
Mark Wielaard f51111
          jbe" for example. */