Alpha: fix decoder bugs and add test coverage#2967
Open
mattst88 wants to merge 7 commits into
Open
Conversation
GPRC[] is LLVM's register allocation order, not the architectural register number order. Using it to map hardware register fields 0-31 scrambled r9-r29 (e.g. field 9 → \$16, field 23 → \$9). Alpha_R0 through Alpha_R31 are contiguous in the enum (33-64), so Alpha_R0 + RegNo gives the correct architectural mapping directly. Update existing tests that encoded the wrong register names, and add new MC tests covering the previously scrambled r9-r29 range.
The LLVM decoder table constrained BR to Ra=31 and BSR to Ra=26, rejecting all other encodings as illegal. The Alpha ISA defines Ra as the return address destination for BSR (any writable register is valid) and as an unused hint field for BR (any register field is legal in existing binaries). Remove both CheckField constraints by zeroing the skip bytes to a no-op, and change the decode format from 25 (disp-only) to 27 (Ra + disp21) so the Ra operand is visible to callers. Override BR/BSR in the instruction printer, since the generated AsmWriter hardcodes "\$31" for BR and ignores Ra entirely for BSR. Update the placeholder BSR test (which had a malformed expected string) and add new tests for BR/BSR with non-default Ra values. Refs: capstone-engine#2582
The LLVM decoder mapped opcode 0x00 to COND_BRANCH_I (format 0), which tried to interpret bits[20:0] as a register number. This failed for any PAL function code > 31 (e.g. 0x83 gentrap, 0x1020b). Add decode format 31 that extracts bits[25:0] as a single immediate, switch opcode 0x00 to use it, map COND_BRANCH_I to the new public Alpha_INS_CALL_PAL, and override the printer to emit "call_pal <imm>".
The LLVM decoder required JMP to have Ra=31 and hint=0, and JSR to have specific Ra/Rb pairs (26/27 or 23/27) with hint=0. Real-world code uses arbitrary combinations: JMP with Ra!=31 to save return addresses, JSR with Ra=26 and Rb!=27, or non-zero hint fields for branch prediction. Remove all Ra, Rb, and hint constraints for JMP and JSR. Switch both from decode format 17 (Rb only) and 14 (no operands) to format 18 (Ra + Rb + hint14). Add printer override to emit the three-operand form: "jmp/jsr \$ra,(\$rb),hint". Closes: capstone-engine#2582
The LLVM assembler emits these barrier instructions with Ra=Rb=31, but the decoder required Ra=Rb=0 (bits[25:16]=0), causing all canonical encodings to fail. Remove the CheckField constraint so any Ra/Rb combination is accepted. The instructions carry no register operands in their decode format, so the field values do not affect the output. Closes: capstone-engine#2795
s4addq (register and literal forms), cvttq/svc, cvtts/sui, cvtqs/sui, and cvtqt/sui had no MC tests despite being reachable instructions.
RET (opcode 0x1a, bits[15:14]=10) shares identical operation semantics with JMP/JSR/JSR_COROUTINE — all four differ only in branch-prediction hints. The decoder incorrectly required Ra=31, Rb=26, hint=1 exactly; any other encoding failed to decode. RC and RS (opcode 0x18) have an unused Rb field. The decoder checked Rb==0 (R0), but convention is to set unused fields to R31 (=31), so any real-world encoding produced by a compiler would fail to decode. Remove the restrictive CheckField constraints on RET, RC, and RS. Update RETDAG's operand table to carry Ra+Rb+hint (format 18), and add a ret printer in Alpha_LLVM_printInstruction matching the existing jmp/jsr handling. Tests added: ret $0,($1),3 (non-canonical RET); rc/rs $1 with Rb=R31.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This series fixes several bugs in the Alpha disassembler where the
LLVM-generated decoder tables used overly-restrictive
CheckFieldconstraints, causing legitimate instruction encodings to fail to decode.
Commits
Alpha: fix integer register class decoding order
DecodeGPRCRegisterClassindexed into the LLVMGPRC[]allocationpriority array, which is not in architectural order. Alpha integer
registers are contiguous (
Alpha_R0..Alpha_R31), so the fix isAlpha_R0 + RegNo.Alpha: fix BR/BSR to accept any Ra register (Refs #2582)
BR and BSR use the Ra field as a write destination for the updated PC.
The decoder required Ra=31; any other value failed to decode.
Alpha: fix CALL_PAL to decode full 26-bit function code
The decoder used format 0 (no operands) and ignored bits[25:0]. Added
format 31 (26-bit immediate) so the PALcode function field is captured.
Alpha: fix JMP/JSR to accept any Ra, Rb, and hint (Closes #2582)
All four Jump instructions (JMP/JSR/RET/JSR_COROUTINE) perform identical
operations and differ only in branch-prediction hints. The decoder
required Ra=31, Rb specific values, and hint=0 for JMP/JSR.
Alpha: fix TRAPB/EXCB/MB/WMB to decode with any Ra/Rb field (Closes #2795)
These instructions architecturally ignore Ra and Rb. Setting them to
R31 is a software convention, not a hardware requirement. The decoder
rejected any encoding where Ra/Rb ≠ 31.
Alpha: fix RET/RC/RS to decode with any register fields
RET (opcode 0x1a, bits[15:14]=10) suffered the same constraint as
JMP/JSR: decoder required Ra=31, Rb=26, hint=1 exactly.
RC and RS (opcode 0x18) have an unused Rb field. The decoder checked
Rb==0 (R0), but the software convention is R31, so real compiler output
failed to decode.
Alpha: add missing test coverage for s4addq and cvt FP variants
Testing
All 425 MC tests and 2 detail tests pass.