From: Julian Seward Date: Thu, 20 Jan 2005 10:04:05 +0000 (+0000) Subject: First fruits from using new bb profiler: improve handling of guest x86 X-Git-Tag: svn/VALGRIND_3_0_1^2~613 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a97d45c929c8fd17aa7037658ddc4b911f8dea98;p=thirdparty%2Fvalgrind.git First fruits from using new bb profiler: improve handling of guest x86 floating point comparisons. A lot. There is more to be done here. git-svn-id: svn://svn.valgrind.org/vex/trunk@721 --- diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 381b5e9564..6735e13aea 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -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; } diff --git a/VEX/priv/ir/iropt.c b/VEX/priv/ir/iropt.c index 14c4789055..ad86ce8781 100644 --- a/VEX/priv/ir/iropt.c +++ b/VEX/priv/ir/iropt.c @@ -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;