fix(asm): validate the loong64 ll/sc offset span like the toolchain

Assisted-by: GLM 5.3 Flash
This commit is contained in:
petrbalvin committed 2026-10-06 23:59:27 +02:00
1 parent 6cc6165c2b
commit 1040739fbb
3 files changed
+138 -1

No files matched your search

+14 -1
View File
@@ -387,6 +387,16 @@ func loong64InstrSize(instr *ast.Instr, fi loong64FrameInfo) int {
return 8 // bne/beq over the BREAK, then BREAK
case "PRELDX":
return 20 // the four-instruction constant materialisation + preldx
case "LL", "LLW", "LLV", "SC", "SCW", "SCV", "MOVWP", "MOVVP":
// The 2RI14 families: one word inside the signed 16-bit offset
// span, otherwise the toolchain's materialisation sequences (see
// l64firr14Words, which decides the width). A memory operand that
// will not parse leaves the single-word size: the encode pass
// reports the error.
if _, _, off, _, err := l64MemOperands(ops, fi); err == nil {
return len(l64firr14Words(0, int(off), 0, 0))
}
return 4
case "MOV", "MOVB", "MOVH", "MOVW", "MOVV", "MOVBU", "MOVHU", "MOVWU", "MOVF", "MOVD":
return loong64MovSize(mnem, ops, fi)
case "ADD", "ADDW", "ADDV", "ADDVU", "AND", "OR", "XOR", "SGT", "SGTU":
@@ -797,7 +807,10 @@ func encodeLOONG64Instr(instr *ast.Instr, pc int, offsets map[string]int, fi loo
// ldptr.{w,d} = stptr.{w,d} minus the LSB of the opcode field.
op -= 1 << 24
}
return l64wordLE(l64irr14(op, int(off)>>2, rj, rd)), nil
if off&3 != 0 {
return nil, fmt.Errorf("%s: offset must be a multiple of 4", mnem)
}
return l64firr14Words(op, int(off), rj, rd), nil
case l64Fir20:
// LU12IW/LU32ID/PCALAU12I/PCADDU12I: INSTR rd, $imm.