mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-05 19:13:46 +00:00
Implement repe scas.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@1929
This commit is contained in:
parent
8f0884bbb6
commit
d4fea78014
@ -1900,7 +1900,7 @@ void codegen_REPNE_SCAS ( UCodeBlock* cb, Int sz, Addr eip, Addr eip_next )
|
||||
uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
|
||||
|
||||
uInstr1(cb, POP, 4, TempReg, tv);
|
||||
uInstr0(cb, CALLM_E, 0);
|
||||
uInstr0(cb, CALLM_E, 0);
|
||||
|
||||
if (sz == 4 || sz == 2) {
|
||||
uInstr2(cb, SHL, 4, Literal, 0, TempReg, tv);
|
||||
@ -1917,6 +1917,56 @@ void codegen_REPNE_SCAS ( UCodeBlock* cb, Int sz, Addr eip, Addr eip_next )
|
||||
uCond(cb, CondAlways);
|
||||
}
|
||||
|
||||
/* Template for REPE SCAS<sz>. Assumes this insn is the last one in
|
||||
the basic block, and so emits a jump to the next insn. */
|
||||
static
|
||||
void codegen_REPE_SCAS ( UCodeBlock* cb, Int sz, Addr eip, Addr eip_next )
|
||||
{
|
||||
Int ta /* EAX */, tc /* ECX */, td /* EDI */, tv;
|
||||
ta = newTemp(cb);
|
||||
tc = newTemp(cb);
|
||||
tv = newTemp(cb);
|
||||
td = newTemp(cb);
|
||||
|
||||
uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, tc);
|
||||
uInstr2(cb, JIFZ, 4, TempReg, tc, Literal, 0);
|
||||
uLiteral(cb, eip_next);
|
||||
uInstr1(cb, DEC, 4, TempReg, tc);
|
||||
uInstr2(cb, PUT, 4, TempReg, tc, ArchReg, R_ECX);
|
||||
|
||||
uInstr2(cb, GET, sz, ArchReg, R_EAX, TempReg, ta);
|
||||
uInstr2(cb, GET, 4, ArchReg, R_EDI, TempReg, td);
|
||||
uInstr2(cb, LOAD, sz, TempReg, td, TempReg, tv);
|
||||
/* next uinstr kills ta, but that's ok -- don't need it again */
|
||||
uInstr2(cb, SUB, sz, TempReg, tv, TempReg, ta);
|
||||
setFlagsFromUOpcode(cb, SUB);
|
||||
|
||||
uInstr0(cb, CALLM_S, 0);
|
||||
uInstr2(cb, MOV, 4, Literal, 0, TempReg, tv);
|
||||
uLiteral(cb, 0);
|
||||
uInstr1(cb, PUSH, 4, TempReg, tv);
|
||||
|
||||
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_get_dirflag));
|
||||
uFlagsRWU(cb, FlagD, FlagsEmpty, FlagsEmpty);
|
||||
|
||||
uInstr1(cb, POP, 4, TempReg, tv);
|
||||
uInstr0(cb, CALLM_E, 0);
|
||||
|
||||
if (sz == 4 || sz == 2) {
|
||||
uInstr2(cb, SHL, 4, Literal, 0, TempReg, tv);
|
||||
uLiteral(cb, sz/2);
|
||||
}
|
||||
uInstr2(cb, ADD, 4, TempReg, tv, TempReg, td);
|
||||
uInstr2(cb, PUT, 4, TempReg, td, ArchReg, R_EDI);
|
||||
uInstr1(cb, JMP, 0, Literal, 0);
|
||||
uLiteral(cb, eip);
|
||||
uCond(cb, CondZ);
|
||||
uFlagsRWU(cb, FlagsOSZACP, FlagsEmpty, FlagsEmpty);
|
||||
uInstr1(cb, JMP, 0, Literal, 0);
|
||||
uLiteral(cb, eip_next);
|
||||
uCond(cb, CondAlways);
|
||||
}
|
||||
|
||||
|
||||
/* Template for REPE MOVS<sz>. Assumes this insn is the last one in
|
||||
the basic block, and so emits a jump to the next insn. */
|
||||
@ -5489,6 +5539,12 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
|
||||
if (dis) VG_(printf)("scasb\n");
|
||||
break;
|
||||
|
||||
case 0xAF: /* SCASl, no REP prefix */
|
||||
vg_assert(sorb == 0);
|
||||
codegen_SCAS ( cb, sz );
|
||||
if (dis) VG_(printf)("scas;\n");
|
||||
break;
|
||||
|
||||
case 0xFC: /* CLD */
|
||||
uInstr0(cb, CALLM_S, 0);
|
||||
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_CLD));
|
||||
@ -5566,6 +5622,13 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
|
||||
if (dis) VG_(printf)("repe stos%c\n", nameISize(sz));
|
||||
}
|
||||
else
|
||||
if (abyte == 0xAE || abyte == 0xAF) { /* REPE SCAS<sz> */
|
||||
if (abyte == 0xAE) sz = 1;
|
||||
codegen_REPE_SCAS ( cb, sz, eip_orig, eip );
|
||||
*isEnd = True;
|
||||
if (dis) VG_(printf)("repe scas%c\n", nameISize(sz));
|
||||
}
|
||||
else
|
||||
if (abyte == 0x90) { /* REPE NOP (PAUSE) */
|
||||
if (dis) VG_(printf)("repe nop (P4 pause)\n");
|
||||
/* do nothing; apparently a hint to the P4 re spin-wait loop */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user