diff options
Diffstat (limited to 'src/dynarec/rv64/dynarec_rv64_helper.c')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 0b597163..8a21e80e 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -2762,33 +2762,22 @@ static void flagsCacheTransform(dynarec_rv64_t* dyn, int ninst, int s1) int jmp = dyn->insts[ninst].x64.jmp_insts; if (jmp < 0) return; - if (dyn->f.dfnone) // 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 = 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: - 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) - go = 1; - break; - case SF_PENDING: - if (dyn->f.pending != SF_SET - && dyn->f.pending != SF_SET_PENDING - && dyn->f.pending != SF_PENDING) - go = 1; - else - go = (dyn->insts[jmp].f_entry.dfnone == dyn->f.dfnone) ? 0 : 1; + default: + if (go && !(dyn->insts[jmp].x64.need_before & X_PEND) && (dyn->f.pending != SF_UNKNOWN)) { + // just clear df flags + go = 0; + SW(xZR, xEmu, offsetof(x64emu_t, df)); + } break; } - if (dyn->insts[jmp].f_entry.dfnone && !dyn->f.dfnone) - go = 1; if (go) { if (dyn->f.pending != SF_PENDING) { LW(s1, xEmu, offsetof(x64emu_t, df)); |