CPU/Recompiler: Handle self-modifying code within same block
Fixes Spyro 2 and 3 PAL with recompiler.
This commit is contained in:
parent
67fe97a17c
commit
d3717e66c3
|
@ -1008,6 +1008,13 @@ void CodeGenerator::InstructionEpilogue(const CodeBlockInstruction& cbi)
|
|||
}
|
||||
}
|
||||
|
||||
void CodeGenerator::TruncateBlockAtCurrentInstruction()
|
||||
{
|
||||
Log_DevPrintf("Truncating block %08X at %08X", m_block->GetPC(), m_current_instruction->pc);
|
||||
m_block_end = m_current_instruction + 1;
|
||||
WriteNewPC(CalculatePC(), true);
|
||||
}
|
||||
|
||||
void CodeGenerator::AddPendingCycles(bool commit)
|
||||
{
|
||||
if (m_delayed_cycles_add == 0)
|
||||
|
@ -1496,6 +1503,25 @@ bool CodeGenerator::Compile_Store(const CodeBlockInstruction& cbi)
|
|||
}
|
||||
|
||||
InstructionEpilogue(cbi);
|
||||
|
||||
if (address_spec)
|
||||
{
|
||||
const CPU::Segment seg = GetSegmentForAddress(*address_spec);
|
||||
if (seg == Segment::KUSEG || seg == Segment::KSEG0 || seg == Segment::KSEG1)
|
||||
{
|
||||
const PhysicalMemoryAddress phys_addr = VirtualAddressToPhysical(*address_spec);
|
||||
const PhysicalMemoryAddress block_start = VirtualAddressToPhysical(m_block->GetPC());
|
||||
const PhysicalMemoryAddress block_end = VirtualAddressToPhysical(
|
||||
m_block->GetPC() + static_cast<u32>(m_block->instructions.size()) * sizeof(Instruction));
|
||||
if (phys_addr >= block_start && phys_addr < block_end)
|
||||
{
|
||||
Log_WarningPrintf("Instruction %08X speculatively writes to %08X inside block %08X-%08X. Truncating block.",
|
||||
cbi.pc, phys_addr, block_start, block_end);
|
||||
TruncateBlockAtCurrentInstruction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -196,6 +196,7 @@ private:
|
|||
void BlockEpilogue();
|
||||
void InstructionPrologue(const CodeBlockInstruction& cbi, TickCount cycles, bool force_sync = false);
|
||||
void InstructionEpilogue(const CodeBlockInstruction& cbi);
|
||||
void TruncateBlockAtCurrentInstruction();
|
||||
void AddPendingCycles(bool commit);
|
||||
|
||||
Value CalculatePC(u32 offset = 0);
|
||||
|
|
Loading…
Reference in New Issue