CPU/CodeCache: Don't choke on indirect -> direct branch in delay slot
This commit is contained in:
parent
56b522a902
commit
bf5f53e1d1
|
@ -494,7 +494,6 @@ bool CompileBlock(CodeBlock* block)
|
||||||
{
|
{
|
||||||
u32 pc = block->GetPC();
|
u32 pc = block->GetPC();
|
||||||
bool is_branch_delay_slot = false;
|
bool is_branch_delay_slot = false;
|
||||||
bool is_unconditional_branch_delay_slot = false;
|
|
||||||
bool is_load_delay_slot = false;
|
bool is_load_delay_slot = false;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -519,6 +518,7 @@ bool CompileBlock(CodeBlock* block)
|
||||||
cbi.is_branch_delay_slot = is_branch_delay_slot;
|
cbi.is_branch_delay_slot = is_branch_delay_slot;
|
||||||
cbi.is_load_delay_slot = is_load_delay_slot;
|
cbi.is_load_delay_slot = is_load_delay_slot;
|
||||||
cbi.is_branch_instruction = IsBranchInstruction(cbi.instruction);
|
cbi.is_branch_instruction = IsBranchInstruction(cbi.instruction);
|
||||||
|
cbi.is_direct_branch_instruction = IsDirectBranchInstruction(cbi.instruction);
|
||||||
cbi.is_unconditional_branch_instruction = IsUnconditionalBranchInstruction(cbi.instruction);
|
cbi.is_unconditional_branch_instruction = IsUnconditionalBranchInstruction(cbi.instruction);
|
||||||
cbi.is_load_instruction = IsMemoryLoadInstruction(cbi.instruction);
|
cbi.is_load_instruction = IsMemoryLoadInstruction(cbi.instruction);
|
||||||
cbi.is_store_instruction = IsMemoryStoreInstruction(cbi.instruction);
|
cbi.is_store_instruction = IsMemoryStoreInstruction(cbi.instruction);
|
||||||
|
@ -543,9 +543,10 @@ bool CompileBlock(CodeBlock* block)
|
||||||
|
|
||||||
if (is_branch_delay_slot && cbi.is_branch_instruction)
|
if (is_branch_delay_slot && cbi.is_branch_instruction)
|
||||||
{
|
{
|
||||||
if (!is_unconditional_branch_delay_slot)
|
const CodeBlockInstruction& prev_cbi = block->instructions.back();
|
||||||
|
if (!prev_cbi.is_unconditional_branch_instruction || !prev_cbi.is_direct_branch_instruction)
|
||||||
{
|
{
|
||||||
Log_WarningPrintf("Conditional branch delay slot at %08X, skipping block", cbi.pc);
|
Log_WarningPrintf("Conditional or indirect branch delay slot at %08X, skipping block", cbi.pc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!IsDirectBranchInstruction(cbi.instruction))
|
if (!IsDirectBranchInstruction(cbi.instruction))
|
||||||
|
@ -555,7 +556,6 @@ bool CompileBlock(CodeBlock* block)
|
||||||
}
|
}
|
||||||
|
|
||||||
// change the pc for the second branch's delay slot, it comes from the first branch
|
// change the pc for the second branch's delay slot, it comes from the first branch
|
||||||
const CodeBlockInstruction& prev_cbi = block->instructions.back();
|
|
||||||
pc = GetBranchInstructionTarget(prev_cbi.instruction, prev_cbi.pc);
|
pc = GetBranchInstructionTarget(prev_cbi.instruction, prev_cbi.pc);
|
||||||
Log_DevPrintf("Double branch at %08X, using delay slot from %08X -> %08X", cbi.pc, prev_cbi.pc, pc);
|
Log_DevPrintf("Double branch at %08X, using delay slot from %08X -> %08X", cbi.pc, prev_cbi.pc, pc);
|
||||||
}
|
}
|
||||||
|
@ -570,7 +570,6 @@ bool CompileBlock(CodeBlock* block)
|
||||||
|
|
||||||
// if this is a branch, we grab the next instruction (delay slot), and then exit
|
// if this is a branch, we grab the next instruction (delay slot), and then exit
|
||||||
is_branch_delay_slot = cbi.is_branch_instruction;
|
is_branch_delay_slot = cbi.is_branch_instruction;
|
||||||
is_unconditional_branch_delay_slot = cbi.is_unconditional_branch_instruction;
|
|
||||||
|
|
||||||
// same for load delay
|
// same for load delay
|
||||||
is_load_delay_slot = cbi.has_load_delay;
|
is_load_delay_slot = cbi.has_load_delay;
|
||||||
|
|
|
@ -52,6 +52,7 @@ struct CodeBlockInstruction
|
||||||
u32 pc;
|
u32 pc;
|
||||||
|
|
||||||
bool is_branch_instruction : 1;
|
bool is_branch_instruction : 1;
|
||||||
|
bool is_direct_branch_instruction : 1;
|
||||||
bool is_unconditional_branch_instruction : 1;
|
bool is_unconditional_branch_instruction : 1;
|
||||||
bool is_branch_delay_slot : 1;
|
bool is_branch_delay_slot : 1;
|
||||||
bool is_load_instruction : 1;
|
bool is_load_instruction : 1;
|
||||||
|
|
Loading…
Reference in New Issue