From 785d3ed5ab4c70c226fbedb2acd5ea8c7746c914 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Tue, 11 Feb 2025 09:59:37 +0100 Subject: [ARM64_DYNAREC] Added code on safeflags=2 to check if SI/DI memory overlap on fast rep movsb opcode --- src/dynarec/arm64/dynarec_arm64_00.c | 12 +++++++++++- src/dynarec/arm64/dynarec_arm64_helper.h | 4 ++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'src') 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); \ -- cgit 1.4.1