diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index 6e1b746ff..80265834d 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -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 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) ) ); }