From 47dbbe030c2126159a31c00b6560cec7cd090a6c Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 15 Nov 2024 00:41:12 +0800 Subject: [PATCH] [DYNAREC] Added a experimental BOX64_DYNAREC_WEAKBARRIER option (#2033) * [DYNAREC] Added a experimental BOX64_DYNAREC_WEAKBARRIER option * Added it to the RCFILE --- src/core.c | 10 ++++++++++ src/dynarec/arm64/arm64_emitter.h | 7 +++++++ src/dynarec/arm64/dynarec_arm64_helper.h | 9 ++++++++- src/include/debug.h | 1 + src/tools/rcfile.c | 2 ++ 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/core.c b/src/core.c index 93bdd763..07579917 100644 --- a/src/core.c +++ b/src/core.c @@ -79,6 +79,7 @@ int box64_dynarec_forced = 0; int box64_dynarec_bigblock = 1; int box64_dynarec_forward = 128; int box64_dynarec_strongmem = 0; +int box64_dynarec_weakbarrier = 0; int box64_dynarec_x87double = 0; int box64_dynarec_div0 = 0; int box64_dynarec_fastnan = 1; @@ -785,6 +786,15 @@ void LoadLogEnv() if(box64_dynarec_strongmem) printf_log(LOG_INFO, "Dynarec will try to emulate a strong memory model%s\n", (box64_dynarec_strongmem==1)?" with limited performance loss":((box64_dynarec_strongmem>1)?" with more performance loss":"")); } + p = getenv("BOX64_DYNAREC_WEAKBARRIER"); + if (p) { + if (strlen(p) == 1) { + if (p[0] >= '0' && p[0] <= '1') + box64_dynarec_weakbarrier = p[0] - '0'; + } + if (box64_dynarec_weakbarrier) + printf_log(LOG_INFO, "Dynarec will try to use weaker memory barriers to reduce the performance loss introduce by strong memory emulation\n"); + } p = getenv("BOX64_DYNAREC_X87DOUBLE"); if(p) { if(strlen(p)==1) { diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h index ae337ac6..a4269283 100644 --- a/src/dynarec/arm64/arm64_emitter.h +++ b/src/dynarec/arm64/arm64_emitter.h @@ -489,12 +489,19 @@ int convert_bitmask(uint64_t bitmask); // Data Memory Barrier #define DMB_gen(CRm) (0b1101010100<<22 | 0b011<<16 | 0b0011<<12 | (CRm)<<8 | 1<<7 | 0b01<<5 | 0b11111) #define DMB_ISH() EMIT(DMB_gen(0b1011)) +#define DMB_ISHLD() EMIT(DMB_gen(0b1001)) +#define DMB_ISHST() EMIT(DMB_gen(0b1010)) +#define DMB_LD() EMIT(DMB_gen(0b1101)) +#define DMB_ST() EMIT(DMB_gen(0b1110)) #define DMB_SY() EMIT(DMB_gen(0b1111)) // Data Synchronization Barrier #define DSB_gen(CRm) (0b1101010100<<22 | 0b011<<16 | 0b0011<<12 | (CRm)<<8 | 1<<7 | 0b00<<5 | 0b11111) #define DSB_ISH() EMIT(DSB_gen(0b1011)) +#define DSB_ISHLD() EMIT(DSB_gen(0b1001)) #define DSB_ISHST() EMIT(DSB_gen(0b1010)) +#define DSB_LD() EMIT(DSB_gen(0b1101)) +#define DSB_ST() EMIT(DSB_gen(0b1110)) #define DSB_SY() EMIT(DSB_gen(0b1111)) // Break diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index cae4add9..5b4e5c1d 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -85,7 +85,14 @@ // End of sequence #define SMEND() if(dyn->smwrite && box64_dynarec_strongmem && (box64_dynarec_strongmem!=SMREAD_VAL)) {DMB_ISH();} dyn->smwrite=0; dyn->smread=0 // Force a Data memory barrier (for LOCK: prefix) -#define SMDMB() if(box64_dynarec_strongmem){DSB_ISH();}else{DMB_ISH();} dyn->smwrite=0; dyn->smread=0 +#define SMDMB() \ + if (box64_dynarec_strongmem && !box64_dynarec_weakbarrier) { \ + DSB_ISH(); \ + } else { \ + DMB_ISH(); \ + } \ + dyn->smwrite = 0; \ + dyn->smread = 0 #endif diff --git a/src/include/debug.h b/src/include/debug.h index 09865dc4..be8e0110 100644 --- a/src/include/debug.h +++ b/src/include/debug.h @@ -27,6 +27,7 @@ extern uintptr_t box64_dynarec_test_start, box64_dynarec_test_end; extern int box64_dynarec_bigblock; extern int box64_dynarec_forward; extern int box64_dynarec_strongmem; +extern int box64_dynarec_weakbarrier; extern int box64_dynarec_fastnan; extern int box64_dynarec_fastround; extern int box64_dynarec_x87double; diff --git a/src/tools/rcfile.c b/src/tools/rcfile.c index 1c23dda1..26366ac9 100644 --- a/src/tools/rcfile.c +++ b/src/tools/rcfile.c @@ -156,6 +156,7 @@ ENTRYINT(BOX64_DYNAREC_LOG, box64_dynarec_log, 0, 3, 2) \ ENTRYINT(BOX64_DYNAREC_BIGBLOCK, box64_dynarec_bigblock, 0, 3, 2) \ ENTRYSTRING_(BOX64_DYNAREC_FORWARD, box64_dynarec_forward) \ ENTRYINT(BOX64_DYNAREC_STRONGMEM, box64_dynarec_strongmem, 0, 4, 3) \ +ENTRYBOOL(BOX64_DYNAREC_WEAKBARRIER, box64_dynarec_weakbarrier) \ ENTRYBOOL(BOX64_DYNAREC_X87DOUBLE, box64_dynarec_x87double) \ ENTRYBOOL(BOX64_DYNAREC_DIV0, box64_dynarec_div0) \ ENTRYBOOL(BOX64_DYNAREC_FASTNAN, box64_dynarec_fastnan) \ @@ -182,6 +183,7 @@ IGNORE(BOX64_DYNAREC_LOG) \ IGNORE(BOX64_DYNAREC_BIGBLOCK) \ IGNORE(BOX64_DYNAREC_FORWARD) \ IGNORE(BOX64_DYNAREC_STRONGMEM) \ +IGNORE(BOX64_DYNAREC_WEAKBARRIER) \ IGNORE(BOX64_DYNAREC_X87DOUBLE) \ IGNORE(BOX64_DYNAREC_DIV0) \ IGNORE(BOX64_DYNAREC_FASTNAN) \