diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-07-10 18:32:35 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-07-10 18:32:35 +0200 |
| commit | 968594ee63e1c1ce9cd537c5df63b97e5bd8d91c (patch) | |
| tree | 29812c4765e2eccabff01824256f624d16c5aa6b | |
| parent | 3ac62c64d82c292787ba87b37a8bf580525365f3 (diff) | |
| download | box64-968594ee63e1c1ce9cd537c5df63b97e5bd8d91c.tar.gz box64-968594ee63e1c1ce9cd537c5df63b97e5bd8d91c.zip | |
[ARM64_DYNAREC] Simplified defered flags handling and limited case where UpdateFlags is actualy called (could be simplified more) (TODO on RV64 and LA64)
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_functions.c | 3 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.c | 34 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 8 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_private.h | 1 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_pass.c | 1 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 4 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_private.h | 1 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_private.h | 1 |
9 files changed, 15 insertions, 42 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c index e2ed058a..84832f65 100644 --- a/src/dynarec/arm64/dynarec_arm64_functions.c +++ b/src/dynarec/arm64/dynarec_arm64_functions.c @@ -774,7 +774,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r if (!dyn->need_dump && !BOX64ENV(dynarec_gdbjit) && !BOX64ENV(dynarec_perf_map)) return; static char buf[4096]; - int length = sprintf(buf, "barrier=%d state=%d/%d/%d(%d:%d->%d:%d/%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)", + int length = sprintf(buf, "barrier=%d state=%d/%d/%d(%d:%d->%d:%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)", dyn->insts[ninst].x64.barrier, dyn->insts[ninst].x64.state_flags, dyn->f.pending, @@ -783,7 +783,6 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r dyn->insts[ninst].f_entry.dfnone, dyn->insts[ninst].f_exit.pending, dyn->insts[ninst].f_exit.dfnone, - dyn->insts[ninst].f_exit.dfnone_here, dyn->insts[ninst].x64.may_set ? "may" : "set", dyn->insts[ninst].x64.set_flags, dyn->insts[ninst].x64.gen_flags, diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c index 88ea9846..c8f242d3 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -2498,39 +2498,21 @@ static void flagsCacheTransform(dynarec_arm_t* dyn, int ninst, int s1) int jmp = dyn->insts[ninst].x64.jmp_insts; if(jmp<0) return; - if(dyn->f.dfnone || (dyn->insts[jmp].f_exit.dfnone_here && !dyn->insts[jmp].x64.use_flags)) // flags are fully known, nothing we can do more + if(dyn->f.dfnone || ((dyn->insts[jmp].f_exit.dfnone && !dyn->insts[jmp].f_entry.dfnone) && !dyn->insts[jmp].x64.use_flags)) // flags are fully known, nothing we can do more return; MESSAGE(LOG_DUMP, "\tFlags fetch ---- ninst=%d -> %d\n", ninst, jmp); int go = (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone && !dyn->insts[jmp].df_notneeded)?1:0; switch (dyn->insts[jmp].f_entry.pending) { - case SF_UNKNOWN: break; - case SF_SET: - if(dyn->f.pending!=SF_SET && dyn->f.pending!=SF_SET_PENDING) - go = 1; + case SF_UNKNOWN: + go = 0; break; - case SF_SET_PENDING: - if(dyn->f.pending!=SF_SET - && dyn->f.pending!=SF_SET_PENDING - && dyn->f.pending!=SF_PENDING - ) { - // only sync if some previous flags are used or if all flags are not regenerated at the instuction - if(dyn->insts[jmp].x64.use_flags || (dyn->insts[jmp].x64.set_flags!=X_ALL)) - go = 1; - else if(go) { - // just clear df flags - go = 0; - STRw_U12(xZR, xEmu, offsetof(x64emu_t, df)); - } + default: + if(go && !(dyn->insts[jmp].x64.need_before&X_PEND) && (dyn->f.pending!=SF_UNKNOWN)) { + // just clear df flags + go = 0; + STRw_U12(xZR, xEmu, offsetof(x64emu_t, df)); } break; - case SF_PENDING: - if(dyn->f.pending!=SF_SET - && dyn->f.pending!=SF_SET_PENDING - && dyn->f.pending!=SF_PENDING) - go = 1; - else if (dyn->insts[jmp].f_entry.dfnone !=dyn->f.dfnone) - go = 1; - break; } if(go) { if(dyn->f.pending!=SF_PENDING) { diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 595660fb..266f988c 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1119,11 +1119,12 @@ x87_do_pop(dyn, ninst, scratch) #endif +#define FORCE_DFNONE() STRw_U12(wZR, xEmu, offsetof(x64emu_t, df)) + #define SET_DFNONE() \ do { \ if (!dyn->f.dfnone) { \ - STRw_U12(wZR, xEmu, offsetof(x64emu_t, df)); \ - dyn->f.dfnone_here = 1; \ + FORCE_DFNONE(); \ } \ if(!dyn->insts[ninst].x64.may_set) { \ dyn->f.dfnone = 1; \ @@ -1146,7 +1147,7 @@ #ifndef SET_NODF #define SET_NODF() dyn->f.dfnone = 0 #endif -#define SET_DFOK() dyn->f.dfnone = 1; dyn->f.dfnone_here=1 +#define SET_DFOK() dyn->f.dfnone = 1 #ifndef READFLAGS #define READFLAGS(A) \ @@ -1197,7 +1198,6 @@ #define UFLAG_RES(A) if(dyn->insts[ninst].x64.gen_flags) {STRxw_U12(A, xEmu, offsetof(x64emu_t, res));} #define UFLAG_DF(r, A) if(dyn->insts[ninst].x64.gen_flags) {SET_DF(r, A);} #define UFLAG_IF if(dyn->insts[ninst].x64.gen_flags) -#define UFLAG_IF_DF if(dyn->insts[ninst].x64.gen_flags || (dyn->insts[ninst].f_entry.dfnone && dyn->insts[ninst].f_entry.dfnone_here)) #define UFLAG_IF2(A) if(dyn->insts[ninst].x64.gen_flags A) #ifndef DEFAULT #define DEFAULT *ok = -1; BARRIER(2) diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h index 2e7145a9..e3d78d8e 100644 --- a/src/dynarec/arm64/dynarec_arm64_private.h +++ b/src/dynarec/arm64/dynarec_arm64_private.h @@ -87,7 +87,6 @@ typedef struct neoncache_s { typedef struct flagcache_s { int pending; // is there a pending flags here, or to check? uint8_t dfnone; // if deferred flags is already set to df_none - uint8_t dfnone_here;// defered flags is cleared in this opcode } flagcache_t; typedef struct instruction_arm64_s { diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c index a974fc12..dcf798dd 100644 --- a/src/dynarec/dynarec_native_pass.c +++ b/src/dynarec/dynarec_native_pass.c @@ -117,7 +117,6 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int else if(ninst && (dyn->insts[ninst].pred_sz>1 || (dyn->insts[ninst].pred_sz==1 && dyn->insts[ninst].pred[0]!=ninst-1))) dyn->last_ip = 0; // reset IP if some jump are coming here #endif - dyn->f.dfnone_here = 0; NEW_INST; MESSAGE(LOG_DUMP, "New Instruction %s:%p, native:%p\n", is32bits?"x86":"x64",(void*)addr, (void*)dyn->block); #ifdef ARCH_NOP diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 9e636cda..b6b646a8 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -852,7 +852,6 @@ do { \ if (!dyn->f.dfnone) { \ ST_W(xZR, xEmu, offsetof(x64emu_t, df)); \ - dyn->f.dfnone_here = 1; \ } \ if (!dyn->insts[ninst].x64.may_set) { \ dyn->f.dfnone = 1; \ @@ -876,8 +875,7 @@ #define SET_NODF() dyn->f.dfnone = 0 #define SET_DFOK() \ - dyn->f.dfnone = 1; \ - dyn->f.dfnone_here = 1 + dyn->f.dfnone = 1 #define CLEAR_FLAGS_(s) \ MOV64x(s, (1UL << F_AF) | (1UL << F_CF) | (1UL << F_OF) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF)); \ diff --git a/src/dynarec/la64/dynarec_la64_private.h b/src/dynarec/la64/dynarec_la64_private.h index 08e0ffe2..a71557cc 100644 --- a/src/dynarec/la64/dynarec_la64_private.h +++ b/src/dynarec/la64/dynarec_la64_private.h @@ -80,7 +80,6 @@ typedef struct lsxcache_s { typedef struct flagcache_s { int pending; // is there a pending flags here, or to check? uint8_t dfnone; // if deferred flags is already set to df_none - uint8_t dfnone_here;// defered flags is cleared in this opcode } flagcache_t; typedef struct callret_s callret_t; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index bbd305cf..d009c0ab 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -892,7 +892,6 @@ do { \ if (!dyn->f.dfnone) { \ SW(xZR, xEmu, offsetof(x64emu_t, df)); \ - dyn->f.dfnone_here = 1; \ } \ if (!dyn->insts[ninst].x64.may_set) { \ dyn->f.dfnone = 1; \ @@ -913,8 +912,7 @@ SET_DFNONE() #define SET_NODF() dyn->f.dfnone = 0 #define SET_DFOK() \ - dyn->f.dfnone = 1; \ - dyn->f.dfnone_here = 1 + dyn->f.dfnone = 1 #define CLEAR_FLAGS() \ IFX (X_ALL) { ANDI(xFlags, xFlags, ~((1UL << F_AF) | (1UL << F_CF) | (1UL << F_OF2) | (1UL << F_ZF) | (1UL << F_SF) | (1UL << F_PF))); } diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h index 4fa1b91c..d50bafab 100644 --- a/src/dynarec/rv64/dynarec_rv64_private.h +++ b/src/dynarec/rv64/dynarec_rv64_private.h @@ -96,7 +96,6 @@ typedef struct extcache_s { typedef struct flagcache_s { int pending; // is there a pending flags here, or to check? uint8_t dfnone; // if deferred flags is already set to df_none - uint8_t dfnone_here;// defered flags is cleared in this opcode } flagcache_t; typedef struct callret_s callret_t; |