diff --git a/src/core/cpu_recompiler_code_generator.cpp b/src/core/cpu_recompiler_code_generator.cpp index e2ff21631..ee117eaa0 100644 --- a/src/core/cpu_recompiler_code_generator.cpp +++ b/src/core/cpu_recompiler_code_generator.cpp @@ -2371,6 +2371,8 @@ bool CodeGenerator::Compile_Branch(Instruction instruction, const CodeCache::Ins // now invalidate lr because it was possibly written in the branch m_register_cache.InvalidateGuestRegister(lr_reg); + if (m_register_cache.GetLoadDelayRegister() == lr_reg) + m_register_cache.CancelLoadDelay(); } // we don't need to test the address of constant branches unless they're definitely misaligned, which would be diff --git a/src/core/cpu_recompiler_register_cache.cpp b/src/core/cpu_recompiler_register_cache.cpp index d6ff9baec..b8f6c769a 100644 --- a/src/core/cpu_recompiler_register_cache.cpp +++ b/src/core/cpu_recompiler_register_cache.cpp @@ -753,6 +753,16 @@ void RegisterCache::UpdateLoadDelay() } } +void RegisterCache::CancelLoadDelay() +{ + if (m_state.load_delay_register == Reg::count) + return; + + Log_DebugPrintf("Cancelling load delay of register %s", GetRegName(m_state.load_delay_register)); + m_state.load_delay_register = Reg::count; + m_state.load_delay_value.ReleaseAndClear(); +} + void RegisterCache::WriteLoadDelayToCPU(bool clear) { // There shouldn't be a flush at the same time as there's a new load delay. diff --git a/src/core/cpu_recompiler_register_cache.h b/src/core/cpu_recompiler_register_cache.h index 0f63053ea..305e93292 100644 --- a/src/core/cpu_recompiler_register_cache.h +++ b/src/core/cpu_recompiler_register_cache.h @@ -390,6 +390,9 @@ public: /// Moves load delay to the next load delay, and writes any previous load delay to the destination register. void UpdateLoadDelay(); + /// Cancels any present load delay. + void CancelLoadDelay(); + /// Writes the load delay to the CPU structure, so it is synced up with the interpreter. void WriteLoadDelayToCPU(bool clear);