From 5b9db71b876d09085756a74bdb7880c2121d4260 Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Sun, 9 Aug 2020 04:32:52 +1000 Subject: [PATCH] CPU/Recompiler: Fix mid-block software interrupts not updating pc Fixes Need for Speed: High Stakes hanging at boot. --- src/core/cpu_code_cache.cpp | 4 ++-- src/core/cpu_recompiler_code_generator.cpp | 10 ++++++---- src/core/cpu_recompiler_code_generator.h | 3 +-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/core/cpu_code_cache.cpp b/src/core/cpu_code_cache.cpp index 48b02b70e..1bd8bda9c 100644 --- a/src/core/cpu_code_cache.cpp +++ b/src/core/cpu_code_cache.cpp @@ -141,8 +141,8 @@ void Execute() reexecute_block: #if 0 - const u32 tick = g_system->GetGlobalTickCounter() + m_core->GetPendingTicks(); - if (tick == 61033207) + const u32 tick = TimingEvents::GetGlobalTickCounter() + CPU::GetPendingTicks(); + if (tick == 4188233674) __debugbreak(); #endif diff --git a/src/core/cpu_recompiler_code_generator.cpp b/src/core/cpu_recompiler_code_generator.cpp index 48e257bfd..2e8802c17 100644 --- a/src/core/cpu_recompiler_code_generator.cpp +++ b/src/core/cpu_recompiler_code_generator.cpp @@ -987,11 +987,12 @@ void CodeGenerator::UpdateCurrentInstructionPC(bool commit) } } -void CodeGenerator::WriteNewPC(const Value& value) +void CodeGenerator::WriteNewPC(const Value& value, bool commit) { // TODO: This _could_ be moved into the register cache, but would it gain anything? EmitStoreGuestRegister(Reg::pc, value); - m_next_pc_offset = 0; + if (commit) + m_next_pc_offset = 0; } bool CodeGenerator::Compile_Fallback(const CodeBlockInstruction& cbi) @@ -1671,12 +1672,12 @@ bool CodeGenerator::Compile_Branch(const CodeBlockInstruction& cbi) // converge point EmitBindLabel(&branch_not_taken); - WriteNewPC(next_pc); + WriteNewPC(next_pc, true); } else { // next_pc is not used for unconditional branches - WriteNewPC(branch_target); + WriteNewPC(branch_target, true); } // now invalidate lr becuase it was possibly written in the branch @@ -1917,6 +1918,7 @@ bool CodeGenerator::Compile_cop0(const CodeBlockInstruction& cbi) // we want to flush pc here m_register_cache.PushState(); m_register_cache.FlushAllGuestRegisters(false, true); + WriteNewPC(CalculatePC(), false); EmitExceptionExit(); m_register_cache.PopState(); diff --git a/src/core/cpu_recompiler_code_generator.h b/src/core/cpu_recompiler_code_generator.h index 9e0dca5b4..b59992330 100644 --- a/src/core/cpu_recompiler_code_generator.h +++ b/src/core/cpu_recompiler_code_generator.h @@ -171,10 +171,9 @@ private: void AddPendingCycles(bool commit); Value CalculatePC(u32 offset = 0); - void CalculatePC(Value* dest_value, u32 offset = 0); Value GetCurrentInstructionPC(u32 offset = 0); void UpdateCurrentInstructionPC(bool commit); - void WriteNewPC(const Value& value); + void WriteNewPC(const Value& value, bool commit); Value DoGTERegisterRead(u32 index); void DoGTERegisterWrite(u32 index, const Value& value);