CPU/Recompiler: Fix mid-block software interrupts not updating pc

Fixes Need for Speed: High Stakes hanging at boot.
This commit is contained in:
Connor McLaughlin 2020-08-09 04:32:52 +10:00
parent 223074b78f
commit 5b9db71b87
3 changed files with 9 additions and 8 deletions

View file

@ -141,8 +141,8 @@ void Execute()
reexecute_block: reexecute_block:
#if 0 #if 0
const u32 tick = g_system->GetGlobalTickCounter() + m_core->GetPendingTicks(); const u32 tick = TimingEvents::GetGlobalTickCounter() + CPU::GetPendingTicks();
if (tick == 61033207) if (tick == 4188233674)
__debugbreak(); __debugbreak();
#endif #endif

View file

@ -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? // TODO: This _could_ be moved into the register cache, but would it gain anything?
EmitStoreGuestRegister(Reg::pc, value); EmitStoreGuestRegister(Reg::pc, value);
m_next_pc_offset = 0; if (commit)
m_next_pc_offset = 0;
} }
bool CodeGenerator::Compile_Fallback(const CodeBlockInstruction& cbi) bool CodeGenerator::Compile_Fallback(const CodeBlockInstruction& cbi)
@ -1671,12 +1672,12 @@ bool CodeGenerator::Compile_Branch(const CodeBlockInstruction& cbi)
// converge point // converge point
EmitBindLabel(&branch_not_taken); EmitBindLabel(&branch_not_taken);
WriteNewPC(next_pc); WriteNewPC(next_pc, true);
} }
else else
{ {
// next_pc is not used for unconditional branches // 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 // 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 // we want to flush pc here
m_register_cache.PushState(); m_register_cache.PushState();
m_register_cache.FlushAllGuestRegisters(false, true); m_register_cache.FlushAllGuestRegisters(false, true);
WriteNewPC(CalculatePC(), false);
EmitExceptionExit(); EmitExceptionExit();
m_register_cache.PopState(); m_register_cache.PopState();

View file

@ -171,10 +171,9 @@ private:
void AddPendingCycles(bool commit); void AddPendingCycles(bool commit);
Value CalculatePC(u32 offset = 0); Value CalculatePC(u32 offset = 0);
void CalculatePC(Value* dest_value, u32 offset = 0);
Value GetCurrentInstructionPC(u32 offset = 0); Value GetCurrentInstructionPC(u32 offset = 0);
void UpdateCurrentInstructionPC(bool commit); void UpdateCurrentInstructionPC(bool commit);
void WriteNewPC(const Value& value); void WriteNewPC(const Value& value, bool commit);
Value DoGTERegisterRead(u32 index); Value DoGTERegisterRead(u32 index);
void DoGTERegisterWrite(u32 index, const Value& value); void DoGTERegisterWrite(u32 index, const Value& value);