fix(asm): lower the riscv64 immediate CSR pseudos onto their opcode forms

Assisted-by: GLM 5.3
This commit is contained in:
petrbalvin committed 2026-10-07 13:51:02 +02:00
1 parent e5aabf9801
commit f8dbd4f017
1 file changed
+26
+26
View File
@@ -1532,6 +1532,21 @@ func encodeRISCVInstr(instr *ast.Instr, pc int, offsets map[string]int, fi riscv
csrOp, srcOp = ops[1], ops[0]
}
rdOp = nil
// The toolchain picks the opcode form from the source's kind:
// CSRW $2, csr assembles as CSRRWI exactly as CSRWI does, and
// the register spellings stay on CSRRW.
if isImmOperand(srcOp) {
csrMnem = map[string]string{
"CSRS": "CSRRSI", "CSRW": "CSRRWI", "CSRC": "CSRRCI",
"CSRSI": "CSRRSI", "CSRWI": "CSRRWI", "CSRCI": "CSRRCI",
}[mnem]
} else {
csrMnem = map[string]string{
"CSRS": "CSRRS", "CSRW": "CSRRW", "CSRC": "CSRRC",
"CSRSI": "CSRRSI", "CSRWI": "CSRRWI", "CSRCI": "CSRRCI",
}[mnem]
}
csrEnc = riscvCsrTable[csrMnem]
default:
// Either src, csr, rd or csr, src, rd: a CSR *name* in the
// second operand marks the toolchain's order.
@@ -1541,6 +1556,17 @@ func encodeRISCVInstr(instr *ast.Instr, pc int, offsets map[string]int, fi riscv
csrOp, srcOp = ops[1], ops[0]
}
}
// An immediate source selects the immediate opcode (CSRRW $2,
// c, rd encodes CSRRWI, byte-identical to the explicit form),
// mirroring the toolchain's constant rewrite.
if isImmOperand(srcOp) {
csrMnem = map[string]string{
"CSRRW": "CSRRWI", "CSRRS": "CSRRSI", "CSRRC": "CSRRCI",
}[csrMnem]
if csrMnem != "" {
csrEnc = riscvCsrTable[csrMnem]
}
}
}
csr, ok := riscvCSRAddress(csrOp)
if !ok && csrFix == 0 {