mirror of
https://github.com/stenzek/duckstation.git
synced 2024-11-23 13:59:49 +00:00
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::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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user