|
From: Nicholas N. <nj...@ca...> - 2004-02-22 17:04:01
|
CVS commit by nethercote:
Patch from Tom Hughes:
Patch to ignore REP prefixes on single byte RET instructions.
(REP RET is apparently faster than RET on AMD K7/K8)
M +27 -17 vg_to_ucode.c 1.130
--- valgrind/coregrind/vg_to_ucode.c #1.129:1.130
@@ -3770,4 +3770,17 @@ void dis_pop_segreg ( UCodeBlock* cb, UI
}
+static
+void dis_ret ( UCodeBlock* cb, UInt d32 )
+{
+ Int t1 = newTemp(cb), t2 = newTemp(cb);
+ uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t1);
+ uInstr2(cb, LOAD, 4, TempReg, t1, TempReg, t2);
+ uInstr2(cb, ADD, 4, Literal, 0, TempReg, t1);
+ uLiteral(cb, 4+d32);
+ uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP);
+ jmp_treg(cb, t2);
+ LAST_UINSTR(cb).jmpkind = JmpRet;
+}
+
/*------------------------------------------------------------*/
/*--- Disassembling entire basic blocks ---*/
@@ -5188,22 +5201,12 @@ static Addr disInstr ( UCodeBlock* cb, A
case 0xC2: /* RET imm16 */
d32 = getUDisp16(eip); eip += 2;
- goto do_Ret;
+ dis_ret(cb, d32);
+ *isEnd = True;
+ DIP("ret %d\n", d32);
+ break;
case 0xC3: /* RET */
- d32 = 0;
- goto do_Ret;
- do_Ret:
- t1 = newTemp(cb); t2 = newTemp(cb);
- uInstr2(cb, GET, 4, ArchReg, R_ESP, TempReg, t1);
- uInstr2(cb, LOAD, 4, TempReg, t1, TempReg, t2);
- uInstr2(cb, ADD, 4, Literal, 0, TempReg, t1);
- uLiteral(cb, 4+d32);
- uInstr2(cb, PUT, 4, TempReg, t1, ArchReg, R_ESP);
- jmp_treg(cb, t2);
- LAST_UINSTR(cb).jmpkind = JmpRet;
-
+ dis_ret(cb, 0);
*isEnd = True;
- if (d32 == 0) { DIP("ret\n"); }
- else { DIP("ret %d\n", d32); }
-
+ DIP("ret\n");
break;
@@ -6218,4 +6221,11 @@ static Addr disInstr ( UCodeBlock* cb, A
*isEnd = True;
}
+ else
+ if (abyte == 0xC3) { /* REP RET */
+ /* AMD K7/K8-specific optimisation; faster than vanilla RET */
+ dis_ret(cb, 0);
+ *isEnd = True;
+ DIP("rep ret\n");
+ }
else {
goto decode_failure;
|