From 9d50212a71b2ea395fa7af4047845aff3551632b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Balv=C3=ADn?= Date: Wed, 7 Oct 2026 13:21:35 +0200 Subject: [PATCH] fix(asm): refuse the riscv64 width moves across register banks Assisted-by: GLM 5.3 --- asm/riscv_assemble.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/asm/riscv_assemble.go b/asm/riscv_assemble.go index 3b01b54..25036ca 100644 --- a/asm/riscv_assemble.go +++ b/asm/riscv_assemble.go @@ -2095,17 +2095,29 @@ func encodeRISCVMov(instr *ast.Instr, fi riscvFrameInfo, relocs *[]Reloc, lits * // ADDIW $0, rs, rd; the two-operand-only form never has // rd == rs1 in real sources, and the toolchain's C.ADDIW // forbids a zero immediate, so the word stays uncompressed. + if srcF || dstF { + return nil, fmt.Errorf("%s: expected integer register in rd position", mnem) + } return wordLE(riscvIType(riscvEnc{0x1B, 0x0, 0x00}, rd, rs1, 0)), nil case "MOVBU": // ANDI $255, rs, rd; 255 never fits C.ANDI's six signed bits. + if srcF || dstF { + return nil, fmt.Errorf("%s: expected integer register in rd position", mnem) + } return wordLE(riscvIType(riscvEnc{0x13, 0x7, 0x00}, rd, rs1, 0xFF)), nil case "MOVB", "MOVH": + if srcF || dstF { + return nil, fmt.Errorf("%s: expected integer register in rd position", mnem) + } shamt := 56 if mnem == "MOVH" { shamt = 48 } return riscvExtendBytes(rd, rs1, shamt, true), nil case "MOVHU", "MOVWU": + if srcF || dstF { + return nil, fmt.Errorf("%s: expected integer register in rd position", mnem) + } shamt := 48 if mnem == "MOVWU" { shamt = 32