about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-05-21 18:36:36 +0800
committerGitHub <noreply@github.com>2025-05-21 12:36:36 +0200
commit8c51be6985e0281ebbb62093b59f295b266e0369 (patch)
treea1d6a329b6b819596f369bfbddf6f193d582aad6 /src
parentf25af13f795756fd70285fe9a285077497158630 (diff)
downloadbox64-8c51be6985e0281ebbb62093b59f295b266e0369.tar.gz
box64-8c51be6985e0281ebbb62093b59f295b266e0369.zip
[RV64_DYNAREC] Implemented unaligned path for LOCK INC/DEC opcodes (#2656)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f0.c42
1 files changed, 34 insertions, 8 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c
index 84816cea..4a7f3257 100644
--- a/src/dynarec/rv64/dynarec_rv64_f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_f0.c
@@ -851,13 +851,26 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         emit_inc32(dyn, ninst, rex, ed, x3, x4, x5, x6);
                     } else {
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
-                        MARKLOCK;
-                        LRxw(x1, wback, 1, 1);
+                        ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+                        BNEZ_MARK3(x1);
+                        // Aligned
+                        ADDIxw(x4, xZR, 1); 
+                        AMOADDxw(x1, x4, wback, 1, 1);
+                        B_MARK_nocond;
+                        MARK3;
+                        // Unaligned
+                        ANDI(x5, wback, -(1 << (rex.w + 2)));
+                        MARKLOCK2;
+                        LDxw(x1, wback, 0);
+                        LRxw(x6, x5, 1, 1);
                         ADDIxw(x4, x1, 1);
-                        SCxw(x3, x4, wback, 1, 1);
-                        BNEZ_MARKLOCK(x3);
+                        SCxw(x3, x6, x5, 1, 1);
+                        BNEZ_MARKLOCK2(x3);
+                        SDxw(x4, wback, 0);
+                        MARK;
                         IFXORNAT (X_ALL | X_PEND)
                             emit_inc32(dyn, ninst, rex, x1, x3, x4, x5, x6);
+                        SMDMB();
                     }
                     break;
                 case 1: // DEC Ed
@@ -869,13 +882,26 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         emit_dec32(dyn, ninst, rex, ed, x3, x4, x5, x6);
                     } else {
                         addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
-                        MARKLOCK;
-                        LRxw(x1, wback, 1, 1);
+                        ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+                        BNEZ_MARK3(x1);
+                        // Aligned
+                        ADDIxw(x4, xZR, -1); 
+                        AMOADDxw(x1, x4, wback, 1, 1);
+                        B_MARK_nocond;
+                        MARK3;
+                        // Unaligned
+                        ANDI(x5, wback, -(1 << (rex.w + 2)));
+                        MARKLOCK2;
+                        LDxw(x1, wback, 0);
+                        LRxw(x6, x5, 1, 1);
                         ADDIxw(x4, x1, -1);
-                        SCxw(x3, x4, wback, 1, 1);
-                        BNEZ_MARKLOCK(x3);
+                        SCxw(x3, x6, x5, 1, 1);
+                        BNEZ_MARKLOCK2(x3);
+                        SDxw(x4, wback, 0);
+                        MARK;
                         IFXORNAT (X_ALL | X_PEND)
                             emit_dec32(dyn, ninst, rex, x1, x3, x4, x5, x6);
+                        SMDMB();
                     }
                     break;
                 default: