diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 3 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_functions.c | 6 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.c | 2 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 2 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_pass1.h | 10 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_private.h | 1 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_functions.c | 14 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_functions.h | 2 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_private.h | 1 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_private.h | 1 |
10 files changed, 39 insertions, 3 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index cd886163..c777ed3d 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -3158,6 +3158,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin JUMP((uintptr_t)getAlternate((void*)j64), 0); if(dyn->insts[ninst].x64.jmp_insts==-1) { // out of the block + SET_NODF(); fpu_purgecache(dyn, ninst, 1, x1, x2, x3); jump_to_next(dyn, (uintptr_t)getAlternate((void*)j64), 0, ninst, rex.is32bits); } else { @@ -3746,6 +3747,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin case 4: // JMP Ed INST_NAME("JMP Ed"); READFLAGS(X_PEND); + SET_NODF(); BARRIER(BARRIER_FLOAT); GETEDz(0); jump_to_next(dyn, 0, ed, ninst, rex.is32bits); @@ -3758,6 +3760,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { INST_NAME("JMP FAR Ed"); READFLAGS(X_PEND); + SET_NODF(); BARRIER(BARRIER_FLOAT); SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, &unscaled, 0, 0, rex, NULL, 0, 0); diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c index 1400f977..dd4749e7 100644 --- a/src/dynarec/arm64/dynarec_arm64_functions.c +++ b/src/dynarec/arm64/dynarec_arm64_functions.c @@ -662,7 +662,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r { if(box64_dynarec_dump) { printf_x64_instruction(rex.is32bits?my_context->dec32:my_context->dec, &dyn->insts[ninst].x64, name); - dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d(%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)", + dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d/%d(%d:%d->%d:%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)", (box64_dynarec_dump>1)?"\e[32m":"", (void*)(dyn->native_start+dyn->insts[ninst].address), dyn->insts[ninst].size/4, @@ -671,6 +671,10 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r dyn->insts[ninst].x64.state_flags, dyn->f.pending, dyn->f.dfnone, + dyn->insts[ninst].f_entry.pending, + dyn->insts[ninst].f_entry.dfnone, + dyn->insts[ninst].f_exit.pending, + dyn->insts[ninst].f_exit.dfnone, 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 7a29562b..1b56127e 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.c +++ b/src/dynarec/arm64/dynarec_arm64_helper.c @@ -2346,7 +2346,7 @@ static void flagsCacheTransform(dynarec_arm_t* dyn, int ninst, int s1) 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 return; MESSAGE(LOG_DUMP, "\tFlags fetch ---- ninst=%d -> %d\n", ninst, jmp); - int go = (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone)?1:0; + 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: diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h index 803e15e1..84533591 100644 --- a/src/dynarec/arm64/dynarec_arm64_helper.h +++ b/src/dynarec/arm64/dynarec_arm64_helper.h @@ -1092,7 +1092,9 @@ } \ dyn->f.dfnone=0; \ } else SET_DFNONE(S) +#ifndef SET_NODF #define SET_NODF() dyn->f.dfnone = 0 +#endif #define SET_DFOK() dyn->f.dfnone = 1; dyn->f.dfnone_here=1 #ifndef MAYSETFLAGS diff --git a/src/dynarec/arm64/dynarec_arm64_pass1.h b/src/dynarec/arm64/dynarec_arm64_pass1.h index 173f27bf..9a3132b3 100644 --- a/src/dynarec/arm64/dynarec_arm64_pass1.h +++ b/src/dynarec/arm64/dynarec_arm64_pass1.h @@ -2,6 +2,16 @@ #define FINI #define MESSAGE(A, ...) do {} while (0) #define EMIT(A) do {} while (0) +#define MAYSETFLAGS() dyn->insts[ninst].x64.may_set = 1 +#define SET_NODF() \ + if(!dyn->insts[ninst].x64.gen_flags && !dyn->insts[ninst].x64.use_flags) \ + propagate_nodf(dyn, ninst); \ + dyn->f.dfnone = 0 +#define SETFLAGS(A,B) \ + dyn->insts[ninst].x64.set_flags = A; \ + dyn->insts[ninst].x64.state_flags = (B)&~SF_DF; \ + dyn->f.pending=(B)&SF_SET_PENDING; \ + dyn->f.dfnone=((B)&SF_SET)?(((B)==SF_SET_NODF)?0:1):0; #define NEW_INST \ dyn->insts[ninst].f_entry = dyn->f; \ dyn->n.combined1 = dyn->n.combined2 = 0;\ diff --git a/src/dynarec/arm64/dynarec_arm64_private.h b/src/dynarec/arm64/dynarec_arm64_private.h index b010d4ed..3b8cb1f3 100644 --- a/src/dynarec/arm64/dynarec_arm64_private.h +++ b/src/dynarec/arm64/dynarec_arm64_private.h @@ -119,6 +119,7 @@ typedef struct instruction_arm64_s { unsigned normal_carry:1; unsigned normal_carry_before:1; unsigned invert_carry:1; // this opcode force an inverted carry + unsigned df_notneeded:1; flagcache_t f_exit; // flags status at end of instruction neoncache_t n; // neoncache at end of instruction (but before poping) flagcache_t f_entry; // flags status before the instruction begin diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c index c6ea65b0..f0bf3d08 100644 --- a/src/dynarec/dynarec_native_functions.c +++ b/src/dynarec/dynarec_native_functions.c @@ -513,7 +513,7 @@ static int flagsCacheNeedsTransform(dynarec_native_t* dyn, int ninst) { return 0; if(dyn->insts[ninst].f_exit.dfnone) // flags are fully known, nothing we can do more return 0; - if(dyn->insts[jmp].f_entry.dfnone && !dyn->insts[ninst].f_exit.dfnone) + if(dyn->insts[jmp].f_entry.dfnone && !dyn->insts[ninst].f_exit.dfnone && !dyn->insts[jmp].df_notneeded) return 1; switch (dyn->insts[jmp].f_entry.pending) { case SF_UNKNOWN: return 0; @@ -648,3 +648,15 @@ void avx_unmark_zero(dynarec_native_t* dyn, int ninst, int reg) { dyn->ymm_zero &= ~(1<<reg); } + +void propagate_nodf(dynarec_native_t* dyn, int ninst) +{ + while(ninst>=0) { + if(dyn->insts[ninst].df_notneeded) + return; // already flagged + if(dyn->insts[ninst].x64.gen_flags || dyn->insts[ninst].x64.use_flags) + return; // flags are use, so maybe it's needed + dyn->insts[ninst].df_notneeded = 1; + --ninst; + } +} \ No newline at end of file diff --git a/src/dynarec/dynarec_native_functions.h b/src/dynarec/dynarec_native_functions.h index fe74c2b3..827a02a4 100644 --- a/src/dynarec/dynarec_native_functions.h +++ b/src/dynarec/dynarec_native_functions.h @@ -61,6 +61,8 @@ void native_div0(x64emu_t* emu); // Caches transformation (for loops) // Specific, need to be written par backend int CacheNeedsTransform(dynarec_native_t* dyn, int i1); +// propagete defererd to unknow, as state is not needed +void propagate_nodf(dynarec_native_t* dyn, int ninst); // predecessor access int isPred(dynarec_native_t* dyn, int ninst, int pred); diff --git a/src/dynarec/la64/dynarec_la64_private.h b/src/dynarec/la64/dynarec_la64_private.h index 3d65de48..1dab0696 100644 --- a/src/dynarec/la64/dynarec_la64_private.h +++ b/src/dynarec/la64/dynarec_la64_private.h @@ -91,6 +91,7 @@ typedef struct instruction_la64_s { uint8_t barrier_maybe; uint8_t will_write; uint8_t last_write; + uint8_t df_notneeded; flagcache_t f_exit; // flags status at end of instruction lsxcache_t lsx; // lsxcache at end of instruction (but before poping) flagcache_t f_entry; // flags status before the instruction begin diff --git a/src/dynarec/rv64/dynarec_rv64_private.h b/src/dynarec/rv64/dynarec_rv64_private.h index 0beaf11c..5c00231e 100644 --- a/src/dynarec/rv64/dynarec_rv64_private.h +++ b/src/dynarec/rv64/dynarec_rv64_private.h @@ -122,6 +122,7 @@ typedef struct instruction_rv64_s { uint16_t ymm0_out; // the ymm0 at th end of the opcode uint16_t ymm0_pass2, ymm0_pass3; int barrier_maybe; + uint8_t df_notneeded; flagcache_t f_exit; // flags status at end of instruction extcache_t e; // extcache at end of instruction (but before poping) flagcache_t f_entry; // flags status before the instruction begin |