[Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions #19

Merged
techwritescode merged 1 commit from r5900-disasm-mmi into r5900-ee 2026-10-15 22:09:45 +00:00

The R5900-only instructions were defined for the assembler but sat in a decoder namespace (VU0) that MipsDisassembler::getInstruction never queried, so llvm-objdump and llvm-mc --disassemble showed them as <unknown> or invalid. This moves them to the R5900 table, which is only tried when the r5900 feature is set.

Group Now decodes
Quadword load/store lq, sq, lqc2, sqc2
MMI (opcode 0x1c) all 87 p* instructions and qfsrv
Pipeline 1 mult1, multu1, madd1, maddu1 (2- and 3-operand), div1, divu1, mfhi1, mflo1, mthi1, mtlo1
Other 3-operand mult/multu/madd/maddu, mfsa, mtsa, mtsab, mtsah, bc0f/bc0t/bc0fl/bc0tl, the 14 debug COP0 moves (mfbpc ... mtdvbm)

Decoding details:

Case Behaviour
3-operand mult/multu with rd = 0 DecodeR5900MulRd fails, so the main table's 2-operand mult $rs, $rt is used
div1/divu1 2-operand def marked isAsmParserOnly; decodes as div1 $zero, $rs, $rt, the spelling GNU objdump uses and GNU as accepts
lqc2/sqc2 new DecodeVU0Mem decodes rt as a VF register ($vf9, not $9)

All changes are gated on the R5900: the R5900 decoder table is only reached when FeatureR5900 is set, and every moved def keeps its IsR5900Pred/HasVU0 predicate.

Tests:

  • llvm/test/MC/Disassembler/Mips/r5900-ee.txt: 143 encodings. 140 are every newly decodable def, assembled with mips64r5900el-ps2-elf-as -march=r5900; GNU objdump prints the same instruction and operands for each.
  • r5900-ee-invalid.txt: the same encodings do not decode with -mcpu=mips3.
  • lit for MC/Mips and MC/Disassembler/Mips: 557 passed, 53 expected failures (already there), 0 failures.

Bench ELF (scratch/bv/lto194-base-O2/.../ee-bench.unstripped.elf): the 99 <unknown> instruction words (lq, sq, MMI, 3-operand mult) now disassemble. The 264 <unknown> lines left are all 0x04170001, lld's MIPS trap fill between functions (trapInstr in lld/ELF/Arch/Mips.cpp, the R6 sigrie). GNU objdump prints these as .word 0x4170001, so they stay undecoded. llvm-objdump on this ELF needs ps2/llvm#17 to get past the EF_MIPS_ARCH abort; I checked the result with #17 applied.

🤖 Generated with Claude Code

The R5900-only instructions were defined for the assembler but sat in a decoder namespace (`VU0`) that `MipsDisassembler::getInstruction` never queried, so llvm-objdump and `llvm-mc --disassemble` showed them as `<unknown>` or invalid. This moves them to the `R5900` table, which is only tried when the `r5900` feature is set. | Group | Now decodes | |---|---| | Quadword load/store | `lq`, `sq`, `lqc2`, `sqc2` | | MMI (opcode 0x1c) | all 87 `p*` instructions and `qfsrv` | | Pipeline 1 | `mult1`, `multu1`, `madd1`, `maddu1` (2- and 3-operand), `div1`, `divu1`, `mfhi1`, `mflo1`, `mthi1`, `mtlo1` | | Other | 3-operand `mult`/`multu`/`madd`/`maddu`, `mfsa`, `mtsa`, `mtsab`, `mtsah`, `bc0f`/`bc0t`/`bc0fl`/`bc0tl`, the 14 debug COP0 moves (`mfbpc` ... `mtdvbm`) | Decoding details: | Case | Behaviour | |---|---| | 3-operand `mult`/`multu` with rd = 0 | `DecodeR5900MulRd` fails, so the main table's 2-operand `mult $rs, $rt` is used | | `div1`/`divu1` | 2-operand def marked `isAsmParserOnly`; decodes as `div1 $zero, $rs, $rt`, the spelling GNU objdump uses and GNU as accepts | | `lqc2`/`sqc2` | new `DecodeVU0Mem` decodes rt as a VF register (`$vf9`, not `$9`) | All changes are gated on the R5900: the `R5900` decoder table is only reached when `FeatureR5900` is set, and every moved def keeps its `IsR5900Pred`/`HasVU0` predicate. Tests: - `llvm/test/MC/Disassembler/Mips/r5900-ee.txt`: 143 encodings. 140 are every newly decodable def, assembled with `mips64r5900el-ps2-elf-as -march=r5900`; GNU objdump prints the same instruction and operands for each. - `r5900-ee-invalid.txt`: the same encodings do not decode with `-mcpu=mips3`. - lit for `MC/Mips` and `MC/Disassembler/Mips`: 557 passed, 53 expected failures (already there), 0 failures. Bench ELF (`scratch/bv/lto194-base-O2/.../ee-bench.unstripped.elf`): the 99 `<unknown>` instruction words (lq, sq, MMI, 3-operand mult) now disassemble. The 264 `<unknown>` lines left are all `0x04170001`, lld's MIPS trap fill between functions (`trapInstr` in lld/ELF/Arch/Mips.cpp, the R6 `sigrie`). GNU objdump prints these as `.word 0x4170001`, so they stay undecoded. llvm-objdump on this ELF needs ps2/llvm#17 to get past the EF_MIPS_ARCH abort; I checked the result with #17 applied. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
[Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions
Some checks failed
action.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (push) Failing after 0s
release-binaries-all.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (push) Failing after 0s
release-binaries.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (push) Failing after 0s
release-documentation.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (push) Failing after 0s
release-sources.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (push) Failing after 0s
Check for private emails used in PRs / validate_email (pull_request) Has been skipped
action.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (pull_request) Failing after 0s
Check LLVM ABI annotations / Check LLVM_ABI annotations with ids (pull_request) Has been skipped
CI Checks / Build and Test Linux (pull_request) Has been skipped
CI Checks / Build and Test Windows (pull_request) Has been skipped
CI Checks / Compute macOS Projects (pull_request) Has been skipped
CI Checks / Build and Test macOS arm64 (pull_request) Has been skipped
release-binaries-all.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (pull_request) Failing after 0s
release-binaries.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (pull_request) Failing after 0s
release-documentation.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (pull_request) Failing after 0s
release-sources.yml / [Mips] Disassemble the R5900 lq/sq, MMI and pipeline-1 instructions (pull_request) Failing after 0s
Add buildbot information to first PRs from new contributors / buildbot_comment (pull_request_target) Has been skipped
Labelling new pull requests / greeter (pull_request_target) Has been cancelled
Labelling new pull requests / automate-prs-labels (pull_request_target) Has been cancelled
e6d79fb764
The R5900-only instructions (lq/sq, lqc2/sqc2, the MMI group, mult1/madd1
and the other pipeline-1 HI/LO forms, the three-operand mult/madd forms,
mfsa/mtsa, bc0*, the debug COP0 moves) were in a decoder namespace the
disassembler never queried. Move them to the R5900 table, which is only
tried for the R5900. Three-operand mult/multu with rd == 0 fall through to
the main table's two-operand form, div1/divu1 decode to the $zero spelling
GNU objdump uses, and lqc2/sqc2 decode their register as a VF register.

The test encodings come from GNU as -march=r5900, and GNU objdump prints
the same instructions for them.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
techwritescode deleted branch r5900-disasm-mmi 2026-10-15 22:09:49 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
ps2/llvm!19
No description provided.