mirror of
https://github.com/Zenithsiz/ftmemsim-valgrind.git
synced 2026-02-03 18:13:01 +00:00
implement cmpxchg8b, patch by Tom Hughes.
CCMAIL: 69688-done@bugs.kde.org git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2154
This commit is contained in:
parent
6bbfc962d3
commit
6be7c55829
@ -94,6 +94,7 @@ VG_(tramp_syscall_offset):
|
||||
* integer multiplication
|
||||
* setting and getting obscure eflags
|
||||
* double-length shifts
|
||||
* eight byte compare and exchange
|
||||
|
||||
All routines use a standard calling convention designed for
|
||||
calling from translations, in which the incoming args are
|
||||
@ -630,6 +631,29 @@ VG_(helper_idiv_16_8):
|
||||
ret
|
||||
|
||||
|
||||
/* Eight byte compare and exchange. */
|
||||
.globl VG_(helper_cmpxchg8b)
|
||||
VG_(helper_cmpxchg8b):
|
||||
pushl %eax
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
movl 20(%esp), %eax
|
||||
movl 24(%esp), %edx
|
||||
movl 28(%esp), %ebx
|
||||
movl 32(%esp), %ecx
|
||||
cmpxchg8b 36(%esp)
|
||||
movl %eax, 20(%esp)
|
||||
movl %edx, 24(%esp)
|
||||
movl %ebx, 28(%esp)
|
||||
movl %ecx, 32(%esp)
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %eax
|
||||
ret
|
||||
|
||||
|
||||
/* Undefined instruction (generates SIGILL) */
|
||||
.globl VG_(helper_undefined_instruction)
|
||||
VG_(helper_undefined_instruction):
|
||||
|
||||
@ -1745,6 +1745,8 @@ extern void VG_(helper_LAHF);
|
||||
extern void VG_(helper_DAS);
|
||||
extern void VG_(helper_DAA);
|
||||
|
||||
extern void VG_(helper_cmpxchg8b);
|
||||
|
||||
extern void VG_(helper_undefined_instruction);
|
||||
|
||||
/* Information about trampoline code (for signal return and syscalls) */
|
||||
|
||||
@ -102,6 +102,7 @@ Int VGOFF_(helper_SAHF) = INVALID_OFFSET;
|
||||
Int VGOFF_(helper_LAHF) = INVALID_OFFSET;
|
||||
Int VGOFF_(helper_DAS) = INVALID_OFFSET;
|
||||
Int VGOFF_(helper_DAA) = INVALID_OFFSET;
|
||||
Int VGOFF_(helper_cmpxchg8b) = INVALID_OFFSET;
|
||||
Int VGOFF_(helper_undefined_instruction) = INVALID_OFFSET;
|
||||
|
||||
/* MAX_NONCOMPACT_HELPERS can be increased easily. If MAX_COMPACT_HELPERS is
|
||||
@ -422,6 +423,8 @@ static void vg_init_baseBlock ( void )
|
||||
= alloc_BaB_1_set( (Addr) & VG_(helper_IN));
|
||||
VGOFF_(helper_OUT)
|
||||
= alloc_BaB_1_set( (Addr) & VG_(helper_OUT));
|
||||
VGOFF_(helper_cmpxchg8b)
|
||||
= alloc_BaB_1_set( (Addr) & VG_(helper_cmpxchg8b));
|
||||
|
||||
VGOFF_(helper_undefined_instruction)
|
||||
= alloc_BaB_1_set( (Addr) & VG_(helper_undefined_instruction));
|
||||
|
||||
@ -2754,7 +2754,7 @@ Addr dis_cmpxchg_G_E ( UCodeBlock* cb,
|
||||
|
||||
uInstr2(cb, GET, size, ArchReg, gregOfRM(rm), TempReg, src);
|
||||
uInstr2(cb, GET, size, ArchReg, R_EAX, TempReg, acc);
|
||||
uInstr2(cb, MOV, size, TempReg, acc, TempReg, junk);
|
||||
uInstr2(cb, MOV, 4, TempReg, acc, TempReg, junk);
|
||||
uInstr2(cb, SUB, size, TempReg, dest, TempReg, junk);
|
||||
setFlagsFromUOpcode(cb, SUB);
|
||||
|
||||
@ -2776,6 +2776,74 @@ Addr dis_cmpxchg_G_E ( UCodeBlock* cb,
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
Addr dis_cmpxchg8b ( UCodeBlock* cb,
|
||||
UChar sorb,
|
||||
Addr eip0 )
|
||||
{
|
||||
Int tal, tah, junkl, junkh, destl, desth, srcl, srch, accl, acch;
|
||||
UChar dis_buf[50];
|
||||
UChar rm;
|
||||
UInt pair;
|
||||
|
||||
rm = getUChar(eip0);
|
||||
accl = newTemp(cb);
|
||||
acch = newTemp(cb);
|
||||
srcl = newTemp(cb);
|
||||
srch = newTemp(cb);
|
||||
destl = newTemp(cb);
|
||||
desth = newTemp(cb);
|
||||
junkl = newTemp(cb);
|
||||
junkh = newTemp(cb);
|
||||
|
||||
vg_assert(!epartIsReg(rm));
|
||||
|
||||
pair = disAMode ( cb, sorb, eip0, dis?dis_buf:NULL );
|
||||
tal = LOW24(pair);
|
||||
tah = newTemp(cb);
|
||||
uInstr2(cb, MOV, 4, TempReg, tal, TempReg, tah);
|
||||
uInstr2(cb, ADD, 4, Literal, 0, TempReg, tah);
|
||||
uLiteral(cb, 4);
|
||||
eip0 += HI8(pair);
|
||||
if (dis) VG_(printf)("cmpxchg8b %s\n", dis_buf);
|
||||
|
||||
uInstr0(cb, CALLM_S, 0);
|
||||
|
||||
uInstr2(cb, LOAD, 4, TempReg, tah, TempReg, desth);
|
||||
uInstr1(cb, PUSH, 4, TempReg, desth);
|
||||
uInstr2(cb, LOAD, 4, TempReg, tal, TempReg, destl);
|
||||
uInstr1(cb, PUSH, 4, TempReg, destl);
|
||||
uInstr2(cb, GET, 4, ArchReg, R_ECX, TempReg, srch);
|
||||
uInstr1(cb, PUSH, 4, TempReg, srch);
|
||||
uInstr2(cb, GET, 4, ArchReg, R_EBX, TempReg, srcl);
|
||||
uInstr1(cb, PUSH, 4, TempReg, srcl);
|
||||
uInstr2(cb, GET, 4, ArchReg, R_EDX, TempReg, acch);
|
||||
uInstr1(cb, PUSH, 4, TempReg, acch);
|
||||
uInstr2(cb, GET, 4, ArchReg, R_EAX, TempReg, accl);
|
||||
uInstr1(cb, PUSH, 4, TempReg, accl);
|
||||
|
||||
uInstr1(cb, CALLM, 0, Lit16, VGOFF_(helper_cmpxchg8b));
|
||||
uFlagsRWU(cb, FlagsEmpty, FlagZ, FlagsEmpty);
|
||||
|
||||
uInstr1(cb, POP, 4, TempReg, accl);
|
||||
uInstr2(cb, PUT, 4, TempReg, accl, ArchReg, R_EAX);
|
||||
uInstr1(cb, POP, 4, TempReg, acch);
|
||||
uInstr2(cb, PUT, 4, TempReg, acch, ArchReg, R_EDX);
|
||||
uInstr1(cb, POP, 4, TempReg, srcl);
|
||||
uInstr2(cb, PUT, 4, TempReg, srcl, ArchReg, R_EBX);
|
||||
uInstr1(cb, POP, 4, TempReg, srch);
|
||||
uInstr2(cb, PUT, 4, TempReg, srch, ArchReg, R_ECX);
|
||||
uInstr1(cb, POP, 4, TempReg, destl);
|
||||
uInstr2(cb, STORE, 4, TempReg, destl, TempReg, tal);
|
||||
uInstr1(cb, POP, 4, TempReg, desth);
|
||||
uInstr2(cb, STORE, 4, TempReg, desth, TempReg, tah);
|
||||
|
||||
uInstr0(cb, CALLM_E, 0);
|
||||
|
||||
return eip0;
|
||||
}
|
||||
|
||||
|
||||
/* Handle conditional move instructions of the form
|
||||
cmovcc E(reg-or-mem), G(reg)
|
||||
|
||||
@ -5886,9 +5954,15 @@ static Addr disInstr ( UCodeBlock* cb, Addr eip, Bool* isEnd )
|
||||
|
||||
/* =-=-=-=-=-=-=-=-=- CMPXCHG -=-=-=-=-=-=-=-=-=-= */
|
||||
|
||||
case 0xB0: /* CMPXCHG Gv,Ev */
|
||||
eip = dis_cmpxchg_G_E ( cb, sorb, 1, eip );
|
||||
break;
|
||||
case 0xB1: /* CMPXCHG Gv,Ev */
|
||||
eip = dis_cmpxchg_G_E ( cb, sorb, sz, eip );
|
||||
break;
|
||||
case 0xC7: /* CMPXCHG8B Gv */
|
||||
eip = dis_cmpxchg8b ( cb, sorb, eip );
|
||||
break;
|
||||
|
||||
/* =-=-=-=-=-=-=-=-=- CPUID -=-=-=-=-=-=-=-=-=-=-= */
|
||||
|
||||
|
||||
@ -1183,6 +1183,8 @@ extern Int VGOFF_(helper_LAHF);
|
||||
extern Int VGOFF_(helper_DAS);
|
||||
extern Int VGOFF_(helper_DAA);
|
||||
|
||||
extern Int VGOFF_(helper_cmpxchg8b);
|
||||
|
||||
|
||||
/*====================================================================*/
|
||||
/*=== Generating x86 code from UCode ===*/
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user