53 lines
1.6 KiB
Go
53 lines
1.6 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package lint
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"sourcedock.dev/petrbalvin/gasm-sdk/arch"
|
|
"sourcedock.dev/petrbalvin/gasm-sdk/asm"
|
|
)
|
|
|
|
// TestExtensionInstructionsAreKnown pins the lint side of the
|
|
// extended-instruction layer: every mnemonic the arm64 registry carries
|
|
// lints without unknown-instruction, and a kernel the encoder accepts lints
|
|
// clean, because the wired layer is the acceptance rather than a gap of the
|
|
// generated table.
|
|
func TestExtensionInstructionsAreKnown(t *testing.T) {
|
|
src := `#include "textflag.h"
|
|
TEXT ·f(SB), NOSPLIT, $0
|
|
ADD Z1.S, Z2.S, Z0.S
|
|
SUBR Z1.S, P0/M, Z0.S
|
|
SQADD Z0.D, Z1.D, Z2.D
|
|
UQADD Z0.D, Z1.D, Z2.D
|
|
SQSUB Z0.D, Z1.D, Z2.D
|
|
UQSUB Z0.D, Z1.D, Z2.D
|
|
SMULH Z3.D, Z4.D, Z5.D
|
|
ADD $255, Z0.S
|
|
MUL $-128, Z0.B
|
|
RET
|
|
`
|
|
diags := lintArchFile(t, "ext_arm64.s", src, arch.ARM64, asm.AssembleFileARM64)
|
|
for _, code := range []string{CodeUnknownInstr, CodeUnencodable} {
|
|
if n := codes(diags)[code]; n != 0 {
|
|
t.Errorf("%s fired %d times on the wired extension: %+v", code, n, diags)
|
|
}
|
|
}
|
|
if len(diags) != 0 {
|
|
t.Errorf("a kernel the encoder accepts must lint clean, got %+v", diags)
|
|
}
|
|
|
|
// The registry consult is the layer's own, not a loosening of the rule:
|
|
// a mnemonic neither table nor registry carries still fires.
|
|
diags = lintSrcArch(t, "ext_arm64.s", `#include "textflag.h"
|
|
TEXT ·f(SB), NOSPLIT, $0
|
|
FROBNICATE Z0.S, Z1.S, Z2.S
|
|
RET
|
|
`)
|
|
if codes(diags)[CodeUnknownInstr] != 1 {
|
|
t.Errorf("an unregistered mnemonic must fire unknown-instruction once: %+v", diags)
|
|
}
|
|
}
|