]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
A few more x86 eflags-helper rewrite cases, which further reduce the
authorJulian Seward <jseward@acm.org>
Mon, 15 May 2006 12:23:17 +0000 (12:23 +0000)
committerJulian Seward <jseward@acm.org>
Mon, 15 May 2006 12:23:17 +0000 (12:23 +0000)
false error rate of memcheck on optimised code.

git-svn-id: svn://svn.valgrind.org/vex/trunk@1618

VEX/priv/guest-x86/ghelpers.c

index 13475ff8d558c0504a609674a1bb2d135ccb7d8d..ce38a87956a743cd98cb8f529a002e53a418315d 100644 (file)
@@ -946,6 +946,15 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
                       binop(Iop_Shr32,cc_dep1,mkU8(31)),
                       mkU32(1));
       }
+      if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondNS)) {
+         /* see comment below for (LOGICB, CondNS) */
+         /* long and/or/xor, then S --> (UInt) ~ result[31] */
+         return binop(Iop_Xor32,
+                binop(Iop_And32,
+                      binop(Iop_Shr32,cc_dep1,mkU8(31)),
+                      mkU32(1)),
+                mkU32(1));
+      }
 
       /*---------------- LOGICW ----------------*/
 
@@ -963,6 +972,17 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
                       binop(Iop_Shr32,cc_dep1,mkU8(15)),
                       mkU32(1));
       }
+      //Probably correct, but no test case for it yet found
+      //if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondNS)) {
+      //   /* see comment below for (LOGICB, CondNS) */
+      //   /* word and/or/xor, then S --> (UInt) ~ result[15] */
+      //   vassert(0+0);
+      //   return binop(Iop_Xor32,
+      //          binop(Iop_And32,
+      //                binop(Iop_Shr32,cc_dep1,mkU8(15)),
+      //                mkU32(1)),
+      //          mkU32(1));
+      //}
 
       /*---------------- LOGICB ----------------*/
 
@@ -973,6 +993,15 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
                                         mkU32(0)));
       }
 
+      if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNZ)) {
+         /* byte and/or/xor, then Z --> test dst!=0 */
+         /* b9ac9:       84 c0                   test   %al,%al
+            b9acb:       75 0d                   jne    b9ada */
+         return unop(Iop_1Uto32,
+                     binop(Iop_CmpNE32, binop(Iop_And32,cc_dep1,mkU32(255)), 
+                                        mkU32(0)));
+      }
+
       if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondS)) {
          /* this is an idiom gcc sometimes uses to find out if the top
             bit of a byte register is set: eg testb %al,%al; js ..
@@ -985,6 +1014,15 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
                       binop(Iop_Shr32,cc_dep1,mkU8(7)),
                       mkU32(1));
       }
+      if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondNS)) {
+         /* ditto, for negation-of-S. */
+         /* byte and/or/xor, then S --> (UInt) ~ result[7] */
+         return binop(Iop_Xor32,
+                binop(Iop_And32,
+                      binop(Iop_Shr32,cc_dep1,mkU8(7)),
+                      mkU32(1)),
+                mkU32(1));
+      }
 
       /*---------------- DECL ----------------*/
 
@@ -998,6 +1036,17 @@ IRExpr* guest_x86_spechelper ( HChar* function_name,
          return unop(Iop_1Uto32,binop(Iop_CmpLT32S, cc_dep1, mkU32(0)));
       }
 
+      /*---------------- INCW ----------------*/
+
+      if (isU32(cc_op, X86G_CC_OP_INCW) && isU32(cond, X86CondZ)) {
+         /* This rewrite helps memcheck on 'incw %ax ; je ...'. */
+         /* inc W, then Z --> test dst == 0 */
+         return unop(Iop_1Uto32,
+                     binop(Iop_CmpEQ32, 
+                           binop(Iop_Shl32,cc_dep1,mkU8(16)),
+                           mkU32(0)));
+      }
+
       /*---------------- SHRL ----------------*/
 
       if (isU32(cc_op, X86G_CC_OP_SHRL) && isU32(cond, X86CondZ)) {