about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-06 11:06:51 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-06 11:06:51 +0100
commitfda3396140b7de91ab6a2a55e473f9f27634d6f0 (patch)
tree9a5932ffc19eb5fb90bf7d246960ff1dbda67499 /src
parent65a64003ba135fc21d4a2d3158568277506c2118 (diff)
downloadbox64-fda3396140b7de91ab6a2a55e473f9f27634d6f0.tar.gz
box64-fda3396140b7de91ab6a2a55e473f9f27634d6f0.zip
Added F0 REX B1 LOCK CMPXCHG opcode
Diffstat (limited to 'src')
-rwxr-xr-xsrc/emu/x64run.c9
-rw-r--r--src/emu/x64runf0.c113
2 files changed, 122 insertions, 0 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 953966be..f80948ba 100755
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -520,6 +520,15 @@ x64emurun:
             STEP
             break;
 
+        case 0xF0:                      /* LOCK prefix */
+            if(RunF0(emu, rex)) {
+                unimp = 1;
+                goto fini;
+            }
+            if(emu->quit)
+                goto fini;
+            break;
+
         case 0xF6:                      /* GRP3 Eb(,Ib) */
             nextop = F8;
             GETEB;
diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c
new file mode 100644
index 00000000..6969c062
--- /dev/null
+++ b/src/emu/x64runf0.c
@@ -0,0 +1,113 @@
+#define _GNU_SOURCE

+#include <stdint.h>

+#include <stdio.h>

+#include <stdlib.h>

+#include <math.h>

+#include <string.h>

+#include <signal.h>

+#include <sys/types.h>

+#include <unistd.h>

+

+#include "debug.h"

+#include "box64stack.h"

+#include "x64emu.h"

+#include "x64run.h"

+#include "x64emu_private.h"

+#include "x64run_private.h"

+#include "x64primop.h"

+#include "x64trace.h"

+#include "x87emu_private.h"

+#include "box64context.h"

+#include "my_cpuid.h"

+#include "bridge.h"

+//#include "signals.h"

+#ifdef DYNAREC

+#include "../dynarec/arm_lock_helper.h"

+#endif

+

+#include "modrm.h"

+

+int RunF0(x64emu_t *emu, rex_t rex)

+{

+    uint8_t opcode;

+    uint8_t nextop;

+    int32_t tmp32s;

+    uint32_t tmp32u;

+    reg64_t *oped, *opgd;

+

+    opcode = F8;

+    // REX prefix before the F0 are ignored

+    rex.rex = 0;

+    while(opcode>=0x40 && opcode<=0x4f) {

+        rex.rex = opcode;

+        opcode = F8;

+    }

+

+    switch(opcode) {

+

+        case 0x0f:

+            opcode = F8;

+            switch (opcode) { 

+

+                case 0xB1:                      /* CMPXCHG Ed,Gd */

+                    nextop = F8;

+                    GETED;

+                    GETGD;

+#ifdef DYNAREC

+                    if(((uintptr_t)ED)&3) {

+                        do {

+                            tmp32u = ED->dword[0] & ~0xff;

+                            tmp32u |= arm_lock_read_b(ED);

+                            cmp32(emu, R_EAX, tmp32u);

+                            if(ACCESS_FLAG(F_ZF)) {

+                                tmp32s = arm_lock_write_b(ED, GD->dword[0] & 0xff);

+                                if(!tmp32s)

+                                    ED->dword[0] = GD.dword[0];

+                            } else {

+                                R_EAX = tmp32u;

+                                tmp32s = 0;

+                            }

+                        } while(tmp32s);

+                    } else {

+                        do {

+                            tmp32u = arm_lock_read_d(ED);

+                            cmp32(emu, R_EAX, tmp32u);

+                            if(ACCESS_FLAG(F_ZF)) {

+                                tmp32s = arm_lock_write_d(ED, GD.dword[0]);

+                            } else {

+                                R_EAX = tmp32u;

+                                tmp32s = 0;

+                            }

+                        } while(tmp32s);

+                    }

+#else

+                    pthread_mutex_lock(&emu->context->mutex_lock);

+                    if(rex.w) {

+                        cmp64(emu, R_RAX, ED->q[0]);

+                        if(ACCESS_FLAG(F_ZF)) {

+                            ED->q[0] = GD->q[0];

+                        } else {

+                            R_RAX = ED->q[0];

+                        }

+                    } else {

+                        cmp32(emu, R_EAX, ED->dword[0]);

+                        if(ACCESS_FLAG(F_ZF)) {

+                            ED->dword[0] = GD->dword[0];

+                        } else {

+                            R_EAX = ED->dword[0];

+                        }

+                    }

+                    pthread_mutex_unlock(&emu->context->mutex_lock);

+#endif

+                    break;

+                    

+            default:

+                return 1;

+            }

+            break;

+

+        default:

+            return 1;

+    }

+    return 0;

+}
\ No newline at end of file