about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-28 21:16:22 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-03-28 21:16:22 +0200
commit903f9ddb41782221a6e4a248b4144af2b15f0d0d (patch)
tree086429ec2ffc2986bbb31e6f4869784eaa221fd7 /src
parent4b6ade050f1c69029c764695bf3f6afafdea3a15 (diff)
downloadbox64-903f9ddb41782221a6e4a248b4144af2b15f0d0d.tar.gz
box64-903f9ddb41782221a6e4a248b4144af2b15f0d0d.zip
[DYNAREC] Added F0 C7 opcode
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h8
-rw-r--r--src/dynarec/dynarec_arm64_f0.c25
2 files changed, 33 insertions, 0 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index 9bc3190c..5ff959e9 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -306,6 +306,14 @@
 #define LDAXRxw(Rt, Rn)                 EMIT(MEMAX_gen(2+rex.w, 1, 31, Rn, Rt))
 #define STLXRxw(Rs, Rt, Rn)             EMIT(MEMAX_gen(2+rex.w, 0, Rs, Rn, Rt))
 
+#define MEMAX_pair(size, L, Rs, Rt2, Rn, Rt)    (1<<31 | (size)<<30 | 0b001000<<24 | (L)<<22 | 1<<21 | (Rs)<<16 | 1<<15 | (Rt2)<<10 | (Rn)<<5 | (Rt))
+#define LDAXPx(Rt, Rt2, Rn)             EMIT(MEMAX_pair(1, 1, 31, Rt2, Rn, Rt))
+#define LDAXPw(Rt, Rt2, Rn)             EMIT(MEMAX_pair(0, 1, 31, Rt2, Rn, Rt))
+#define LDAXPxw(Rt, Rt2, Rn)            EMIT(MEMAX_pair(rex.w, 1, 31, Rt2, Rn, Rt))
+#define STLXPx(Rs, Rt, Rt2, Rn)         EMIT(MEMAX_pair(1, 0, Rs, Rt2, Rn, Rt))
+#define STLXPw(Rs, Rt, Rt2, Rn)         EMIT(MEMAX_pair(0, 0, Rs, Rt2, Rn, Rt))
+#define STLXPxw(Rs, Rt, Rt2, Rn)        EMIT(MEMAX_pair(rex.w, 0, Rs, Rt2, Rn, Rt))
+
 // LOAD/STORE Exclusive
 #define MEMX_gen(size, L, Rs, Rn, Rt)       ((size)<<30 | 0b001000<<24 | (L)<<22 | (Rs)<<16 | 0<<15 | 0b11111<<10 | (Rn)<<5 | (Rt))
 #define LDXRB(Rt, Rn)                   EMIT(MEMX_gen(0b00, 1, 31, Rn, Rt))
diff --git a/src/dynarec/dynarec_arm64_f0.c b/src/dynarec/dynarec_arm64_f0.c
index 7b6991f2..ff1b8511 100644
--- a/src/dynarec/dynarec_arm64_f0.c
+++ b/src/dynarec/dynarec_arm64_f0.c
@@ -185,6 +185,31 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     }
                     break;
 
+                case 0xC7:
+                    INST_NAME("LOCK CMPXCHG8B Gq, Eq");
+                    SETFLAGS(X_ZF, SF_SET);
+                    nextop = F8;
+                    addr = geted(dyn, addr, ninst, nextop, &wback, x1, &fixedaddress, 0, 0, rex, 0, 0);
+                    MARKLOCK;
+                    LDAXPxw(x2, x3, wback);
+                    CMPSxw_REG(xRAX, x2);
+                    B_MARK(cNE);    // EAX != Ed[0]
+                    CMPSxw_REG(xRDX, x3);
+                    B_MARK(cNE);    // EDX != Ed[1]
+                    MOVxw_REG(x2, xRBX);
+                    MOVxw_REG(x3, xRCX);
+                    STLXPxw(x4, x2, x3, wback);
+                    CBNZx_MARKLOCK(x4);
+                    MOV32w(x1, 1);
+                    B_MARK3(c__);
+                    MARK;
+                    MOVxw_REG(xRAX, x2);
+                    MOVxw_REG(xRDX, x3);
+                    MOV32w(x1, 0);
+                    MARK3;
+                    BFIw(xFlags, x1, F_ZF, 1);
+                    break;
+
                 default:
                     DEFAULT;
             }