fix(asm): lower the riscv64 immediate CSR pseudos onto their opcode forms
Assisted-by: GLM 5.3
This commit is contained in:
1 parent
e5aabf9801
commit
f8dbd4f017
1 file changed
+26
@@ -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 {
|
||||
|
||||
Reference in new issue
Block a user