diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 1248b1ab01..f31ad18913 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -992,6 +992,11 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) IntializeSpeculativeConstants(); } + BitSet32 previous_gpr_in_use{}; + BitSet32 previous_fpr_in_use{}; + BitSet32 previous_gpr_will_be_written{}; + BitSet32 previous_fpr_will_be_written{}; + // Translate instructions for (u32 i = 0; i < code_block.m_num_instructions; i++) { @@ -1233,12 +1238,17 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) gpr.Discard(op.gprDiscardable); fpr.Discard(op.fprDiscardable); } - gpr.Flush(~(op.gprWillBeRead | op.gprWillBeWritten) & (op.regsIn | op.regsOut), + gpr.Flush(~(op.gprWillBeRead | op.gprWillBeWritten) & previous_gpr_in_use, RegCache::FlushMode::Full); - fpr.Flush(~(op.fprWillBeRead | op.fprWillBeWritten) & (op.fregsIn | op.GetFregsOut()), + fpr.Flush(~(op.fprWillBeRead | op.fprWillBeWritten) & previous_fpr_in_use, RegCache::FlushMode::Full); - gpr.Flush(~op.gprWillBeWritten & op.regsOut, RegCache::FlushMode::Undirty); - fpr.Flush(~op.fprWillBeWritten & op.GetFregsOut(), RegCache::FlushMode::Undirty); + gpr.Flush(~op.gprWillBeWritten & previous_gpr_will_be_written, RegCache::FlushMode::Undirty); + fpr.Flush(~op.fprWillBeWritten & previous_fpr_will_be_written, RegCache::FlushMode::Undirty); + + previous_gpr_in_use = op.gprWillBeRead | op.gprWillBeWritten; + previous_fpr_in_use = op.fprWillBeRead | op.fprWillBeWritten; + previous_gpr_will_be_written = op.gprWillBeWritten; + previous_fpr_will_be_written = op.fprWillBeWritten; if (opinfo->flags & FL_LOADSTORE) ++js.numLoadStoreInst; diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index aba973346d..4258fb999d 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -1207,6 +1207,13 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) IntializeSpeculativeConstants(); } + BitSet32 previous_gpr_in_use{}; + BitSet32 previous_fpr_in_use{}; + BitSet8 previous_cr_in_use{}; + BitSet32 previous_gpr_will_be_written{}; + BitSet32 previous_fpr_will_be_written{}; + BitSet8 previous_cr_will_be_written{}; + // Translate instructions for (u32 i = 0; i < code_block.m_num_instructions; i++) { @@ -1416,16 +1423,22 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) fpr.DiscardRegisters(op.fprDiscardable); gpr.DiscardCRRegisters(op.crDiscardable); } - gpr.FlushRegisters(~(op.gprWillBeRead | op.gprWillBeWritten) & (op.regsIn | op.regsOut), + gpr.FlushRegisters(~(op.gprWillBeRead | op.gprWillBeWritten) & previous_gpr_in_use, FlushMode::Full); - fpr.FlushRegisters(~(op.fprWillBeRead | op.fprWillBeWritten) & - (op.fregsIn | op.GetFregsOut()), + fpr.FlushRegisters(~(op.fprWillBeRead | op.fprWillBeWritten) & previous_fpr_in_use, FlushMode::Full); - gpr.FlushCRRegisters(~(op.crWillBeRead | op.crWillBeWritten) & (op.crIn | op.crOut), + gpr.FlushCRRegisters(~(op.crWillBeRead | op.crWillBeWritten) & previous_cr_in_use, FlushMode::Full); - gpr.FlushRegisters(~op.gprWillBeWritten & op.regsOut, FlushMode::Undirty); - fpr.FlushRegisters(~op.fprWillBeWritten & op.GetFregsOut(), FlushMode::Undirty); - gpr.FlushCRRegisters(~op.crWillBeWritten & op.crOut, FlushMode::Undirty); + gpr.FlushRegisters(~op.gprWillBeWritten & previous_gpr_will_be_written, FlushMode::Undirty); + fpr.FlushRegisters(~op.fprWillBeWritten & previous_fpr_will_be_written, FlushMode::Undirty); + gpr.FlushCRRegisters(~op.crWillBeWritten & previous_cr_will_be_written, FlushMode::Undirty); + + previous_gpr_in_use = op.gprWillBeRead | op.gprWillBeWritten; + previous_fpr_in_use = op.fprWillBeRead | op.fprWillBeWritten; + previous_cr_in_use = op.crWillBeRead | op.crWillBeWritten; + previous_gpr_will_be_written = op.gprWillBeWritten; + previous_fpr_will_be_written = op.fprWillBeWritten; + previous_cr_will_be_written = op.crWillBeWritten; if (opinfo->flags & FL_LOADSTORE) ++js.numLoadStoreInst;