|
From: Nicholas N. <nj...@ca...> - 2003-11-27 09:29:09
|
CVS commit by nethercote:
Added some missing instructions, from HEAD:
SCAS{l,w}
REPE SCAS
CVTPD2PS
MOV imm,eSP
M +75 -3 vg_to_ucode.c 1.87.2.11
--- valgrind/coregrind/vg_to_ucode.c #1.87.2.10:1.87.2.11
@@ -1916,4 +1916,54 @@ void codegen_REPNE_SCAS ( UCodeBlock* cb
}
+/* 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
@@ -2157,5 +2207,5 @@ void codegen_LODS ( UCodeBlock* cb, Int
-/* Template for REPNE SCAS<sz>, _not_ preceded by a REP prefix. */
+/* Template for SCAS<sz>, _not_ preceded by a REP prefix. */
static
void codegen_SCAS ( UCodeBlock* cb, Int sz )
@@ -4743,4 +4793,12 @@ static Addr disInstr ( UCodeBlock* cb, A
}
+ /* CVTPD2PS -- convert two doubles to two floats. */
+ if (sz == 2 &&
+ insn[0] == 0x0F && insn[1] == 0x5A) {
+ eip = dis_SSE3_reg_or_mem ( cb, sorb, eip+2, 16, "cvtpd2ps",
+ 0x66, insn[0], insn[1] );
+ goto decode_success;
+ }
+
/* SQRTPD: square root of packed double. */
if (sz == 2
@@ -5202,4 +5260,5 @@ static Addr disInstr ( UCodeBlock* cb, A
case 0xBA: /* MOV imm,eDX */
case 0xBB: /* MOV imm,eBX */
+ case 0xBC: /* MOV imm,eSP */
case 0xBD: /* MOV imm,eBP */
case 0xBE: /* MOV imm,eSI */
@@ -5711,4 +5770,10 @@ static Addr disInstr ( UCodeBlock* cb, A
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);
@@ -5786,4 +5851,11 @@ static Addr disInstr ( UCodeBlock* cb, A
*isEnd = True;
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
|