about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2023-12-07 23:24:23 +0800
committerGitHub <noreply@github.com>2023-12-07 16:24:23 +0100
commit92fff0c903e28feb8c5cde79cf835cd9209c7f53 (patch)
tree27527cc663cabcf27bb90b21987c54acf46aae90 /src
parent06319911d4681f2a38ca50a4cf0c36617dba4097 (diff)
downloadbox64-92fff0c903e28feb8c5cde79cf835cd9209c7f53.tar.gz
box64-92fff0c903e28feb8c5cde79cf835cd9209c7f53.zip
[DYNAREC_RV64] Added unaligned support for some LOCK opcodes (#1123)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f0.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c
index c4373c44..469ae5bb 100644
--- a/src/dynarec/rv64/dynarec_rv64_f0.c
+++ b/src/dynarec/rv64/dynarec_rv64_f0.c
@@ -214,13 +214,30 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             } else {
                                 SMDMB();
                                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
+                                // TODO: Add support for BOX4_DYNAREC_ALIGNED_ATOMICS.
+                                ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+                                BNEZ_MARK3(x1);
+                                // Aligned
                                 MARKLOCK;
                                 LRxw(x1, wback, 1, 1);
                                 SUBxw(x3, x1, xRAX);
-                                BNE_MARK(x3, xZR);
+                                BNEZ_MARK(x3);
                                 // EAX == Ed
                                 SCxw(x4, gd, wback, 1, 1);
                                 BNEZ_MARKLOCK(x4);
+                                B_MARK_nocond;
+                                MARK3;
+                                // Unaligned
+                                ANDI(x5, wback, -(1 << (rex.w + 2)));
+                                MARK2; // Use MARK2 as a "MARKLOCK" since we're running out of marks.
+                                LDxw(x6, wback, 0);
+                                LRxw(x1, x5, 1, 1);
+                                SUBxw(x3, x6, xRAX);
+                                BNEZ_MARK(x3);
+                                // EAX == Ed
+                                SCxw(x4, x1, x5, 1, 1);
+                                BNEZ_MARK2(x4);
+                                SDxw(gd, wback, 0);
                                 MARK;
                                 UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5, x6);}
                                 MVxw(xRAX, x1);
@@ -533,11 +550,16 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         ed = xRAX+(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; else i64 = F8S;
+                        // TODO: Add support for BOX4_DYNAREC_ALIGNED_ATOMICS.
+                        ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+                        BNEZ_MARK3(x1);
+                        // Aligned
                         MARKLOCK;
                         LRxw(x1, wback, 1, 1);
-                        if(i64>=-2048 && i64<2048)
+                        if (i64 >= -2048 && i64 < 2048)
                             ADDIxw(x4, x1, i64);
                         else {
                             MOV64xw(x4, i64);
@@ -545,8 +567,26 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         }
                         SCxw(x3, x4, wback, 1, 1);
                         BNEZ_MARKLOCK(x3);
-                        IFX(X_ALL|X_PEND)
+                        B_MARK_nocond;
+                        MARK3;
+                        // Unaligned
+                        ANDI(x5, wback, -(1 << (rex.w + 2)));
+                        MARK2; // Use MARK2 as a "MARKLOCK" since we're running out of marks.
+                        LDxw(x6, wback, 0);
+                        LRxw(x1, x5, 1, 1);
+                        if (i64 >= -2048 && i64 < 2048)
+                            ADDIxw(x4, x6, i64);
+                        else {
+                            MOV64xw(x4, i64);
+                            ADDxw(x4, x6, x4);
+                        }
+                        SCxw(x3, x1, x5, 1, 1);
+                        BNEZ_MARK2(x3);
+                        SDxw(x4, wback, 0);
+                        MARK;
+                        IFX (X_ALL | X_PEND)
                             emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
+                        SMDMB();
                     }
                     break;
                 case 1: // OR