fix(asm): encode the riscv64 FENCE predecessor and successor flags
Assisted-by: GLM 5.3
This commit is contained in:
1 parent
36d1ac804a
commit
e5aabf9801
1 file changed
+33
@@ -352,6 +352,26 @@ func riscvPadBytes(pad int) []byte {
|
||||
return out
|
||||
}
|
||||
|
||||
// riscvFenceFlags carries the toolchain's sixteen FENCE flag spellings (its
|
||||
// specialOperands table between SPOP_FENCE_BEGIN and SPOP_FENCE_END), each
|
||||
// with the 4-bit encoding the predecessor and successor fields pack.
|
||||
var riscvFenceFlags = map[string]uint32{
|
||||
"W": 1, "R": 2, "RW": 3, "O": 4, "OW": 5, "OR": 6, "ORW": 7,
|
||||
"I": 8, "IW": 9, "IR": 10, "IRW": 11, "IO": 12, "IOW": 13,
|
||||
"IOR": 14, "IORW": 15,
|
||||
}
|
||||
|
||||
// riscvFenceFlag resolves one FENCE flag operand (a bare name such as W or
|
||||
// IORW) to its 4-bit encoding.
|
||||
func riscvFenceFlag(op *ast.Operand) (uint32, bool) {
|
||||
name := ""
|
||||
if op.Addr.Sym != nil {
|
||||
name = op.Addr.Sym.Name
|
||||
}
|
||||
v, ok := riscvFenceFlags[strings.ToUpper(name)]
|
||||
return v, ok
|
||||
}
|
||||
|
||||
// riscvInstrSize returns the encoded size in bytes of a RISC-V instruction.
|
||||
// Most instructions are 4 bytes; MOV with a large immediate and I-type
|
||||
// arithmetic with a large immediate expand to several (possibly compressed)
|
||||
@@ -1322,6 +1342,19 @@ func encodeRISCVInstr(instr *ast.Instr, pc int, offsets map[string]int, fi riscv
|
||||
if mnem == "PAUSE" {
|
||||
imm = 0x010
|
||||
}
|
||||
// FENCE pred, succ spells both flags with the toolchain's sixteen
|
||||
// IORW combinations, packed as pred<<4 | succ in the immediate.
|
||||
if mnem == "FENCE" && len(ops) == 2 {
|
||||
pred, ok := riscvFenceFlag(ops[0])
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("FENCE: invalid predecessor operand %q", ops[0].Raw)
|
||||
}
|
||||
succ, ok := riscvFenceFlag(ops[1])
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("FENCE: invalid successor operand %q", ops[1].Raw)
|
||||
}
|
||||
imm = int32(pred)<<4 | int32(succ)
|
||||
}
|
||||
word = riscvIType(enc, 0, 0, imm)
|
||||
return []byte{byte(word), byte(word >> 8), byte(word >> 16), byte(word >> 24)}, nil
|
||||
|
||||
|
||||
Reference in new issue
Block a user