From: Julian Seward Date: Mon, 15 May 2006 12:23:17 +0000 (+0000) Subject: A few more x86 eflags-helper rewrite cases, which further reduce the X-Git-Tag: svn/VALGRIND_3_2_3^2~60 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b6881800090fcd0762f458aa4401d79e0e4bef99;p=thirdparty%2Fvalgrind.git A few more x86 eflags-helper rewrite cases, which further reduce the false error rate of memcheck on optimised code. git-svn-id: svn://svn.valgrind.org/vex/trunk@1618 --- diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 13475ff8d5..ce38a87956 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -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)) {