Skip to content

Compare all 64 bits in the relational branches - #208

Open
Sinan-Karakaya wants to merge 1 commit into
ran-j:mainfrom
Sinan-Karakaya:fix/relational-branch-64bit
Open

Compare all 64 bits in the relational branches#208
Sinan-Karakaya wants to merge 1 commit into
ran-j:mainfrom
Sinan-Karakaya:fix/relational-branch-64bit

Conversation

@Sinan-Karakaya

Copy link
Copy Markdown
Contributor

BEQ and BNE already compare the full GPR via GPR_U64, but BLEZ, BGTZ, BLTZ and BGEZ — and their likely and and-link variants — were emitted against the low word only:

return fmt::format("GPR_S32(ctx, {}) <= 0", rsReg);

The R5900 compares the whole 64-bit register for these, so any value whose upper half is significant takes the wrong branch.

It is easy to miss because compilers usually reach these opcodes through the dsll32/dsra32 sign-extension idiom, which leaves a canonical value where the low word alone gives the right answer. Code that keeps a genuine 64-bit quantity in the register does not.

instruction_translator.cpp defers all branch opcodes to the control-flow emitter, so this is the only site.

Copilot AI lite review requested due to automatic review settings August 17, 2026 16:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes R5900 relational-branch codegen to compare the full 64-bit GPR value (matching hardware behavior) instead of only the low 32 bits, preventing incorrect branching when registers contain non-canonical 64-bit quantities.

Changes:

  • Emit BLEZ/BGTZ to use GPR_S64 instead of GPR_S32.
  • Emit REGIMM BLTZ/BGEZ (and variants) to use GPR_S64 instead of GPR_S32.
  • Add an explanatory comment describing why 64-bit compares are required (comment wording needs a small correction per review).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +407 to +410
// 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.
BEQ and BNE already compare the full GPR, but BLEZ, BGTZ, BLTZ and BGEZ (and
their likely/and-link variants) were emitted against the low word only. The
R5900 compares the whole 64-bit register, so any value whose upper half is
significant takes the wrong branch.

Compilers reach these opcodes through the dsll32/dsra32 sign-extension idiom,
which leaves a canonical value and hides the bug; code that keeps a genuine
64-bit quantity in the register does not.
@Sinan-Karakaya
Sinan-Karakaya force-pushed the fix/relational-branch-64bit branch from 3dbb483 to 874d13f Compare August 17, 2026 16:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants