about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2025-10-22 05:01:50 +0800
committerGitHub <noreply@github.com>2025-10-21 23:01:50 +0200
commit1a27269089ab1f1f2d124ef58568aa17fd7771c3 (patch)
treecf38e2cde5fdef4f9ae0256ce670aadf8d0a5769
parent6c1fce4a014c1395ceaf1ca3eb34b85a8b2f3d9b (diff)
downloadbox64-1a27269089ab1f1f2d124ef58568aa17fd7771c3.tar.gz
box64-1a27269089ab1f1f2d124ef58568aa17fd7771c3.zip
[LA64_DYNAREC] Added unaligned F0 81/83 /0,5 LOCK ADD/SUB opcodes (#3084)
* [LA64_DYNAREC] Added unaligned F0 81/83 /5 LOCK SUB opcodes

* add too
-rw-r--r--src/dynarec/la64/dynarec_la64_f0.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/src/dynarec/la64/dynarec_la64_f0.c b/src/dynarec/la64/dynarec_la64_f0.c
index a6594702..68dd3d6f 100644
--- a/src/dynarec/la64/dynarec_la64_f0.c
+++ b/src/dynarec/la64/dynarec_la64_f0.c
@@ -8,6 +8,7 @@
 #include "box64cpu.h"
 #include "emu/x64emu_private.h"
 #include "la64_emitter.h"
+#include "la64_mapping.h"
 #include "x64emu.h"
 #include "box64stack.h"
 #include "callback.h"
@@ -504,18 +505,28 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             i64 = F32S;
                         else
                             i64 = F8S;
-                        if (i64 < -2048 || i64 >= 2048) {
-                            MOV64xw(x3, i64);
-                        }
+                        MOV64xw(x7, i64);
+                        ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+                        BNEZ_MARK3(x1);
+                        // Aligned
                         MARKLOCK;
                         LLxw(x1, wback, 0);
-                        if (i64 >= -2048 && i64 < 2048) {
-                            ADDIxw(x4, x1, i64);
-                        } else {
-                            ADDxw(x4, x1, x3);
-                        }
+                        ADDxw(x4, x1, x7);
                         SCxw(x4, wback, 0);
                         BEQZ_MARKLOCK(x4);
+                        B_MARK_nocond;
+                        MARK3;
+                        // Unaligned
+                        ADDI_D(x5, xZR, -(1 << (rex.w + 2)));
+                        AND(x5, wback, x5);
+                        MARKLOCK2;
+                        LDxw(x1, wback, 0);
+                        LLxw(x6, x5, 0);
+                        ADDxw(x4, x1, x7);
+                        SCxw(x6, x5, 0);
+                        BEQZ_MARKLOCK2(x6);
+                        SDxw(x4, wback, 0);
+                        MARK;
                         IFXORNAT (X_ALL | X_PEND) {
                             emit_add32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
                         }
@@ -609,18 +620,28 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             i64 = F32S;
                         else
                             i64 = F8S;
-                        if (i64 <= -2048 || i64 > 2048) {
-                            MOV64xw(x3, i64);
-                        }
+                        MOV64xw(x7, i64);
+                        ANDI(x1, wback, (1 << (rex.w + 2)) - 1);
+                        BNEZ_MARK3(x1);
+                        // Aligned
                         MARKLOCK;
                         LLxw(x1, wback, 0);
-                        if (i64 > -2048 && i64 <= 2048) {
-                            ADDIxw(x4, x1, -i64);
-                        } else {
-                            SUBxw(x4, x1, x3);
-                        }
+                        SUBxw(x4, x1, x7);
                         SCxw(x4, wback, 0);
                         BEQZ_MARKLOCK(x4);
+                        B_MARK_nocond;
+                        MARK3;
+                        // Unaligned
+                        ADDI_D(x5, xZR, -(1 << (rex.w + 2)));
+                        AND(x5, wback, x5);
+                        MARKLOCK2;
+                        LDxw(x1, wback, 0);
+                        LLxw(x6, x5, 0);
+                        SUBxw(x4, x1, x7);
+                        SCxw(x6, x5, 0);
+                        BEQZ_MARKLOCK2(x6);
+                        SDxw(x4, wback, 0);
+                        MARK;
                         IFXORNAT (X_ALL | X_PEND)
                             emit_sub32c(dyn, ninst, rex, x1, i64, x3, x4, x5, x6);
                     }