From 1008e3e78b1ad23d0afbc20d04ed483104e20870 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Wed, 17 Jun 2026 13:15:23 -0400 Subject: [PATCH 1/7] Alpha: fix integer register class decoding order MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- arch/Alpha/AlphaDisassembler.c | 2 +- tests/MC/Alpha/insn-alpha-be.s.yaml | 2 +- tests/MC/Alpha/insn-alpha.s.yaml | 56 +++++++++++++++++++++++- tests/details/alpha.yaml | 65 ++++++++++++++-------------- tests/details/cs_common_details.yaml | 24 +++++----- 5 files changed, 101 insertions(+), 48 deletions(-) diff --git a/arch/Alpha/AlphaDisassembler.c b/arch/Alpha/AlphaDisassembler.c index f2e2e56c74..697cf682a9 100644 --- a/arch/Alpha/AlphaDisassembler.c +++ b/arch/Alpha/AlphaDisassembler.c @@ -41,7 +41,7 @@ static DecodeStatus DecodeGPRCRegisterClass(MCInst *Inst, unsigned RegNo, if (RegNo > 31) return MCDisassembler_Fail; - unsigned Register = GPRC[RegNo]; + unsigned Register = Alpha_R0 + RegNo; MCOperand_CreateReg0(Inst, (Register)); return MCDisassembler_Success; } diff --git a/tests/MC/Alpha/insn-alpha-be.s.yaml b/tests/MC/Alpha/insn-alpha-be.s.yaml index 96fb54010e..7a0b57cc8b 100644 --- a/tests/MC/Alpha/insn-alpha-be.s.yaml +++ b/tests/MC/Alpha/insn-alpha-be.s.yaml @@ -988,7 +988,7 @@ test_cases: expected: insns: - - asm_text: "jmp $31,$12,0" + asm_text: "jmp $31,$26,0" - input: bytes: [ 0x6b, 0x5b, 0x40, 0x00 ] diff --git a/tests/MC/Alpha/insn-alpha.s.yaml b/tests/MC/Alpha/insn-alpha.s.yaml index 54fcbb4c33..15b9293b52 100644 --- a/tests/MC/Alpha/insn-alpha.s.yaml +++ b/tests/MC/Alpha/insn-alpha.s.yaml @@ -988,7 +988,7 @@ test_cases: expected: insns: - - asm_text: "jmp $31,$12,0" + asm_text: "jmp $31,$26,0" - input: bytes: [ 0x00, 0x40, 0x5b, 0x6b ] @@ -1781,3 +1781,57 @@ test_cases: insns: - asm_text: "zapnot $1,0xde,$3" + - + input: + bytes: [ 0x09, 0x04, 0xff, 0x47 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "bis $31,$31,$9" + - + input: + bytes: [ 0x10, 0x04, 0xff, 0x47 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "bis $31,$31,$16" + - + input: + bytes: [ 0x13, 0x04, 0xff, 0x47 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "bis $31,$31,$19" + - + input: + bytes: [ 0x15, 0x04, 0xff, 0x47 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "bis $31,$31,$21" + - + input: + bytes: [ 0x17, 0x04, 0xff, 0x47 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "bis $31,$31,$23" + - + input: + bytes: [ 0x1d, 0x04, 0xff, 0x47 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "bis $31,$31,$29" diff --git a/tests/details/alpha.yaml b/tests/details/alpha.yaml index 49e4245c3e..90d748c8b2 100644 --- a/tests/details/alpha.yaml +++ b/tests/details/alpha.yaml @@ -8,40 +8,42 @@ test_cases: expected: insns: - - asm_text: "ldah $15,2($13)" + asm_text: "ldah $29,2($27)" details: + regs_read: [ $27 ] + regs_write: [ $28, $29 ] alpha: operands: - type: ALPHA_OP_REG - reg: $15 + reg: $29 - type: ALPHA_OP_IMM imm: 0x2 - type: ALPHA_OP_REG - reg: $13 - regs_read: [ $13 ] - regs_write: [ $28, $15 ] + reg: $27 - - asm_text: "lda $15,0x7a50($15)" + asm_text: "lda $29,0x7a50($29)" details: + regs_read: [ $29 ] + regs_write: [ $28, $29 ] alpha: operands: - type: ALPHA_OP_REG - reg: $15 + reg: $29 - type: ALPHA_OP_IMM imm: 0x7a50 - type: ALPHA_OP_REG - reg: $15 - regs_read: [ $15 ] - regs_write: [ $28, $15 ] + reg: $29 - asm_text: "lda $30,0xffd0($30)" details: + regs_read: [ $30 ] + regs_write: [ $28, $30 ] alpha: operands: - @@ -53,24 +55,22 @@ test_cases: - type: ALPHA_OP_REG reg: $30 - regs_read: [ $30 ] - regs_write: [ $28, $30 ] - - asm_text: "stq $12,0($30)" + asm_text: "stq $26,0($30)" details: + regs_read: [ $26, $30 ] + regs_write: [ $28 ] alpha: operands: - type: ALPHA_OP_REG - reg: $12 + reg: $26 - type: ALPHA_OP_IMM imm: 0x0 - type: ALPHA_OP_REG reg: $30 - regs_read: [ $12, $30 ] - regs_write: [ $28 ] - input: bytes: [ 0x27, 0xbb, 0x00, 0x02, 0x23, 0xbd, 0x7a, 0x50, 0x23, 0xde, 0xff, 0xd0, 0xb7, 0x5e, 0x00, 0x00 ] @@ -80,40 +80,42 @@ test_cases: expected: insns: - - asm_text: "ldah $15,2($13)" + asm_text: "ldah $29,2($27)" details: + regs_read: [ $27 ] + regs_write: [ $28, $29 ] alpha: operands: - type: ALPHA_OP_REG - reg: $15 + reg: $29 - type: ALPHA_OP_IMM imm: 0x2 - type: ALPHA_OP_REG - reg: $13 - regs_read: [ $13 ] - regs_write: [ $28, $15 ] + reg: $27 - - asm_text: "lda $15,0x7a50($15)" + asm_text: "lda $29,0x7a50($29)" details: + regs_read: [ $29 ] + regs_write: [ $28, $29 ] alpha: operands: - type: ALPHA_OP_REG - reg: $15 + reg: $29 - type: ALPHA_OP_IMM imm: 0x7a50 - type: ALPHA_OP_REG - reg: $15 - regs_read: [ $15 ] - regs_write: [ $28, $15 ] + reg: $29 - asm_text: "lda $30,0xffd0($30)" details: + regs_read: [ $30 ] + regs_write: [ $28, $30 ] alpha: operands: - @@ -125,22 +127,19 @@ test_cases: - type: ALPHA_OP_REG reg: $30 - regs_read: [ $30 ] - regs_write: [ $28, $30 ] - - asm_text: "stq $12,0($30)" + asm_text: "stq $26,0($30)" details: + regs_read: [ $26, $30 ] + regs_write: [ $28 ] alpha: operands: - type: ALPHA_OP_REG - reg: $12 + reg: $26 - type: ALPHA_OP_IMM imm: 0x0 - type: ALPHA_OP_REG reg: $30 - regs_read: [ $12, $30 ] - regs_write: [ $28 ] - diff --git a/tests/details/cs_common_details.yaml b/tests/details/cs_common_details.yaml index 2e835a2ead..303419d199 100644 --- a/tests/details/cs_common_details.yaml +++ b/tests/details/cs_common_details.yaml @@ -1216,15 +1216,15 @@ test_cases: expected: insns: - - asm_text: "ldah $15,2($13)" + asm_text: "ldah $29,2($27)" mnemonic: "ldah" - op_str: "$15,2($13)" + op_str: "$29,2($27)" details: regs_impl_write: [ $28 ] - - asm_text: "lda $15,0x7a50($15)" + asm_text: "lda $29,0x7a50($29)" mnemonic: "lda" - op_str: "$15,0x7a50($15)" + op_str: "$29,0x7a50($29)" details: regs_impl_write: [ $28 ] - @@ -1234,9 +1234,9 @@ test_cases: details: regs_impl_write: [ $28 ] - - asm_text: "stq $12,0($30)" + asm_text: "stq $26,0($30)" mnemonic: "stq" - op_str: "$12,0($30)" + op_str: "$26,0($30)" details: regs_impl_write: [ $28 ] @@ -1249,15 +1249,15 @@ test_cases: expected: insns: - - asm_text: "ldah $15,2($13)" + asm_text: "ldah $29,2($27)" mnemonic: "ldah" - op_str: "$15,2($13)" + op_str: "$29,2($27)" details: regs_impl_write: [ $28 ] - - asm_text: "lda $15,0x7a50($15)" + asm_text: "lda $29,0x7a50($29)" mnemonic: "lda" - op_str: "$15,0x7a50($15)" + op_str: "$29,0x7a50($29)" details: regs_impl_write: [ $28 ] - @@ -1267,9 +1267,9 @@ test_cases: details: regs_impl_write: [ $28 ] - - asm_text: "stq $12,0($30)" + asm_text: "stq $26,0($30)" mnemonic: "stq" - op_str: "$12,0($30)" + op_str: "$26,0($30)" details: regs_impl_write: [ $28 ] - From c0420a43339b800707d6d13634945d0ca578615f Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Wed, 17 Jun 2026 13:18:23 -0400 Subject: [PATCH 2/7] Alpha: fix BR/BSR to accept any Ra register 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: https://github.com/capstone-engine/capstone/issues/2582 --- arch/Alpha/AlphaGenDisassemblerTables.inc | 8 +++---- arch/Alpha/AlphaInstPrinter.c | 13 ++++++++++ tests/MC/Alpha/insn-alpha-be.s.yaml | 2 +- tests/MC/Alpha/insn-alpha.s.yaml | 29 ++++++++++++++++++++++- 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/arch/Alpha/AlphaGenDisassemblerTables.inc b/arch/Alpha/AlphaGenDisassemblerTables.inc index 9d616b033a..2c854064e2 100644 --- a/arch/Alpha/AlphaGenDisassemblerTables.inc +++ b/arch/Alpha/AlphaGenDisassemblerTables.inc @@ -527,8 +527,8 @@ static const uint8_t DecoderTable32[] = { /* 2540 */ MCD_OPC_FilterValue, 47, 4, 0, 0, // Skip to: 2549 /* 2545 */ MCD_OPC_Decode, 226, 3, 24, // Opcode: STQ_C /* 2549 */ MCD_OPC_FilterValue, 48, 11, 0, 0, // Skip to: 2565 -/* 2554 */ MCD_OPC_CheckField, 21, 5, 31, 146, 0, 0, // Skip to: 2707 -/* 2561 */ MCD_OPC_Decode, 155, 2, 25, // Opcode: BR +/* 2554 */ MCD_OPC_CheckField, 21, 5, 31, 0, 0, 0, // Skip to: 2561 (no-op: accept any Ra) +/* 2561 */ MCD_OPC_Decode, 155, 2, 27, // Opcode: BR (decode Ra + disp21) /* 2565 */ MCD_OPC_FilterValue, 49, 4, 0, 0, // Skip to: 2574 /* 2570 */ MCD_OPC_Decode, 230, 2, 26, // Opcode: FBEQ /* 2574 */ MCD_OPC_FilterValue, 50, 4, 0, 0, // Skip to: 2583 @@ -536,8 +536,8 @@ static const uint8_t DecoderTable32[] = { /* 2583 */ MCD_OPC_FilterValue, 51, 4, 0, 0, // Skip to: 2592 /* 2588 */ MCD_OPC_Decode, 233, 2, 26, // Opcode: FBLE /* 2592 */ MCD_OPC_FilterValue, 52, 11, 0, 0, // Skip to: 2608 -/* 2597 */ MCD_OPC_CheckField, 21, 5, 26, 103, 0, 0, // Skip to: 2707 -/* 2604 */ MCD_OPC_Decode, 156, 2, 25, // Opcode: BSR +/* 2597 */ MCD_OPC_CheckField, 21, 5, 26, 0, 0, 0, // Skip to: 2604 (no-op: accept any Ra) +/* 2604 */ MCD_OPC_Decode, 156, 2, 27, // Opcode: BSR (decode Ra + disp21) /* 2608 */ MCD_OPC_FilterValue, 53, 4, 0, 0, // Skip to: 2617 /* 2613 */ MCD_OPC_Decode, 235, 2, 26, // Opcode: FBNE /* 2617 */ MCD_OPC_FilterValue, 54, 4, 0, 0, // Skip to: 2626 diff --git a/arch/Alpha/AlphaInstPrinter.c b/arch/Alpha/AlphaInstPrinter.c index a800954584..2d53fddc0a 100644 --- a/arch/Alpha/AlphaInstPrinter.c +++ b/arch/Alpha/AlphaInstPrinter.c @@ -85,6 +85,19 @@ const char *Alpha_LLVM_getRegisterName(csh handle, unsigned int id) void Alpha_LLVM_printInstruction(MCInst *MI, SStream *O, void *Info) { + unsigned Opcode = MCInst_getOpcode(MI); + /* + * The generated AsmWriter hardcodes "$31" for BR and restricts BSR to + * Ra=26. Format 27 now decodes Ra as operand[0] and disp21 as + * operand[1], so we must print them explicitly here. + */ + if (Opcode == Alpha_BR || Opcode == Alpha_BSR) { + SStream_concat0(O, Opcode == Alpha_BR ? "br " : "bsr "); + printOperand(MI, 0, O); + SStream_concat1(O, ','); + printOperandAddr(MI, MI->address, 1, O); + return; + } printAliasInstr(MI, MI->address, O); printInstruction(MI, MI->address, O); } diff --git a/tests/MC/Alpha/insn-alpha-be.s.yaml b/tests/MC/Alpha/insn-alpha-be.s.yaml index 7a0b57cc8b..1e23ab5f3a 100644 --- a/tests/MC/Alpha/insn-alpha-be.s.yaml +++ b/tests/MC/Alpha/insn-alpha-be.s.yaml @@ -196,7 +196,7 @@ test_cases: expected: insns: - - asm_text: "bsr $26,$0xfffffffffffffff4 ..ng" + asm_text: "bsr $26,0xfffffffffffffff4" - input: bytes: [ 0x44, 0x22, 0x04, 0x83 ] diff --git a/tests/MC/Alpha/insn-alpha.s.yaml b/tests/MC/Alpha/insn-alpha.s.yaml index 15b9293b52..37c8816656 100644 --- a/tests/MC/Alpha/insn-alpha.s.yaml +++ b/tests/MC/Alpha/insn-alpha.s.yaml @@ -196,7 +196,7 @@ test_cases: expected: insns: - - asm_text: "bsr $26,$0xfffffffffffffff4 ..ng" + asm_text: "bsr $26,0xfffffffffffffff4" - input: bytes: [ 0x83, 0x04, 0x22, 0x44 ] @@ -1835,3 +1835,30 @@ test_cases: insns: - asm_text: "bis $31,$31,$29" + - + input: + bytes: [ 0x00, 0x00, 0x40, 0xc3 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "br $26,4" + - + input: + bytes: [ 0x03, 0x00, 0x20, 0xc0 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "br $1,0x10" + - + input: + bytes: [ 0x03, 0x00, 0x20, 0xd0 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "bsr $1,0x10" From 24aac9da6ab924ded94b118bc5d26562ceac6378 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Wed, 17 Jun 2026 13:20:49 -0400 Subject: [PATCH 3/7] Alpha: fix CALL_PAL to decode full 26-bit function code 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 ". --- arch/Alpha/AlphaGenCSMappingInsn.inc | 2 +- arch/Alpha/AlphaGenCSMappingInsnName.inc | 1 + arch/Alpha/AlphaGenCSMappingInsnOp.inc | 6 ++--- arch/Alpha/AlphaGenDisassemblerTables.inc | 6 ++++- arch/Alpha/AlphaInstPrinter.c | 5 +++++ include/capstone/alpha.h | 1 + tests/MC/Alpha/insn-alpha.s.yaml | 27 +++++++++++++++++++++++ 7 files changed, 42 insertions(+), 6 deletions(-) diff --git a/arch/Alpha/AlphaGenCSMappingInsn.inc b/arch/Alpha/AlphaGenCSMappingInsn.inc index 8944ebb9fc..5fdd91a5c1 100644 --- a/arch/Alpha/AlphaGenCSMappingInsn.inc +++ b/arch/Alpha/AlphaGenCSMappingInsn.inc @@ -2296,7 +2296,7 @@ }, { /* COND_BRANCH imm:$opc, GPRC:$R, bb:$dst */ - Alpha_COND_BRANCH_I /* 318 */, Alpha_INS_COND_BRANCH, + Alpha_COND_BRANCH_I /* 318 */, Alpha_INS_CALL_PAL, #ifndef CAPSTONE_DIET { 0 }, { 0 }, { Alpha_GRP_JUMP, Alpha_GRP_BRANCH_RELATIVE, 0 }, 1, 0, {{ 0 }}, diff --git a/arch/Alpha/AlphaGenCSMappingInsnName.inc b/arch/Alpha/AlphaGenCSMappingInsnName.inc index b934548c9c..7b34e665a1 100644 --- a/arch/Alpha/AlphaGenCSMappingInsnName.inc +++ b/arch/Alpha/AlphaGenCSMappingInsnName.inc @@ -47,6 +47,7 @@ "cmptun/su", // Alpha_INS_CMPTUNsSU "cmpule", // Alpha_INS_CMPULE "cmpult", // Alpha_INS_CMPULT + "call_pal", // Alpha_INS_CALL_PAL "COND_BRANCH", // Alpha_INS_COND_BRANCH "cpyse", // Alpha_INS_CPYSE "cpysn", // Alpha_INS_CPYSN diff --git a/arch/Alpha/AlphaGenCSMappingInsnOp.inc b/arch/Alpha/AlphaGenCSMappingInsnOp.inc index 6f2772dde8..53eda3a205 100644 --- a/arch/Alpha/AlphaGenCSMappingInsnOp.inc +++ b/arch/Alpha/AlphaGenCSMappingInsnOp.inc @@ -1191,11 +1191,9 @@ { CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_Other, CS_DATA_TYPE_LAST }, }, /* dst */ { 0 } }}, -{ /* Alpha_COND_BRANCH_I (318) - Alpha_INS_COND_BRANCH - COND_BRANCH imm:$opc, GPRC:$R, bb:$dst */ +{ /* Alpha_COND_BRANCH_I (318) - Alpha_INS_CALL_PAL - call_pal imm:$func */ { - { CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* opc */ - { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* R */ - { CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_Other, CS_DATA_TYPE_LAST }, }, /* dst */ + { CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* func */ { 0 } }}, { /* Alpha_CPYSES (319) - Alpha_INS_CPYSE - cpyse $RA,$RB,$RC */ diff --git a/arch/Alpha/AlphaGenDisassemblerTables.inc b/arch/Alpha/AlphaGenDisassemblerTables.inc index 2c854064e2..3842ffd358 100644 --- a/arch/Alpha/AlphaGenDisassemblerTables.inc +++ b/arch/Alpha/AlphaGenDisassemblerTables.inc @@ -30,7 +30,7 @@ static InsnType fname(InsnType insn, unsigned startBit, unsigned numBits) \ static const uint8_t DecoderTable32[] = { /* 0 */ MCD_OPC_ExtractField, 26, 6, // Inst{31-26} ... /* 3 */ MCD_OPC_FilterValue, 0, 4, 0, 0, // Skip to: 12 -/* 8 */ MCD_OPC_Decode, 190, 2, 0, // Opcode: COND_BRANCH_I +/* 8 */ MCD_OPC_Decode, 190, 2, 31, // Opcode: COND_BRANCH_I (CALL_PAL: 26-bit imm) /* 12 */ MCD_OPC_FilterValue, 8, 4, 0, 0, // Skip to: 21 /* 17 */ MCD_OPC_Decode, 144, 3, 1, // Opcode: LDA /* 21 */ MCD_OPC_FilterValue, 9, 4, 0, 0, // Skip to: 30 @@ -931,6 +931,10 @@ static DecodeStatus fname(DecodeStatus S, unsigned Idx, InsnType insn, MCInst *M tmp = fieldname(insn, 16, 5); \ if (DecodeF8RCRegisterClass(MI, tmp, Address, Decoder) == MCDisassembler_Fail) { return MCDisassembler_Fail; } \ return S; \ + case 31: \ + tmp = fieldname(insn, 0, 26); \ + MCOperand_CreateImm0(MI, tmp); \ + return S; \ } \ } diff --git a/arch/Alpha/AlphaInstPrinter.c b/arch/Alpha/AlphaInstPrinter.c index 2d53fddc0a..1f0d598885 100644 --- a/arch/Alpha/AlphaInstPrinter.c +++ b/arch/Alpha/AlphaInstPrinter.c @@ -91,6 +91,11 @@ void Alpha_LLVM_printInstruction(MCInst *MI, SStream *O, void *Info) * Ra=26. Format 27 now decodes Ra as operand[0] and disp21 as * operand[1], so we must print them explicitly here. */ + if (Opcode == Alpha_COND_BRANCH_I) { + SStream_concat0(O, "call_pal "); + printOperand(MI, 0, O); + return; + } if (Opcode == Alpha_BR || Opcode == Alpha_BSR) { SStream_concat0(O, Opcode == Alpha_BR ? "br " : "bsr "); printOperand(MI, 0, O); diff --git a/include/capstone/alpha.h b/include/capstone/alpha.h index e0baa43b01..e96151f2cb 100644 --- a/include/capstone/alpha.h +++ b/include/capstone/alpha.h @@ -163,6 +163,7 @@ typedef enum alpha_insn { Alpha_INS_CMPTUNsSU, Alpha_INS_CMPULE, Alpha_INS_CMPULT, + Alpha_INS_CALL_PAL, Alpha_INS_COND_BRANCH, Alpha_INS_CPYSE, Alpha_INS_CPYSN, diff --git a/tests/MC/Alpha/insn-alpha.s.yaml b/tests/MC/Alpha/insn-alpha.s.yaml index 37c8816656..35831795e4 100644 --- a/tests/MC/Alpha/insn-alpha.s.yaml +++ b/tests/MC/Alpha/insn-alpha.s.yaml @@ -1862,3 +1862,30 @@ test_cases: insns: - asm_text: "bsr $1,0x10" + - + input: + bytes: [ 0x00, 0x00, 0x00, 0x00 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "call_pal 0" + - + input: + bytes: [ 0x83, 0x00, 0x00, 0x00 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "call_pal 0x83" + - + input: + bytes: [ 0x0b, 0x02, 0x01, 0x00 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "call_pal 0x1020b" From b00953a360894597ea9b6a67ea9c9cc702057eda Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Wed, 17 Jun 2026 13:47:03 -0400 Subject: [PATCH 4/7] Alpha: fix JMP/JSR to accept any Ra, Rb, and hint 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: https://github.com/capstone-engine/capstone/issues/2582 --- arch/Alpha/AlphaGenCSMappingInsnOp.inc | 9 ++++-- arch/Alpha/AlphaGenDisassemblerTables.inc | 16 +++++----- arch/Alpha/AlphaInstPrinter.c | 17 ++++++++++ tests/MC/Alpha/insn-alpha-be.s.yaml | 2 +- tests/MC/Alpha/insn-alpha.s.yaml | 38 ++++++++++++++++++++++- 5 files changed, 70 insertions(+), 12 deletions(-) diff --git a/arch/Alpha/AlphaGenCSMappingInsnOp.inc b/arch/Alpha/AlphaGenCSMappingInsnOp.inc index 53eda3a205..ee4a68dbd6 100644 --- a/arch/Alpha/AlphaGenCSMappingInsnOp.inc +++ b/arch/Alpha/AlphaGenCSMappingInsnOp.inc @@ -1723,13 +1723,18 @@ { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* RA */ { 0 } }}, -{ /* Alpha_JMP (396) - Alpha_INS_JMP - jmp $$31,{$RS},0 */ +{ /* Alpha_JMP (396) - Alpha_INS_JMP - jmp $RD,($RS),$DISP */ { + { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* RD */ { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* RS */ + { CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* DISP */ { 0 } }}, -{ /* Alpha_JSR (397) - Alpha_INS_JSR - jsr $$26,($$27),0 */ +{ /* Alpha_JSR (397) - Alpha_INS_JSR - jsr $RD,($RS),$DISP */ { + { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* RD */ + { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* RS */ + { CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* DISP */ { 0 } }}, { /* Alpha_JSR_COROUTINE (398) - Alpha_INS_JSR_COROUTINE - jsr_coroutine $RD,($RS),$DISP */ diff --git a/arch/Alpha/AlphaGenDisassemblerTables.inc b/arch/Alpha/AlphaGenDisassemblerTables.inc index 3842ffd358..f807175294 100644 --- a/arch/Alpha/AlphaGenDisassemblerTables.inc +++ b/arch/Alpha/AlphaGenDisassemblerTables.inc @@ -462,17 +462,17 @@ static const uint8_t DecoderTable32[] = { /* 2215 */ MCD_OPC_FilterValue, 26, 101, 0, 0, // Skip to: 2321 /* 2220 */ MCD_OPC_ExtractField, 14, 2, // Inst{15-14} ... /* 2223 */ MCD_OPC_FilterValue, 0, 18, 0, 0, // Skip to: 2246 -/* 2228 */ MCD_OPC_CheckField, 21, 5, 31, 216, 1, 0, // Skip to: 2707 -/* 2235 */ MCD_OPC_CheckField, 0, 14, 0, 209, 1, 0, // Skip to: 2707 -/* 2242 */ MCD_OPC_Decode, 140, 3, 17, // Opcode: JMP +/* 2228 */ MCD_OPC_CheckField, 21, 5, 31, 0, 0, 0, // (no-op: accept any Ra) +/* 2235 */ MCD_OPC_CheckField, 0, 14, 0, 0, 0, 0, // (no-op: accept any hint) +/* 2242 */ MCD_OPC_Decode, 140, 3, 18, // Opcode: JMP (Ra + Rb + hint14) /* 2246 */ MCD_OPC_FilterValue, 1, 37, 0, 0, // Skip to: 2288 /* 2251 */ MCD_OPC_ExtractField, 16, 10, // Inst{25-16} ... /* 2254 */ MCD_OPC_FilterValue, 251, 5, 11, 0, 0, // Skip to: 2271 -/* 2260 */ MCD_OPC_CheckField, 0, 14, 0, 184, 1, 0, // Skip to: 2707 -/* 2267 */ MCD_OPC_Decode, 143, 3, 14, // Opcode: JSRs -/* 2271 */ MCD_OPC_FilterValue, 219, 6, 174, 1, 0, // Skip to: 2707 -/* 2277 */ MCD_OPC_CheckField, 0, 14, 0, 167, 1, 0, // Skip to: 2707 -/* 2284 */ MCD_OPC_Decode, 141, 3, 14, // Opcode: JSR +/* 2260 */ MCD_OPC_CheckField, 0, 14, 0, 0, 0, 0, // (no-op: accept any hint) +/* 2267 */ MCD_OPC_Decode, 141, 3, 18, // Opcode: JSR (Ra + Rb + hint14) +/* 2271 */ MCD_OPC_FilterValue, 219, 6, 7, 0, 0, // Skip to: 2284 (not to 2707) +/* 2277 */ MCD_OPC_CheckField, 0, 14, 0, 0, 0, 0, // (no-op: accept any hint) +/* 2284 */ MCD_OPC_Decode, 141, 3, 18, // Opcode: JSR (Ra + Rb + hint14) /* 2288 */ MCD_OPC_FilterValue, 2, 19, 0, 0, // Skip to: 2312 /* 2293 */ MCD_OPC_CheckField, 16, 10, 250, 7, 150, 1, 0, // Skip to: 2707 /* 2301 */ MCD_OPC_CheckField, 0, 14, 1, 143, 1, 0, // Skip to: 2707 diff --git a/arch/Alpha/AlphaInstPrinter.c b/arch/Alpha/AlphaInstPrinter.c index 1f0d598885..aade8bc9b6 100644 --- a/arch/Alpha/AlphaInstPrinter.c +++ b/arch/Alpha/AlphaInstPrinter.c @@ -96,6 +96,23 @@ void Alpha_LLVM_printInstruction(MCInst *MI, SStream *O, void *Info) printOperand(MI, 0, O); return; } + /* + * JMP/JSR/JSRs now decode with format 18 (Ra + Rb + hint14). + * The generated AsmWriter hardcodes operands for specific canonical + * forms, so print all three operands explicitly here. + */ + if (Opcode == Alpha_JMP || Opcode == Alpha_JSR || Opcode == Alpha_JSRs) { + const char *name = (Opcode == Alpha_JMP) ? "jmp " : "jsr "; + SStream_concat0(O, name); + printOperand(MI, 0, O); + SStream_concat1(O, ','); + SStream_concat1(O, '('); + printOperand(MI, 1, O); + SStream_concat1(O, ')'); + SStream_concat1(O, ','); + printOperand(MI, 2, O); + return; + } if (Opcode == Alpha_BR || Opcode == Alpha_BSR) { SStream_concat0(O, Opcode == Alpha_BR ? "br " : "bsr "); printOperand(MI, 0, O); diff --git a/tests/MC/Alpha/insn-alpha-be.s.yaml b/tests/MC/Alpha/insn-alpha-be.s.yaml index 1e23ab5f3a..f5201ac3c7 100644 --- a/tests/MC/Alpha/insn-alpha-be.s.yaml +++ b/tests/MC/Alpha/insn-alpha-be.s.yaml @@ -988,7 +988,7 @@ test_cases: expected: insns: - - asm_text: "jmp $31,$26,0" + asm_text: "jmp $31,($26),0" - input: bytes: [ 0x6b, 0x5b, 0x40, 0x00 ] diff --git a/tests/MC/Alpha/insn-alpha.s.yaml b/tests/MC/Alpha/insn-alpha.s.yaml index 35831795e4..8ab0bdc401 100644 --- a/tests/MC/Alpha/insn-alpha.s.yaml +++ b/tests/MC/Alpha/insn-alpha.s.yaml @@ -988,7 +988,7 @@ test_cases: expected: insns: - - asm_text: "jmp $31,$26,0" + asm_text: "jmp $31,($26),0" - input: bytes: [ 0x00, 0x40, 0x5b, 0x6b ] @@ -1889,3 +1889,39 @@ test_cases: insns: - asm_text: "call_pal 0x1020b" + - + input: + bytes: [ 0x44, 0x00, 0x00, 0x68 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "jmp $0,($0),0x44" + - + input: + bytes: [ 0x1a, 0x00, 0x40, 0x6b ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "jmp $26,($0),0x1a" + - + input: + bytes: [ 0x00, 0x40, 0x40, 0x6b ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "jsr $26,($0),0" + - + input: + bytes: [ 0x1a, 0x40, 0x40, 0x6b ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "jsr $26,($0),0x1a" From 95e78c381587e91b8026883a92879051b4222925 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Wed, 17 Jun 2026 13:47:44 -0400 Subject: [PATCH 5/7] Alpha: fix TRAPB/EXCB/MB/WMB to decode with any Ra/Rb field 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: https://github.com/capstone-engine/capstone/issues/2795 --- arch/Alpha/AlphaGenDisassemblerTables.inc | 8 ++++---- tests/MC/Alpha/insn-alpha.s.yaml | 9 +++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/arch/Alpha/AlphaGenDisassemblerTables.inc b/arch/Alpha/AlphaGenDisassemblerTables.inc index f807175294..de7e3f4184 100644 --- a/arch/Alpha/AlphaGenDisassemblerTables.inc +++ b/arch/Alpha/AlphaGenDisassemblerTables.inc @@ -430,16 +430,16 @@ static const uint8_t DecoderTable32[] = { /* 2036 */ MCD_OPC_FilterValue, 24, 174, 0, 0, // Skip to: 2215 /* 2041 */ MCD_OPC_ExtractField, 0, 16, // Inst{15-0} ... /* 2044 */ MCD_OPC_FilterValue, 0, 11, 0, 0, // Skip to: 2060 -/* 2049 */ MCD_OPC_CheckField, 16, 10, 0, 139, 2, 0, // Skip to: 2707 +/* 2049 */ MCD_OPC_CheckField, 16, 10, 0, 0, 0, 0, // (no-op: accept any Ra/Rb) /* 2056 */ MCD_OPC_Decode, 241, 3, 14, // Opcode: TRAPB /* 2060 */ MCD_OPC_FilterValue, 128, 8, 11, 0, 0, // Skip to: 2077 -/* 2066 */ MCD_OPC_CheckField, 16, 10, 0, 122, 2, 0, // Skip to: 2707 +/* 2066 */ MCD_OPC_CheckField, 16, 10, 0, 0, 0, 0, // (no-op: accept any Ra/Rb) /* 2073 */ MCD_OPC_Decode, 215, 2, 14, // Opcode: EXCB /* 2077 */ MCD_OPC_FilterValue, 128, 128, 1, 11, 0, 0, // Skip to: 2095 -/* 2084 */ MCD_OPC_CheckField, 16, 10, 0, 104, 2, 0, // Skip to: 2707 +/* 2084 */ MCD_OPC_CheckField, 16, 10, 0, 0, 0, 0, // (no-op: accept any Ra/Rb) /* 2091 */ MCD_OPC_Decode, 166, 3, 14, // Opcode: MB /* 2095 */ MCD_OPC_FilterValue, 128, 136, 1, 11, 0, 0, // Skip to: 2113 -/* 2102 */ MCD_OPC_CheckField, 16, 10, 0, 86, 2, 0, // Skip to: 2707 +/* 2102 */ MCD_OPC_CheckField, 16, 10, 0, 0, 0, 0, // (no-op: accept any Ra/Rb) /* 2109 */ MCD_OPC_Decode, 246, 3, 14, // Opcode: WMB /* 2113 */ MCD_OPC_FilterValue, 128, 128, 2, 4, 0, 0, // Skip to: 2124 /* 2120 */ MCD_OPC_Decode, 248, 2, 15, // Opcode: FETCH diff --git a/tests/MC/Alpha/insn-alpha.s.yaml b/tests/MC/Alpha/insn-alpha.s.yaml index 8ab0bdc401..2cef1b1e77 100644 --- a/tests/MC/Alpha/insn-alpha.s.yaml +++ b/tests/MC/Alpha/insn-alpha.s.yaml @@ -1925,3 +1925,12 @@ test_cases: insns: - asm_text: "jsr $26,($0),0x1a" + - + input: + bytes: [ 0x00, 0x00, 0xff, 0x63 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "trapb" From 03d478898c19b289ac28d3d5735ca8314f4a570b Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Wed, 17 Jun 2026 14:03:03 -0400 Subject: [PATCH 6/7] Alpha: add missing test coverage for s4addq and cvt FP variants s4addq (register and literal forms), cvttq/svc, cvtts/sui, cvtqs/sui, and cvtqt/sui had no MC tests despite being reachable instructions. --- tests/MC/Alpha/insn-alpha.s.yaml | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/MC/Alpha/insn-alpha.s.yaml b/tests/MC/Alpha/insn-alpha.s.yaml index 2cef1b1e77..cea5d993f6 100644 --- a/tests/MC/Alpha/insn-alpha.s.yaml +++ b/tests/MC/Alpha/insn-alpha.s.yaml @@ -1934,3 +1934,57 @@ test_cases: insns: - asm_text: "trapb" + - + input: + bytes: [ 0x43, 0x04, 0x22, 0x40 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "s4addq $1,$2,$3" + - + input: + bytes: [ 0x43, 0xd4, 0x3b, 0x40 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "s4addq $1,0xde,$3" + - + input: + bytes: [ 0xe2, 0xa5, 0xe1, 0x5b ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "cvttq/svc $f1,$f10" + - + input: + bytes: [ 0x82, 0xf5, 0xe1, 0x5b ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "cvtts/sui $f1,$f10" + - + input: + bytes: [ 0x82, 0xf7, 0xe1, 0x5b ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "cvtqs/sui $f1,$f10" + - + input: + bytes: [ 0xc2, 0xf7, 0xe1, 0x5b ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "cvtqt/sui $f1,$f10" From 69b10aee51311467a5fa179c8183bdacc7cfcd32 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Wed, 17 Jun 2026 17:43:01 -0400 Subject: [PATCH 7/7] Alpha: fix RET/RC/RS to decode with any register fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- arch/Alpha/AlphaGenCSMappingInsnOp.inc | 5 ++++- arch/Alpha/AlphaGenDisassemblerTables.inc | 10 ++++----- arch/Alpha/AlphaInstPrinter.c | 7 ++++-- tests/MC/Alpha/insn-alpha-be.s.yaml | 27 +++++++++++++++++++++++ tests/MC/Alpha/insn-alpha.s.yaml | 27 +++++++++++++++++++++++ 5 files changed, 68 insertions(+), 8 deletions(-) diff --git a/arch/Alpha/AlphaGenCSMappingInsnOp.inc b/arch/Alpha/AlphaGenCSMappingInsnOp.inc index ee4a68dbd6..ef3eb4d6b5 100644 --- a/arch/Alpha/AlphaGenCSMappingInsnOp.inc +++ b/arch/Alpha/AlphaGenCSMappingInsnOp.inc @@ -2067,8 +2067,11 @@ { CS_OP_REG, CS_AC_WRITE, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* RA */ { 0 } }}, -{ /* Alpha_RETDAG (446) - Alpha_INS_RET - ret $$31,($$26),1 */ +{ /* Alpha_RETDAG (446) - Alpha_INS_RET - ret $RD,($RS),$DISP */ { + { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* RD */ + { CS_OP_REG, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* RS */ + { CS_OP_IMM, CS_AC_READ, { CS_DATA_TYPE_i64, CS_DATA_TYPE_LAST }, }, /* DISP */ { 0 } }}, { /* Alpha_RETDAGp (447) - Alpha_INS_RET - ret $$31,($$26),1 */ diff --git a/arch/Alpha/AlphaGenDisassemblerTables.inc b/arch/Alpha/AlphaGenDisassemblerTables.inc index de7e3f4184..a35b97490b 100644 --- a/arch/Alpha/AlphaGenDisassemblerTables.inc +++ b/arch/Alpha/AlphaGenDisassemblerTables.inc @@ -448,12 +448,12 @@ static const uint8_t DecoderTable32[] = { /* 2135 */ MCD_OPC_FilterValue, 128, 128, 3, 4, 0, 0, // Skip to: 2146 /* 2142 */ MCD_OPC_Decode, 192, 3, 15, // Opcode: RPCC /* 2146 */ MCD_OPC_FilterValue, 128, 192, 3, 11, 0, 0, // Skip to: 2164 -/* 2153 */ MCD_OPC_CheckField, 16, 5, 0, 35, 2, 0, // Skip to: 2707 +/* 2153 */ MCD_OPC_CheckField, 16, 5, 0, 0, 0, 0, // (no-op: accept any Rb) /* 2160 */ MCD_OPC_Decode, 189, 3, 16, // Opcode: RC /* 2164 */ MCD_OPC_FilterValue, 128, 208, 3, 4, 0, 0, // Skip to: 2175 /* 2171 */ MCD_OPC_Decode, 212, 2, 15, // Opcode: ECB /* 2175 */ MCD_OPC_FilterValue, 128, 224, 3, 11, 0, 0, // Skip to: 2193 -/* 2182 */ MCD_OPC_CheckField, 16, 5, 0, 6, 2, 0, // Skip to: 2707 +/* 2182 */ MCD_OPC_CheckField, 16, 5, 0, 0, 0, 0, // (no-op: accept any Rb) /* 2189 */ MCD_OPC_Decode, 193, 3, 16, // Opcode: RS /* 2193 */ MCD_OPC_FilterValue, 128, 240, 3, 4, 0, 0, // Skip to: 2204 /* 2200 */ MCD_OPC_Decode, 244, 3, 15, // Opcode: WH64 @@ -474,9 +474,9 @@ static const uint8_t DecoderTable32[] = { /* 2277 */ MCD_OPC_CheckField, 0, 14, 0, 0, 0, 0, // (no-op: accept any hint) /* 2284 */ MCD_OPC_Decode, 141, 3, 18, // Opcode: JSR (Ra + Rb + hint14) /* 2288 */ MCD_OPC_FilterValue, 2, 19, 0, 0, // Skip to: 2312 -/* 2293 */ MCD_OPC_CheckField, 16, 10, 250, 7, 150, 1, 0, // Skip to: 2707 -/* 2301 */ MCD_OPC_CheckField, 0, 14, 1, 143, 1, 0, // Skip to: 2707 -/* 2308 */ MCD_OPC_Decode, 190, 3, 14, // Opcode: RETDAG +/* 2293 */ MCD_OPC_CheckField, 16, 10, 250, 7, 0, 0, 0, // (no-op: accept any Ra/Rb) +/* 2301 */ MCD_OPC_CheckField, 0, 14, 1, 0, 0, 0, // (no-op: accept any hint) +/* 2308 */ MCD_OPC_Decode, 190, 3, 18, // Opcode: RETDAG (Ra + Rb + hint14) /* 2312 */ MCD_OPC_FilterValue, 3, 134, 1, 0, // Skip to: 2707 /* 2317 */ MCD_OPC_Decode, 142, 3, 18, // Opcode: JSR_COROUTINE /* 2321 */ MCD_OPC_FilterValue, 28, 115, 0, 0, // Skip to: 2441 diff --git a/arch/Alpha/AlphaInstPrinter.c b/arch/Alpha/AlphaInstPrinter.c index aade8bc9b6..d8f73ba203 100644 --- a/arch/Alpha/AlphaInstPrinter.c +++ b/arch/Alpha/AlphaInstPrinter.c @@ -101,8 +101,11 @@ void Alpha_LLVM_printInstruction(MCInst *MI, SStream *O, void *Info) * The generated AsmWriter hardcodes operands for specific canonical * forms, so print all three operands explicitly here. */ - if (Opcode == Alpha_JMP || Opcode == Alpha_JSR || Opcode == Alpha_JSRs) { - const char *name = (Opcode == Alpha_JMP) ? "jmp " : "jsr "; + if (Opcode == Alpha_JMP || Opcode == Alpha_JSR || + Opcode == Alpha_JSRs || Opcode == Alpha_RETDAG) { + const char *name = (Opcode == Alpha_JMP) ? "jmp " : + (Opcode == Alpha_RETDAG) ? "ret " : + "jsr "; SStream_concat0(O, name); printOperand(MI, 0, O); SStream_concat1(O, ','); diff --git a/tests/MC/Alpha/insn-alpha-be.s.yaml b/tests/MC/Alpha/insn-alpha-be.s.yaml index f5201ac3c7..44a43f4717 100644 --- a/tests/MC/Alpha/insn-alpha-be.s.yaml +++ b/tests/MC/Alpha/insn-alpha-be.s.yaml @@ -1781,3 +1781,30 @@ test_cases: insns: - asm_text: "zapnot $1,0xde,$3" + - + input: + bytes: [ 0x68, 0x01, 0x80, 0x03 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_BIG_ENDIAN" ] + expected: + insns: + - + asm_text: "ret $0,($1),3" + - + input: + bytes: [ 0x60, 0x3F, 0xE0, 0x00 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_BIG_ENDIAN" ] + expected: + insns: + - + asm_text: "rc $1" + - + input: + bytes: [ 0x60, 0x3F, 0xF0, 0x00 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_BIG_ENDIAN" ] + expected: + insns: + - + asm_text: "rs $1" diff --git a/tests/MC/Alpha/insn-alpha.s.yaml b/tests/MC/Alpha/insn-alpha.s.yaml index cea5d993f6..7b699a91db 100644 --- a/tests/MC/Alpha/insn-alpha.s.yaml +++ b/tests/MC/Alpha/insn-alpha.s.yaml @@ -1988,3 +1988,30 @@ test_cases: insns: - asm_text: "cvtqt/sui $f1,$f10" + - + input: + bytes: [ 0x03, 0x80, 0x01, 0x68 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "ret $0,($1),3" + - + input: + bytes: [ 0x00, 0xE0, 0x3F, 0x60 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "rc $1" + - + input: + bytes: [ 0x00, 0xF0, 0x3F, 0x60 ] + arch: "CS_ARCH_ALPHA" + options: [ "CS_MODE_LITTLE_ENDIAN" ] + expected: + insns: + - + asm_text: "rs $1"