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

+36 -3
View File
@@ -568,10 +568,11 @@ func TestArm64CondCompare(t *testing.T) {
// TestArm64CompareBranch pins CBZ/CBNZ/TBZ/TBNZ against a label five and
// six words ahead, matching go tool asm's own offsets.
func TestArm64CompareBranch(t *testing.T) {
// Layout: CBZ(0) TBZ(4) TBNZ(8) CBNZ(12) NOP(16) NOP(17th word...) done.
// Layout: CBZ(0) TBZ(4) TBNZ(8) CBNZ(12) NOOP(16) NOOP(17th word...) done.
// The fillers are NOOP, not NOP: the toolchain's NOP emits nothing.
src := "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n" +
"\tCBZ R1, done\n\tTBZ $4, R7, done\n\tTBNZ $33, R7, done\n\tCBNZW R2, done\n" +
"\tNOP\n\tNOP\n\tdone:\tNOP\n\tRET\n"
"\tNOOP\n\tNOOP\n\tdone:\tNOOP\n\tRET\n"
f, errs := parser.Parse("test_arm64.s", src)
if len(errs) > 0 {
t.Fatalf("parse: %v", errs)
@@ -604,7 +605,7 @@ func TestArm64CompareBranch(t *testing.T) {
// TestArm64ADR pins ADR against a forward label.
func TestArm64ADR(t *testing.T) {
src := "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n" +
"\tADR done, R10\n\tNOP\n\tNOP\n\tdone:\tNOP\n\tRET\n"
"\tADR done, R10\n\tNOOP\n\tNOOP\n\tdone:\tNOOP\n\tRET\n"
f, errs := parser.Parse("test_arm64.s", src)
if len(errs) > 0 {
t.Fatalf("parse: %v", errs)
@@ -2234,6 +2235,38 @@ func TestArm64LiteralPoolGuard(t *testing.T) {
}
}
// TestArm64NoopVsNop pins the two spellings apart, the way the toolchain
// holds them: NOOP is the real hint instruction and NOP a zero-size pseudo
// whose operand, when it is an immediate or a register, rides along for go
// vet's benefit; every other operand shape and the NOOP operands are illegal
// combinations.
func TestArm64NoopVsNop(t *testing.T) {
got := arm64Words(t, "\tNOP\n\tNOOP\n\tNOP\tR0\n")
want := []uint32{0xd503201f, 0xd65f03c0}
if len(got) != len(want) {
t.Fatalf("word count = %d, want %d", len(got), len(want))
}
for i := range want {
if got[i] != want[i] {
t.Errorf("word %d = %08x, want %08x", i, got[i], want[i])
}
}
for _, src := range []string{
"\tNOOP\t$0\n",
"\tNOOP\tR0\n",
"\tNOP\t8(R0)\n",
"\tNOP\t$0, $1\n",
} {
f, errs := parser.Parse("test_arm64.s", "#include \"textflag.h\"\n\nTEXT ·f(SB), NOSPLIT, $0-0\n"+src+"\tRET\n")
if len(errs) > 0 {
continue // a parse rejection is a rejection
}
if _, err := AssembleFileARM64(f); err == nil {
t.Errorf("expected rejection for %q, got nil", strings.TrimSpace(src))
}
}
}
// TestArm64FPImmediate pins the FP immediate moves against `go tool asm`
// words: the FMOV (immediate) instruction for the 8-bit encodable values and
// the FMOV-from-ZR move for zero, plus the rejections the toolchain raises