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:
Dirk Mueller 2004-01-02 22:42:29 +00:00
parent 6bbfc962d3
commit 6be7c55829
5 changed files with 106 additions and 1 deletions

View File

@ -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):

View File

@ -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) */

View File

@ -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));

View File

@ -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 -=-=-=-=-=-=-=-=-=-=-= */

View File

@ -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 ===*/