about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-02-11 09:59:37 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-02-11 09:59:45 +0100
commit785d3ed5ab4c70c226fbedb2acd5ea8c7746c914 (patch)
tree81a45ec590f66772df2bf873eff1dd204ea32817 /src
parent33d17279259ba6bd4deff2ca018d4c1741f4967e (diff)
downloadbox64-785d3ed5ab4c70c226fbedb2acd5ea8c7746c914.tar.gz
box64-785d3ed5ab4c70c226fbedb2acd5ea8c7746c914.zip
[ARM64_DYNAREC] Added code on safeflags=2 to check if SI/DI memory overlap on fast rep movsb opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c12
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h4
2 files changed, 15 insertions, 1 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 5627fd6e..c9e8abb7 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1678,6 +1678,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 IF_UNALIGNED(ip) {
                     // special optim for large RCX value on forward case only
                     // but because it's unaligned path, check if a byte per byt is needed, and do 4-bytes per 4-bytes only instead
+                    if(BOX64DRENV(dynarec_safeflags)>1) {
+                        SUBx_REG(x2, xRDI, xRSI);
+                        CMPSx_U12(x2, 4);
+                        B_MARK(cCC);
+                    }
                     ORRw_REG(x1, xRSI, xRDI);
                     ANDw_mask(x1, x1, 0, 1);    //mask = 3
                     CBNZw_MARK(x1);
@@ -1690,6 +1695,11 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     CBNZx_MARK3(xRCX);
                     CBZx_MARKLOCK(xRCX);
                 } else {
+                    if(BOX64DRENV(dynarec_safeflags)>1) {
+                        SUBx_REG(x2, xRDI, xRSI);
+                        CMPSx_U12(x2, 8);
+                        B_MARK(cCC);
+                    }
                     // special optim for large RCX value on forward case only
                     MARK3;
                     CMPSx_U12(xRCX, 8);
@@ -1705,7 +1715,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 STRB_S9_postindex(x1, xRDI, 1);
                 SUBx_U12(xRCX, xRCX, 1);
                 CBNZx_MARK(xRCX);
-                B_NEXT_nocond;
+                B_MARKLOCK_nocond;
                 MARK2;  // Part with DF==1
                 LDRB_S9_postindex(x1, xRSI, -1);
                 STRB_S9_postindex(x1, xRDI, -1);
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 97f35221..fcaa38d7 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -891,6 +891,10 @@
 #define B_MARKLOCK(cond)    \
     j64 = GETMARKLOCK-(dyn->native_size);   \
     Bcond(cond, j64)
+// Branch to MARKLOCK unconditional (use j64)
+#define B_MARKLOCK_nocond    \
+    j64 = GETMARKLOCK-(dyn->native_size);   \
+    B(j64)
 // Branch to MARKLOCK if reg is not 0 (use j64)
 #define CBNZw_MARKLOCK(reg)             \
     j64 = GETMARKLOCK-(dyn->native_size);  \