]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
implement cmpxchg8b, patch by Tom Hughes.
authorDirk Mueller <dmuell@gmx.net>
Fri, 2 Jan 2004 22:42:29 +0000 (22:42 +0000)
committerDirk Mueller <dmuell@gmx.net>
Fri, 2 Jan 2004 22:42:29 +0000 (22:42 +0000)
CCMAIL: 69688-done@bugs.kde.org

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2154

coregrind/vg_helpers.S
coregrind/vg_include.h
coregrind/vg_main.c
coregrind/vg_to_ucode.c
include/vg_skin.h.base

index 270caac3b41d4e6c5d3de9df645b47ac870a2e5b..ea7614eb919a45ed27404d20854a43dd5315a81f 100644 (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):
index a7f5f60f1e3a7dd573abb7ce93b9d88863fdc039..1e79e56b3f12429e1bf82de6e4d10a66756c2ab1 100644 (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) */
index d91f48729baa78b4632a2b85d83362982028ab36..db93c7c49e729ec760ec0c450ae0c91759077cc1 100644 (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));
index e05c44980ae8a62afd7dfeab3f106b3ec336a804..0240cebabbb80c6374e3ac1f05928078257c77bb 100644 (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 -=-=-=-=-=-=-=-=-=-=-= */
 
index cff8a22df47e2593872d325a3df8865c7d0a3349..25a42ee3802799248b0c9980883b5c0d0582108d 100644 (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                               ===*/