]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
First fruits from using new bb profiler: improve handling of guest x86
authorJulian Seward <jseward@acm.org>
Thu, 20 Jan 2005 10:04:05 +0000 (10:04 +0000)
committerJulian Seward <jseward@acm.org>
Thu, 20 Jan 2005 10:04:05 +0000 (10:04 +0000)
floating point comparisons.  A lot.  There is more to be done here.

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

VEX/priv/guest-x86/ghelpers.c
VEX/priv/ir/iropt.c

index 381b5e9564c9971753b74398eefbfe9938b106ad..6735e13aea0392e8ae75c063912705378b6335df 100644 (file)
@@ -672,6 +672,7 @@ IRExpr* guest_x86_spechelper ( Char* function_name,
 #  define unop(_op,_a1) IRExpr_Unop((_op),(_a1))
 #  define binop(_op,_a1,_a2) IRExpr_Binop((_op),(_a1),(_a2))
 #  define mkU32(_n) IRExpr_Const(IRConst_U32(_n))
+#  define mkU8(_n)  IRExpr_Const(IRConst_U8(_n))
 
    Int i, arity = 0;
    for (i = 0; args[i]; i++)
@@ -874,12 +875,56 @@ IRExpr* guest_x86_spechelper ( Char* function_name,
          return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0)));
       }
 
+      /*---------------- COPY ----------------*/
+      /* 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)) {
+         /* COPY, then BE --> extract C and Z from dep1, and test (C
+            or Z == 1). */
+         return
+            unop(
+               Iop_1Uto32,
+               binop(
+                  Iop_CmpNE32,
+                  binop(
+                     Iop_And32,
+                     binop(
+                        Iop_Or32,
+                        binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)),
+                        binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_Z))
+                     ),
+                     mkU32(1)
+                  ),
+                  mkU32(0)
+               )
+            );
+      }
+      
+      if (isU32(cc_op, X86G_CC_OP_COPY) && isU32(cond, X86CondB)) {
+         /* COPY, then B --> extract C dep1, and test (C == 1). */
+         return
+            unop(
+               Iop_1Uto32,
+               binop(
+                  Iop_CmpNE32,
+                  binop(
+                     Iop_And32,
+                     binop(Iop_Shr32, cc_dep1, mkU8(X86G_CC_SHIFT_C)),
+                     mkU32(1)
+                  ),
+                  mkU32(0)
+               )
+            );
+      }
+
       return NULL;
    }
 
 #  undef unop
 #  undef binop
 #  undef mkU32
+#  undef mkU8
 
    return NULL;
 }
index 14c478905552bc05847650b21db38a6659916fba..ad86ce8781c2a37f39a2c90c92997e2f3e19b0ff 100644 (file)
@@ -1095,8 +1095,8 @@ static IRExpr* fold_Expr ( IRExpr* e )
       } else {
 
          /* other cases (identities, etc) */
-         /* Shl32(x,0) ==> x */
-         if (e->Iex.Binop.op == Iop_Shl32
+         /* Shl32/Shr32(x,0) ==> x */
+         if ((e->Iex.Binop.op == Iop_Shl32 || e->Iex.Binop.op == Iop_Shr32)
              && e->Iex.Binop.arg2->tag == Iex_Const
              && e->Iex.Binop.arg2->Iex.Const.con->Ico.U8 == 0) {
             e2 = e->Iex.Binop.arg1;