fix(asm): emit nothing for the arm64 NOP pseudo-instruction

Assisted-by: GLM 5.3
This commit is contained in:
petrbalvin committed 2026-10-07 13:49:49 +02:00
1 parent 405e2427ed
commit 7bc80ccb54
2 files changed
+66 -4

No files matched your search

+30 -1
View File
@@ -287,6 +287,9 @@ func arm64InstrSize(instr *ast.Instr, fi arm64FrameInfo, pos int) int {
if mnem == "BYTE" {
return len(ops)
}
if mnem == "NOP" {
return 0 // the zero-size pseudo-instruction, operand or not
}
switch mnem {
case "VMOVS", "VMOVD", "VMOVQ":
// ADRP + ADD + wide load against a pooled literal.
@@ -414,7 +417,33 @@ func encodeARM64Instr(instr *ast.Instr, pc int, offsets map[string]int, fi arm64
switch mnem {
case "RET":
return arm64RetInstr(fi, ops, relocs), nil
case "NOP", "NOOP":
case "NOP":
// The toolchain's ANOP is a zero-size pseudo-instruction: no bytes
// whatever operand rides it, the immediate, register and vector
// classes included (asm7.go's ANOP rows), and anything else is an
// illegal combination. A bare register operand parses as a symbol
// reference with no base, the way operandRegName reads it.
if len(ops) > 1 {
return nil, fmt.Errorf("NOP: illegal combination")
}
if len(ops) == 1 && !isImmOperand(ops[0]) {
op := ops[0]
name := operandRegName(op)
bare := op.Addr.Base == "" && op.Addr.Sym != nil && op.Addr.Sym.Pseudo == "" &&
!op.Addr.HasOff && op.Addr.Index == ""
reg := arm64RegNum(name) >= 0 ||
len(name) > 1 && (name[0] == 'F' || name[0] == 'V') && strings.Trim(name[1:], "0123456789") == ""
if !bare || !reg {
return nil, fmt.Errorf("NOP: illegal combination")
}
}
return nil, nil
case "NOOP":
// NOOP is the real hint instruction: one word, and it takes no
// operand at all.
if len(ops) != 0 {
return nil, fmt.Errorf("NOOP: illegal combination")
}
return a64wordLE(a64NOP), nil
case "UNDEF":
return a64wordLE(a64BRK(0)), nil