about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-02-07 12:13:13 +0100
committerptitSeb <sebastien.chev@gmail.com>2025-02-07 12:13:21 +0100
commit46ad2261e760b3bb96c41205ab22dbfa8c54e963 (patch)
treeab609bfa6de42626fbfa11b99a1189aa80e56a7a /src/dynarec
parent6c60ad4695c167ac0a9f75b4b139eb46f5abaab9 (diff)
downloadbox64-46ad2261e760b3bb96c41205ab22dbfa8c54e963.tar.gz
box64-46ad2261e760b3bb96c41205ab22dbfa8c54e963.zip
[ARM64_DYNAREC] Optimized REP MOVSB
Diffstat (limited to 'src/dynarec')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c12
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h4
2 files changed, 16 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 899915ba..162a833d 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1675,6 +1675,17 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 INST_NAME("REP MOVSB");
                 CBZx_NEXT(xRCX);
                 TBNZ_MARK2(xFlags, F_DF);
+                IF_UNALIGNED(ip) {} else {
+                    // special optim for large RCX value on forward case only
+                    MARK3;
+                    CMPSx_U12(xRCX, 8);
+                    B_MARK(cCC);
+                    LDRx_S9_postindex(x1, xRSI, 8);
+                    STRx_S9_postindex(x1, xRDI, 8);
+                    SUBx_U12(xRCX, xRCX, 8);
+                    CBNZx_MARK3(xRCX);
+                    CBZx_MARKLOCK(xRCX);
+                }
                 MARK;   // Part with DF==0
                 LDRB_S9_postindex(x1, xRSI, 1);
                 STRB_S9_postindex(x1, xRDI, 1);
@@ -1686,6 +1697,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_MARK2(xRCX);
+                MARKLOCK;
                 // done
             } else {
                 INST_NAME("MOVSB");
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 56b388d4..b6398a2b 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -899,6 +899,10 @@
 #define CBNZx_MARKLOCK(reg)             \
     j64 = GETMARKLOCK-(dyn->native_size);  \
     CBNZx(reg, j64)
+// Branch to MARKLOCK if reg is 0 (use j64)
+#define CBZx_MARKLOCK(reg)             \
+    j64 = GETMARKLOCK-(dyn->native_size);  \
+    CBZx(reg, j64)
 
 #ifndef IFNATIVE
 #define IFNATIVE(A)     if(dyn->insts[ninst].need_nat_flags&(A))