CPU/NewRec: Enable delay slot swapping in more situations

Load delay is always updated, so don't need to swap when it's reading
from a delayed register. Branching on a delayed register will also be
fine, since it won't be flushed by the the branch executes.
This commit is contained in:
Stenzek 2024-05-19 23:55:53 +10:00
parent 09b43f962a
commit ab4c6f2dde
No known key found for this signature in database

View File

@ -391,23 +391,22 @@ bool CPU::NewRec::Compiler::TrySwapDelaySlot(Reg rs, Reg rt, Reg rd)
case InstructionOp::lbu:
case InstructionOp::lhu:
case InstructionOp::lwr:
case InstructionOp::sb:
case InstructionOp::sh:
case InstructionOp::swl:
case InstructionOp::sw:
case InstructionOp::swr:
{
if ((rs != Reg::zero && rs == opcode_rt) || (rt != Reg::zero && rt == opcode_rt) ||
(rd != Reg::zero && (rd == opcode_rs || rd == opcode_rt)) ||
(HasLoadDelay() && (m_load_delay_register == opcode_rs || m_load_delay_register == opcode_rt)))
(rd != Reg::zero && (rd == opcode_rs || rd == opcode_rt)))
{
goto is_unsafe;
}
}
break;
case InstructionOp::lwc2: // LWC2
case InstructionOp::swc2: // SWC2
case InstructionOp::sb:
case InstructionOp::sh:
case InstructionOp::swl:
case InstructionOp::sw:
case InstructionOp::swr:
case InstructionOp::lwc2:
case InstructionOp::swc2:
break;
case InstructionOp::funct: // SPECIAL
@ -432,9 +431,7 @@ bool CPU::NewRec::Compiler::TrySwapDelaySlot(Reg rs, Reg rt, Reg rd)
case InstructionFunct::sltu:
{
if ((rs != Reg::zero && rs == opcode_rd) || (rt != Reg::zero && rt == opcode_rd) ||
(rd != Reg::zero && (rd == opcode_rs || rd == opcode_rt)) ||
(HasLoadDelay() && (m_load_delay_register == opcode_rs || m_load_delay_register == opcode_rt ||
m_load_delay_register == opcode_rd)))
(rd != Reg::zero && (rd == opcode_rs || rd == opcode_rt)))
{
goto is_unsafe;
}
@ -445,11 +442,7 @@ bool CPU::NewRec::Compiler::TrySwapDelaySlot(Reg rs, Reg rt, Reg rd)
case InstructionFunct::multu:
case InstructionFunct::div:
case InstructionFunct::divu:
{
if (HasLoadDelay() && (m_load_delay_register == opcode_rs || m_load_delay_register == opcode_rt))
goto is_unsafe;
}
break;
break;
default:
goto is_unsafe;
@ -470,7 +463,7 @@ bool CPU::NewRec::Compiler::TrySwapDelaySlot(Reg rs, Reg rt, Reg rd)
case CopCommonInstruction::cfcn: // CFC0
{
if ((rs != Reg::zero && rs == opcode_rt) || (rt != Reg::zero && rt == opcode_rt) ||
(rd != Reg::zero && rd == opcode_rt) || (HasLoadDelay() && m_load_delay_register == opcode_rt))
(rd != Reg::zero && rd == opcode_rt))
{
goto is_unsafe;
}