From: Julian Seward Date: Thu, 12 Dec 2002 23:54:47 +0000 (+0000) Subject: Merge patch from JeremyF: X-Git-Tag: svn/VALGRIND_1_9_4~81 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f9d4a371e1fd4c8e64ef6fada0fe857199ca9960;p=thirdparty%2Fvalgrind.git Merge patch from JeremyF: 75-simple-jle Another pattern to test for Jle/Jnle. The observation is that EFLAGS looks like this: ----O--+SZ------ with Z in bit 6, S in 7 and O in 11. Therefore RORL $7, %eflags will result in: Z------+-------+-------+---O---S Since parity is only computed on the lower 8 bits, testing on P will determine whether O==S, and since Z is in the MSB, it can be tested with S. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1366 --- diff --git a/coregrind/vg_from_ucode.c b/coregrind/vg_from_ucode.c index b3603a1840..f2e89c41d0 100644 --- a/coregrind/vg_from_ucode.c +++ b/coregrind/vg_from_ucode.c @@ -1887,9 +1887,11 @@ static void synth_jcond_lit ( Condcode cond, { UInt mask; Bool simd; - Int tgt; + Int tgt, tgt2, tgt_jump; VG_(init_target)(&tgt); + VG_(init_target)(&tgt2); + VG_(init_target)(&tgt_jump); /* Ensure simulated %EFLAGS are up-to-date, by copying back %eflags if need be */ @@ -1914,32 +1916,32 @@ static void synth_jcond_lit ( Condcode cond, switch (cond) { - case CondLE: - case CondNLE: + case CondLE: /* Z || S != O -> S || !P */ + case CondNLE: /* !Z && S == O -> !S && P */ vg_assert(eax_trashable); VG_(emit_movv_offregmem_reg) ( 4, VGOFF_(m_eflags) * 4, R_EBP, R_EAX ); /* eax == %EFLAGS */ - VG_(emit_shiftopv_lit_reg)( False, 4, SHR, 11-7, R_EAX ); - /* eax has OF in SF's place */ - - emit_nonshiftopv_offregmem_reg - ( False, 4, XOR, VGOFF_(m_eflags) * 4, R_EBP, R_EAX ); - /* eax has (OF xor SF) in SF's place */ - - VG_(emit_shiftopv_lit_reg)( False, 4, SHR, 7-6, R_EAX ); - /* eax has (OF xor SF) in ZF's place */ - - emit_nonshiftopv_offregmem_reg - ( False, 4, OR, VGOFF_(m_eflags) * 4, R_EBP, R_EAX ); - /* eax has ((OF xor SF) or ZF) in SF's place */ - - VG_(emit_nonshiftopv_lit_reg)( False, 4, AND, 1 << 6, R_EAX ); - /* Z is now set iff ((OF xor SF) or ZF) == 1 */ - - if (cond == CondLE) cond = CondZ; else cond = CondNZ; + VG_(emit_nonshiftopv_lit_reg) + ( False, 4, AND, EFlagO|EFlagS|EFlagZ, R_EAX ); + /* eax just contains OF, SF and ZF */ + + VG_(emit_shiftopv_lit_reg)( False, 4, ROR, 7, R_EAX ); + /* eax has OF and SF in lower 8 bits, and ZF in MSB */ + + if (cond == CondLE) { + /* test Z */ + VG_(emit_jcondshort_target)(False, CondS, &tgt_jump); + /* test OF != SF */ + cond = CondP; + } else { + /* test Z */ + VG_(emit_jcondshort_target)(False, CondS, &tgt2); + /* test OF == SF */ + cond = CondNP; + } break; case CondL: @@ -2018,9 +2020,12 @@ static void synth_jcond_lit ( Condcode cond, } VG_(emit_jcondshort_target) ( simd, cond, &tgt ); + + VG_(target_forward)(&tgt_jump); synth_jmp_lit ( addr, JmpBoring ); VG_(target_forward)(&tgt); + VG_(target_forward)(&tgt2); }