about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-03-18 19:10:24 +0800
committerGitHub <noreply@github.com>2025-03-18 12:10:24 +0100
commitc7280d93129b94fae9fc12bd3f1f746541b9aaa2 (patch)
tree85d72c4a4e4f428ef4d0ee5d26f12e8705bf7b55 /src
parentdaca99017b4d5a3770dab6de039a9d023bebba92 (diff)
downloadbox64-c7280d93129b94fae9fc12bd3f1f746541b9aaa2.tar.gz
box64-c7280d93129b94fae9fc12bd3f1f746541b9aaa2.zip
[RV64_DYNAREC] Added 66 F0 0F B1 LOCK CMPXCHG opcode (#2447)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66f0.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66f0.c b/src/dynarec/rv64/dynarec_rv64_66f0.c
index 7066f1c8..c904d077 100644
--- a/src/dynarec/rv64/dynarec_rv64_66f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_66f0.c
@@ -52,6 +52,59 @@ uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
     GETREX();
 
     switch (opcode) {
+        case 0x0F:
+            opcode = F8;
+            switch (opcode) {
+                case 0xB1:
+                    INST_NAME("LOCK CMPXCHG Ew, Gw");
+                    SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
+                    nextop = F8;
+                    GETGD;
+                    ZEXTH(x6, xRAX);
+                    if (MODREG) {
+                        ed = TO_NAT((nextop & 7) + (rex.b << 3));
+                        wback = 0;
+                        ZEXTH(x1, ed);
+                        BNE_MARK(x6, x1);
+                        INSH(ed, gd, x2, x3, 1, 1);
+                    } else {
+                        addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, LOCK_LOCK, 0, 0);
+                        ANDI(x5, wback, 0b10);
+                        BNEZ_MARK2(x5);
+
+                        // lower 16 bits
+                        MARKLOCK;
+                        LR_W(x2, wback, 1, 1);
+                        ZEXTH(x1, x2);
+                        BNE_MARK(x6, x1);
+                        INSH(x2, gd, x5, x4, 1, 1);
+                        SC_W(x5, x2, wback, 1, 1);
+                        BNEZ_MARKLOCK(x5);
+                        B_MARK_nocond;
+
+                        MARK2;
+                        // upper 16 bits
+                        XORI(wback, wback, 0b10);
+                        MARKLOCK2;
+                        LR_W(x2, wback, 1, 1);
+                        SRLIW(x1, x2, 16);
+                        BNE_MARK(x6, x1);
+                        SLLIW(x2, x2, 16);
+                        SRLIW(x2, x2, 16);
+                        SLLIW(x5, gd, 16);
+                        OR(x2, x2, x5);
+                        SC_W(x5, x2, wback, 1, 1);
+                        BNEZ_MARKLOCK2(x5);
+                    }
+                    MARK;
+                    SMDMB();
+                    UFLAG_IF { emit_cmp16(dyn, ninst, x6, x7, x2, x3, x4, x5); }
+                    INSH(xRAX, x1, x2, x3, 1, 0);
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         case 0x81:
         case 0x83:
             nextop = F8;