Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions ps2xRecomp/src/lib/control_flow_emitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,25 +404,29 @@ namespace ps2recomp
case OPCODE_BNE:
case OPCODE_BNEL:
return fmt::format("GPR_U64(ctx, {}) != GPR_U64(ctx, {})", rsReg, rtReg);
// The R5900 compares the full 64-bit GPR for the relational branches, as it
// already does for BEQ/BNE above. Comparing only the low word takes the wrong
// branch whenever the upper half is significant, which happens with the
// dsll32/dsra32 sign-extension idiom compilers emit ahead of these opcodes.
case OPCODE_BLEZ:
case OPCODE_BLEZL:
return fmt::format("GPR_S32(ctx, {}) <= 0", rsReg);
return fmt::format("GPR_S64(ctx, {}) <= 0", rsReg);
case OPCODE_BGTZ:
case OPCODE_BGTZL:
return fmt::format("GPR_S32(ctx, {}) > 0", rsReg);
return fmt::format("GPR_S64(ctx, {}) > 0", rsReg);
case OPCODE_REGIMM:
switch (m_branchInst.rt)
{
case REGIMM_BLTZ:
case REGIMM_BLTZL:
case REGIMM_BLTZAL:
case REGIMM_BLTZALL:
return fmt::format("GPR_S32(ctx, {}) < 0", rsReg);
return fmt::format("GPR_S64(ctx, {}) < 0", rsReg);
case REGIMM_BGEZ:
case REGIMM_BGEZL:
case REGIMM_BGEZAL:
case REGIMM_BGEZALL:
return fmt::format("GPR_S32(ctx, {}) >= 0", rsReg);
return fmt::format("GPR_S64(ctx, {}) >= 0", rsReg);
default:
return "false";
}
Expand Down