about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2022-09-15 10:43:25 +0200
committerptitSeb <sebastien.chev@gmail.com>2022-09-15 10:43:25 +0200
commit7c74e7be35d9f235b4c308aac2ab8c32bdd40f90 (patch)
tree5313af3d7f3f25bf5793892e3a72c383806272de /src
parentbf5ec1eb578452942d81cf96502445a54f641d51 (diff)
downloadbox64-7c74e7be35d9f235b4c308aac2ab8c32bdd40f90.tar.gz
box64-7c74e7be35d9f235b4c308aac2ab8c32bdd40f90.zip
Added F0 86 ocpode ([DYNAREC] too) (for #406)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c37
-rw-r--r--src/emu/x64runf0.c29
2 files changed, 65 insertions, 1 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index 7d77fecc..d13c91b2 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -30,10 +30,12 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
     uint8_t opcode = F8;
     uint8_t nextop;
     uint8_t gd, ed, u8;
-    uint8_t wback, wb1, wb2, gb1, gb2;
+    uint8_t wback, wb1, wb2, eb1, eb2, gb1, gb2;
     int32_t i32;
     int64_t i64, j64;
     int64_t fixedaddress;
+    MAYUSE(eb1);
+    MAYUSE(eb2);
     MAYUSE(gb1);
     MAYUSE(gb2);
     MAYUSE(wb1);
@@ -704,6 +706,39 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             DMB_ISH();
             break;
             
+        case 0x86:
+            INST_NAME("LOCK XCHG Eb, Gb");
+            // Do the swap
+            nextop = F8;
+            if(MODREG) {
+                GETGB(x4);
+                if(rex.rex) {
+                    ed = xRAX+(nextop&7)+(rex.b<<3);
+                    eb1 = ed;
+                    eb2 = 0;
+                } else {
+                    ed = (nextop&7);
+                    eb1 = xRAX+(ed&3);
+                    eb2 = ((ed&4)>>2);
+                }
+                UBFXw(x1, eb1, eb2*8, 8);
+                // do the swap 14 -> ed, 1 -> gd
+                BFIx(gb1, x1, gb2*8, 8);
+                BFIx(eb1, x4, eb2*8, 8);
+            } else {
+                DMB_ISH();
+                GETGB(x4);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0, rex, LOCK_LOCK, 0, 0);
+                MARKLOCK;
+                // do the swap with exclusive locking
+                LDAXRB(x1, ed);
+                // do the swap 14 -> strb(ed), 1 -> gd
+                STLXRB(x3, x4, ed);
+                CBNZx_MARKLOCK(x3);
+                DMB_ISH();
+                BFIx(gb1, x1, gb2*8, 8);
+            }
+            break;
         case 0x87:
             INST_NAME("LOCK XCHG Ed, Gd");
             nextop = F8;
diff --git a/src/emu/x64runf0.c b/src/emu/x64runf0.c
index df33758b..6dd80657 100644
--- a/src/emu/x64runf0.c
+++ b/src/emu/x64runf0.c
@@ -842,6 +842,35 @@ uintptr_t RunF0(x64emu_t *emu, rex_t rex, uintptr_t addr)
             pthread_mutex_unlock(&emu->context->mutex_lock);

 #endif

             break;

+

+        case 0x86:                      /* XCHG Eb,Gb */

+            nextop = F8;

+#ifdef DYNAREC

+            GETEB(0);

+            GETGB;

+            if(MODREG) { // reg / reg: no lock

+                tmp8u = GB;

+                GB = EB->byte[0];

+                EB->byte[0] = tmp8u;

+            } else {

+                do {

+                    tmp8u = native_lock_read_b(EB);

+                } while(native_lock_write_b(EB, GB));

+                GB = tmp8u;

+            }

+            // dynarec use need it's own mecanism

+#else

+            GETEB(0);

+            GETGB;

+            if(!MODREG)

+                pthread_mutex_lock(&emu->context->mutex_lock); // XCHG always LOCK (but when accessing memory only)

+            tmp8u = GB;

+            GB = EB->byte[0];

+            EB->byte[0] = tmp8u;

+            if(!MODREG)

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

+#endif                

+            break;

         case 0x87:                      /* XCHG Ed,Gd */

             nextop = F8;

 #ifdef DYNAREC