From: Julian Seward Date: Sat, 13 May 2006 23:08:06 +0000 (+0000) Subject: Add specialisation rules to simplify the IR for 'testl .. ; js ..', X-Git-Tag: svn/VALGRIND_3_2_3^2~62 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c26b8fe19569b0e431dc31e5b2b05f509025519d;p=thirdparty%2Fvalgrind.git Add specialisation rules to simplify the IR for 'testl .. ; js ..', 'testw .. ; js ..' and 'testb .. ; js ..'. This gets rid of a bunch of false errors in Memcheck of the form ==2398== Conditional jump or move depends on uninitialised value(s) ==2398== at 0x6C51B61: KHTMLPart::clear() (khtml_part.cpp:1370) ==2398== by 0x6C61A72: KHTMLPart::begin(KURL const&, int, int) (khtml_part.cpp:1881) (KDE 3.5.2 compiled by gcc-4.0.2, -g -O). git-svn-id: svn://svn.valgrind.org/vex/trunk@1616 --- diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index e27223da50..13475ff8d5 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -920,11 +920,6 @@ IRExpr* guest_x86_spechelper ( HChar* function_name, return unop(Iop_1Uto32,binop(Iop_CmpEQ32, cc_dep1, mkU32(0))); } - if (isU32(cc_op, X86G_CC_OP_LOGICL) && isU32(cond, X86CondS)) { - /* long and/or/xor, then S --> test dst (UInt)result[31] */ + return binop(Iop_And32, + binop(Iop_Shr32,cc_dep1,mkU8(31)), + mkU32(1)); + } + /*---------------- LOGICW ----------------*/ if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondZ)) { @@ -953,6 +956,14 @@ IRExpr* guest_x86_spechelper ( HChar* function_name, mkU32(0))); } + if (isU32(cc_op, X86G_CC_OP_LOGICW) && isU32(cond, X86CondS)) { + /* see comment below for (LOGICB, CondS) */ + /* word and/or/xor, then S --> (UInt)result[15] */ + return binop(Iop_And32, + binop(Iop_Shr32,cc_dep1,mkU8(15)), + mkU32(1)); + } + /*---------------- LOGICB ----------------*/ if (isU32(cc_op, X86G_CC_OP_LOGICB) && isU32(cond, X86CondZ)) { @@ -962,6 +973,19 @@ IRExpr* guest_x86_spechelper ( HChar* function_name, 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 .. + Since it just depends on the top bit of the byte, extract + that bit and explicitly get rid of all the rest. This + helps memcheck avoid false positives in the case where any + of the other bits in the byte are undefined. */ + /* byte and/or/xor, then S --> (UInt)result[7] */ + return binop(Iop_And32, + binop(Iop_Shr32,cc_dep1,mkU8(7)), + mkU32(1)); + } + /*---------------- DECL ----------------*/ if (isU32(cc_op, X86G_CC_OP_DECL) && isU32(cond, X86CondZ)) {