|
From: Dirk M. <mu...@kd...> - 2004-01-02 22:49:12
|
CVS commit by mueller:
cmpxchg8b support (backport)
M +24 -0 coregrind/vg_helpers.S 1.23.2.2
M +2 -0 coregrind/vg_include.h 1.142.2.4
M +3 -0 coregrind/vg_main.c 1.110.2.5
M +75 -1 coregrind/vg_to_ucode.c 1.87.2.15
M +2 -0 include/vg_skin.h 1.79.2.6
--- valgrind/coregrind/vg_helpers.S #1.23.2.1:1.23.2.2
@@ -80,4 +80,5 @@
* setting and getting obscure eflags
* double-length shifts
+ * eight byte compare and exchange
All routines use a standard calling convention designed for
@@ -616,4 +617,27 @@
+/* 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)
--- valgrind/coregrind/vg_include.h #1.142.2.3:1.142.2.4
@@ -1579,4 +1579,6 @@ extern void VG_(helper_DAS);
extern void VG_(helper_DAA);
+extern void VG_(helper_cmpxchg8b);
+
extern void VG_(helper_undefined_instruction);
--- valgrind/coregrind/vg_main.c #1.110.2.4:1.110.2.5
@@ -103,4 +103,5 @@ 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;
@@ -382,4 +383,6 @@ static void vg_init_baseBlock ( void )
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)
--- valgrind/coregrind/vg_to_ucode.c #1.87.2.14:1.87.2.15
@@ -3052,5 +3052,5 @@ 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);
@@ -3074,4 +3074,72 @@ 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)
@@ -6205,7 +6273,13 @@ static Addr disInstr ( UCodeBlock* cb, A
/* =-=-=-=-=-=-=-=-=- 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 -=-=-=-=-=-=-=-=-=-=-= */
--- valgrind/include/vg_skin.h #1.79.2.5:1.79.2.6
@@ -1089,4 +1089,6 @@ extern Int VGOFF_(helper_DAS);
extern Int VGOFF_(helper_DAA);
+extern Int VGOFF_(helper_cmpxchg8b);
+
/*====================================================================*/
|