mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-04 02:18:37 +00:00
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
This commit is contained in:
parent
32c4a39bae
commit
f9d4a371e1
@ -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 */
|
||||
VG_(emit_nonshiftopv_lit_reg)
|
||||
( False, 4, AND, EFlagO|EFlagS|EFlagZ, R_EAX );
|
||||
/* eax just contains OF, SF and ZF */
|
||||
|
||||
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, ROR, 7, R_EAX );
|
||||
/* eax has OF and SF in lower 8 bits, and ZF in MSB */
|
||||
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user