// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: BSD-3-Clause // The lint side of the extended-instruction layer. The generated tables and // the extension registry are two homes for a mnemonic, so a registered // mnemonic is known wherever the tables are consulted, and a statement pinned // to the registry is validated by the registry's own encoding, whose refusal // is the sharper diagnostic the layer carries. package lint import ( "sourcedock.dev/petrbalvin/gasm-sdk/arch" "sourcedock.dev/petrbalvin/gasm-sdk/asm" "sourcedock.dev/petrbalvin/gasm-sdk/ast" ) // amd64ExtPinned reports whether a statement belongs to the amd64 extension // layer alone: the mnemonic is registered in the registry and the encoder // mirror cannot encode it, the same routing the assembler applies before its // scalar paths run. A statement the layer pins never passes through go tool // asm, so the per-operand portability advice the scalar statements earn is // noise on it. func amd64ExtPinned(upper string) bool { if _, ok := asm.LookupExtension(arch.AMD64, upper); !ok { return false } return !asm.Encodable(upper) } // checkAmd64Extension validates one amd64 statement pinned to the extension // layer by encoding it through the registry: the layer's own validators carry // the sharper diagnostic (a mask on a scalar form, rounding on a VL form, k0 // as a write mask), and their refusal is the diagnostic, the same text the // assembler prints at build time. A statement the registry encodes is clean: // the wired layer is the acceptance, not a gap of the generated table. func checkAmd64Extension(st *ast.Instr, upper string) []Diagnostic { _, _, err := asm.EncodeAmd64Statement(upper, st.Operands) if err == nil { return nil } return []Diagnostic{{ Pos: st.Mnemonic.Pos, End: st.Mnemonic.End, Severity: Error, Code: CodeExtensionForm, Message: err.Error(), }} }