about summary refs log tree commit diff stats
path: root/src/dynarec/rv64
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-09-16 17:44:27 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-09-16 17:44:27 +0200
commitea48f2b823b253fd4ed61925d5b3ac9ac2d2955e (patch)
tree1e6997434a4d60913f72c3c65e58e92f760fef54 /src/dynarec/rv64
parent85b07f7441e7342e7d4c40166eef3b47c7090745 (diff)
downloadbox64-ea48f2b823b253fd4ed61925d5b3ac9ac2d2955e.tar.gz
box64-ea48f2b823b253fd4ed61925d5b3ac9ac2d2955e.zip
[DYNAREC] Improved Memory Barrier handling for LOCK prefixed opcodes
Diffstat (limited to 'src/dynarec/rv64')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_2.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66f0.c3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f0.c46
4 files changed, 0 insertions, 53 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c
index 4c5f3687..e9cb0259 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_2.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_2.c
@@ -293,7 +293,6 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             } else {
                 GETGB(x3);
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
-                SMDMB();
 
                 // calculate shift amount
                 ANDI(x1, ed, 0x3);
@@ -335,7 +334,6 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
             } else {
                 GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
-                SMDMB();
                 ANDI(x3, ed, (1 << (2 + rex.w)) - 1);
                 BNE_MARK(x3, xZR);
                 AMOSWAPxw(gd, gd, ed, 1, 1);
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c
index a9399651..51bb829c 100644
--- a/src/dynarec/rv64/dynarec_rv64_66.c
+++ b/src/dynarec/rv64/dynarec_rv64_66.c
@@ -630,7 +630,6 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
-                SMDMB();
 
                 ANDI(x3, ed, 1);
                 BNEZ_MARK(x3);
@@ -670,7 +669,6 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 SH(gd, ed, 0);
 
                 MARK2;
-                SMDMB();
                 INSHz(gd, x1, x3, x4, 1, 0);
             }
             break;
diff --git a/src/dynarec/rv64/dynarec_rv64_66f0.c b/src/dynarec/rv64/dynarec_rv64_66f0.c
index 3e49b463..c409b74e 100644
--- a/src/dynarec/rv64/dynarec_rv64_66f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_66f0.c
@@ -95,7 +95,6 @@ uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                         BNEZ_MARKLOCK2(x5);
                     }
                     MARK;
-                    SMDMB();
                     UFLAG_IF { emit_cmp16(dyn, ninst, x6, x1, x2, x3, x4, x5); }
                     INSH(xRAX, x1, x2, x3, 1, 0);
                     break;
@@ -106,7 +105,6 @@ uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
         case 0x81:
         case 0x83:
             nextop = F8;
-            SMDMB();
             switch ((nextop >> 3) & 7) {
                 case 0: // ADD
                     if (opcode == 0x81) {
@@ -311,7 +309,6 @@ uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 default:
                     DEFAULT;
             }
-            SMDMB();
             break;
 
         default:
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c
index 047b72cc..c7f3f634 100644
--- a/src/dynarec/rv64/dynarec_rv64_f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_f0.c
@@ -58,7 +58,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
             nextop = F8;
             GETGD;
-            SMDMB();
             if (MODREG) {
                 ed = TO_NAT((nextop & 7) + (rex.b << 3));
                 emit_add32(dyn, ninst, rex, ed, gd, x3, x4, x5);
@@ -69,14 +68,12 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     emit_add32(dyn, ninst, rex, x1, gd, x3, x4, x5);
                 }
             }
-            SMDMB();
             break;
         case 0x08:
             INST_NAME("LOCK OR Eb, Gb");
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
             nextop = F8;
             GETGB(x1);
-            SMDMB();
             if (MODREG) {
                 GETEB(x2, 1);
                 emit_or8(dyn, ninst, x2, x1, x4, x5);
@@ -94,14 +91,12 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     emit_or8(dyn, ninst, x2, x1, x4, x5);
                 }
             }
-            SMDMB();
             break;
         case 0x09:
             INST_NAME("LOCK OR Ed, Gd");
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
             nextop = F8;
             GETGD;
-            SMDMB();
             if (MODREG) {
                 ed = TO_NAT((nextop & 7) + (rex.b << 3));
                 emit_or32(dyn, ninst, rex, ed, gd, x3, x4);
@@ -111,7 +106,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 IFXORNAT (X_ALL | X_PEND)
                     emit_or32(dyn, ninst, rex, x1, gd, x3, x4);
             }
-            SMDMB();
             break;
 
         case 0x0F:
@@ -135,7 +129,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         OR(ed, ed, x4);
                         if (!rex.w) ZEROUP(ed);
                     } else {
-                        SMDMB();
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
                         SRAIxw(x1, gd, 5 + rex.w);
                         ADDSL(x3, wback, x1, 2 + rex.w, x1);
@@ -152,7 +145,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         OR(ed, ed, x4);
                         SCxw(x7, ed, wback, 1, 1);
                         BNEZ_MARKLOCK(x7);
-                        SMDMB();
                     }
                     break;
                 case 0xB0:
@@ -196,7 +188,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                 ANDI(xRAX, xRAX, ~0xff);
                                 OR(xRAX, xRAX, x2);
                             } else {
-                                SMDMB();
                                 if (rex.rex) {
                                     gb1 = TO_NAT(((nextop & 0x38) >> 3) + (rex.r << 3));
                                     gb2 = 0;
@@ -237,7 +228,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                 // load m8 into AL
                                 ANDI(xRAX, xRAX, ~0xff);
                                 OR(xRAX, xRAX, x4);
-                                SMDMB();
                             }
                             break;
                         default:
@@ -262,7 +252,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                 MARK2;
                                 MVxw(xRAX, x1);
                             } else {
-                                SMDMB();
                                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
                                 ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
                                 BNEZ_MARK3(x1);
@@ -290,7 +279,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                 MARK;
                                 UFLAG_IF { emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5, x6); }
                                 MVxw(xRAX, x1);
-                                SMDMB();
                             }
                             break;
                         default:
@@ -316,7 +304,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         AND(ed, ed, x4);
                         if (!rex.w) ZEROUP(ed);
                     } else {
-                        SMDMB();
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
                         SRAIxw(x1, gd, 5 + rex.w);
                         ADDSL(x3, wback, x1, 2 + rex.w, x1);
@@ -335,7 +322,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         AND(ed, ed, x4);
                         SCxw(x7, ed, wback, 1, 1);
                         BNEZ_MARKLOCK(x7);
-                        SMDMB();
                     }
                     break;
                 case 0xC1:
@@ -345,7 +331,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
                             nextop = F8;
                             GETGD;
-                            SMDMB();
                             if (MODREG) {
                                 ed = TO_NAT((nextop & 7) + (rex.b << 3));
                                 MVxw(x1, ed);
@@ -361,7 +346,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                 }
                                 MVxw(gd, x1);
                             }
-                            SMDMB();
                             break;
                         default:
                             DEFAULT;
@@ -378,7 +362,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                     nextop = F8;
                                     addr = geted(dyn, addr, ninst, nextop, &wback, x1, x2, &fixedaddress, rex, LOCK_LOCK, 0, 0);
                                     ANDI(xFlags, xFlags, ~(1 << F_ZF));
-                                    SMDMB();
                                     ZEXTW2(x3, xRAX);
                                     SLLI(x2, xRDX, 32);
                                     OR(x3, x3, x2); // x3 is edx:eax
@@ -394,12 +377,10 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                     SC_D(x5, x4, wback, 1, 1); // set ZF and load ecx:ebx into m64
                                     BNEZ_MARKLOCK(x5);
                                     ORI(xFlags, xFlags, 1 << F_ZF);
-                                    SMDMB();
                                     B_NEXT_nocond;
                                     MARK;
                                     SRLI(xRDX, x2, 32);
                                     ZEXTW2(xRAX, x2);
-                                    SMDMB();
                                     B_NEXT_nocond;
                                     MARK3;
                                     // Unaligned
@@ -412,12 +393,10 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                     BNEZ_MARKLOCK2(x7);
                                     SD(x4, wback, 0); // set ZF and load ecx:ebx into m64
                                     ORI(xFlags, xFlags, 1 << F_ZF);
-                                    SMDMB();
                                     B_NEXT_nocond;
                                     MARK2;
                                     SRLI(xRDX, x2, 32);
                                     ZEXTW2(xRAX, x2);
-                                    SMDMB();
                                     break;
                                 case 1:
                                     INST_NAME("LOCK CMPXCHG16B Gq, Eq");
@@ -437,7 +416,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                     // x4 == 1 if locked
                                     BNEZ_MARK2(x4);
 
-                                    SMDMB();
                                     MARKLOCK;
                                     LD(x3, wback, 8);
                                     LR_D(x2, wback, 1, 1);
@@ -452,7 +430,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                                     MV(xRAX, x2);
                                     MV(xRDX, x3);
                                     MARK3;
-                                    SMDMB();
 
                                     // unlock
                                     AMOSWAP_W(xZR, xZR, x7, 1, 1);
@@ -474,7 +451,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
             nextop = F8;
             GETGB(x2);
-            SMDMB();
             if (MODREG) {
                 if (rex.rex) {
                     wback = TO_NAT((nextop & 7) + (rex.b << 3));
@@ -539,7 +515,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     emit_adc8(dyn, ninst, x4, x2, x3, x5, x6);
                 }
             }
-            SMDMB();
             break;
         case 0x11:
             INST_NAME("LOCK ADC Ed, Gd");
@@ -547,7 +522,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
             nextop = F8;
             GETGD;
-            SMDMB();
             if (MODREG) {
                 ed = TO_NAT((nextop & 7) + (rex.b << 3));
                 emit_adc32(dyn, ninst, rex, ed, gd, x3, x4, x5, x6);
@@ -564,14 +538,12 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     emit_adc32(dyn, ninst, rex, x1, gd, x3, x4, x5, x6);
                 }
             }
-            SMDMB();
             break;
         case 0x21:
             INST_NAME("LOCK AND Ed, Gd");
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
             nextop = F8;
             GETGD;
-            SMDMB();
             if (MODREG) {
                 ed = TO_NAT((nextop & 7) + (rex.b << 3));
                 emit_and32(dyn, ninst, rex, ed, gd, x3, x4);
@@ -581,14 +553,12 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 IFXORNAT (X_ALL | X_PEND)
                     emit_and32(dyn, ninst, rex, x1, gd, x3, x4);
             }
-            SMDMB();
             break;
         case 0x29:
             INST_NAME("LOCK SUB Ed, Gd");
             SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
             nextop = F8;
             GETGD;
-            SMDMB();
             if (MODREG) {
                 ed = TO_NAT((nextop & 7) + (rex.b << 3));
                 emit_sub32(dyn, ninst, rex, ed, gd, x3, x4, x5);
@@ -599,14 +569,12 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 IFXORNAT (X_ALL | X_PEND)
                     emit_sub32(dyn, ninst, rex, x1, gd, x3, x4, x5);
             }
-            SMDMB();
             break;
         case 0x66:
             return dynarec64_66F0(dyn, addr, ip, ninst, rex, rep, ok, need_epilog);
 
         case 0x80:
             nextop = F8;
-            SMDMB();
             switch ((nextop >> 3) & 7) {
                 case 1: // OR
                     INST_NAME("LOCK OR Eb, Ib");
@@ -635,12 +603,10 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 default:
                     DEFAULT;
             }
-            SMDMB();
             break;
         case 0x81:
         case 0x83:
             nextop = F8;
-            SMDMB();
             switch ((nextop >> 3) & 7) {
                 case 0: // ADD
                     if (opcode == 0x81) {
@@ -657,7 +623,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         ed = TO_NAT((nextop & 7) + (rex.b << 3));
                         emit_add32c(dyn, ninst, rex, ed, i64, x3, x4, x5, x6);
                     } else {
-                        SMDMB();
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, (opcode == 0x81) ? 4 : 1);
                         if (opcode == 0x81)
                             i64 = F32S;
@@ -682,7 +647,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         MARK;
                         IFXORNAT (X_ALL | X_PEND)
                             emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
-                        SMDMB();
                     }
                     break;
                 case 1: // OR
@@ -777,7 +741,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         MARK;
                         IFXORNAT (X_ALL | X_PEND)
                             emit_sub32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
-                        SMDMB();
                     }
                     break;
                 case 6: // XOR
@@ -808,7 +771,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     break;
                 default: DEFAULT;
             }
-            SMDMB();
             break;
         case 0x87:
             INST_NAME("LOCK XCHG Ed, Gd");
@@ -820,7 +782,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 MV(gd, ed);
                 MV(ed, x5);
             } else {
-                SMDMB();
                 GETGD;
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
                 ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
@@ -839,7 +800,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 BNEZ_MARKLOCK(x4);
                 SDxw(gd, wback, 0);
                 MVxw(gd, x1);
-                SMDMB();
             }
             break;
         case 0xF6:
@@ -853,14 +813,12 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         EBBACK(x5, 1);
                     } else {
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
-                        SMDMB();
                         ANDI(x3, wback, 3);
                         ANDI(x5, wback, ~3);
                         MOV32w(x4, 0xFF);
                         SLLIW(x3, x3, 3);
                         SLLW(x4, x4, x3); // mask
                         AMOXOR_W(xZR, x4, x5, 1, 1);
-                        SMDMB();
                     }
                     break;
                 default:
@@ -873,7 +831,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 case 0: // INC Ed
                     INST_NAME("LOCK INC Ed");
                     SETFLAGS(X_ALL & ~X_CF, SF_SUBSET_PENDING, NAT_FLAGS_FUSION);
-                    SMDMB();
                     if (MODREG) {
                         ed = TO_NAT((nextop & 7) + (rex.b << 3));
                         emit_inc32(dyn, ninst, rex, ed, x3, x4, x5, x6);
@@ -898,13 +855,11 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         MARK;
                         IFXORNAT (X_ALL | X_PEND)
                             emit_inc32(dyn, ninst, rex, x1, x3, x4, x5, x6);
-                        SMDMB();
                     }
                     break;
                 case 1: // DEC Ed
                     INST_NAME("LOCK DEC Ed");
                     SETFLAGS(X_ALL & ~X_CF, SF_SUBSET_PENDING, NAT_FLAGS_FUSION);
-                    SMDMB();
                     if (MODREG) {
                         ed = TO_NAT((nextop & 7) + (rex.b << 3));
                         emit_dec32(dyn, ninst, rex, ed, x3, x4, x5, x6);
@@ -929,7 +884,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         MARK;
                         IFXORNAT (X_ALL | X_PEND)
                             emit_dec32(dyn, ninst, rex, x1, x3, x4, x5, x6);
-                        SMDMB();
                     }
                     break;
                 default: