]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
More tuning of the eflags machinery.
authorJulian Seward <jseward@acm.org>
Sun, 23 Jan 2005 11:39:02 +0000 (11:39 +0000)
committerJulian Seward <jseward@acm.org>
Sun, 23 Jan 2005 11:39:02 +0000 (11:39 +0000)
git-svn-id: svn://svn.valgrind.org/vex/trunk@739

VEX/priv/guest-x86/ghelpers.c

index 6e1b746ff091cbcd3b5bd8fdc2eed3e12fc3a0bb..80265834ddee1b132f8b4531d339a448a79c3ac5 100644 (file)
@@ -765,6 +765,12 @@ IRExpr* guest_x86_spechelper ( Char* function_name,
                      binop(Iop_CmpEQ32, cc_dep1, cc_dep2));
       }
 
+      if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondNZ)) {
+         /* long sub/cmp, then NZ --> test dst!=src */
+         return unop(Iop_1Uto32,
+                     binop(Iop_CmpNE32, cc_dep1, cc_dep2));
+      }
+
       if (isU32(cc_op, X86G_CC_OP_SUBL) && isU32(cond, X86CondL)) {
          /* long sub/cmp, then L (signed less than) 
             --> test dst <s src */
@@ -853,6 +859,15 @@ IRExpr* guest_x86_spechelper ( Char* function_name,
          return unop(Iop_1Uto32,binop(Iop_CmpLE32S, cc_dep1, mkU32(0)));
       }
 
+      if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondBE)) {
+         /* long and/or/xor, then BE
+            LOGIC sets ZF according to the result and makes CF be zero.
+            BE computes (CF | ZF), but CF is zero, so this reduces ZF 
+            -- which will be 1 iff the result is zero.  Hence ...
+         */
+         return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
+      }
+
       /*---------------- LOGICW ----------------*/
 
       if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondZ)) {
@@ -894,14 +909,18 @@ IRExpr* guest_x86_spechelper ( Char* function_name,
       /* This can happen, as a result of x87 FP compares: "fcom ... ;
          fnstsw %ax ; sahf ; jbe" for example. */
 
-      if (isU32(cc_op, X86G_CC_OP_COPY) && isU32(cond, X86CondBE)) {
+      if (isU32(cc_op, X86G_CC_OP_COPY) && 
+          (isU32(cond, X86CondBE) || isU32(cond, X86CondNBE))) {
          /* COPY, then BE --> extract C and Z from dep1, and test (C
             or Z == 1). */
+         /* COPY, then NBE --> extract C and Z from dep1, and test (C
+            or Z == 0). */
+         UInt nnn = isU32(cond, X86CondBE) ? 1 : 0;
          return
             unop(
                Iop_1Uto32,
                binop(
-                  Iop_CmpNE32,
+                  Iop_CmpEQ32,
                   binop(
                      Iop_And32,
                      binop(
@@ -911,7 +930,7 @@ IRExpr* guest_x86_spechelper ( Char* function_name,
                      ),
                      mkU32(1)
                   ),
-                  mkU32(0)
+                  mkU32(nnn)
                )
             );
       }