mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-23 14:25:37 +00:00
CPU/CodeCache: Don't choke on indirect branches in delay slot
Fixes emulator crash/memory usage explosion in Shadow Master.
This commit is contained in:
parent
d7c3a0137f
commit
5164840c25
|
@ -527,6 +527,11 @@ bool CompileBlock(CodeBlock* block)
|
|||
Log_WarningPrintf("Conditional branch delay slot at %08X, skipping block", cbi.pc);
|
||||
return false;
|
||||
}
|
||||
if (!IsDirectBranchInstruction(cbi.instruction))
|
||||
{
|
||||
Log_WarningPrintf("Indirect branch in delay slot at %08X, skipping block", cbi.pc);
|
||||
return false;
|
||||
}
|
||||
|
||||
// change the pc for the second branch's delay slot, it comes from the first branch
|
||||
const CodeBlockInstruction& prev_cbi = block->instructions.back();
|
||||
|
|
|
@ -80,6 +80,24 @@ bool IsUnconditionalBranchInstruction(const Instruction& instruction)
|
|||
}
|
||||
}
|
||||
|
||||
bool IsDirectBranchInstruction(const Instruction& instruction)
|
||||
{
|
||||
switch (instruction.op)
|
||||
{
|
||||
case InstructionOp::j:
|
||||
case InstructionOp::jal:
|
||||
case InstructionOp::b:
|
||||
case InstructionOp::beq:
|
||||
case InstructionOp::bgtz:
|
||||
case InstructionOp::blez:
|
||||
case InstructionOp::bne:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
u32 GetBranchInstructionTarget(const Instruction& instruction, u32 instruction_pc)
|
||||
{
|
||||
switch (instruction.op)
|
||||
|
@ -96,6 +114,7 @@ u32 GetBranchInstructionTarget(const Instruction& instruction, u32 instruction_p
|
|||
return instruction_pc + 4 + (instruction.i.imm_sext32() << 2);
|
||||
|
||||
default:
|
||||
Panic("Trying to get branch target of indirect or invalid branch");
|
||||
return instruction_pc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,6 +213,7 @@ union Instruction
|
|||
// Instruction helpers.
|
||||
bool IsBranchInstruction(const Instruction& instruction);
|
||||
bool IsUnconditionalBranchInstruction(const Instruction& instruction);
|
||||
bool IsDirectBranchInstruction(const Instruction& instruction);
|
||||
u32 GetBranchInstructionTarget(const Instruction& instruction, u32 instruction_pc);
|
||||
bool IsMemoryLoadInstruction(const Instruction& instruction);
|
||||
bool IsMemoryStoreInstruction(const Instruction& instruction);
|
||||
|
|
Loading…
Reference in a new issue