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