63 lines
1.8 KiB
Go
63 lines
1.8 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-devkit/asm"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestUnencodableInstruction(t *testing.T) {
|
||
|
|
// MOVBE is a real x86 instruction the architecture table knows about;
|
||
|
|
// before the encoder grows it, lint must flag the gap at edit time.
|
||
|
|
diags := lintSrc(t, `
|
||
|
|
#include "textflag.h"
|
||
|
|
TEXT ·f(SB), NOSPLIT, $0
|
||
|
|
MOVQ AX, BX
|
||
|
|
RET
|
||
|
|
`)
|
||
|
|
if codes(diags)[CodeUnencodable] != 0 {
|
||
|
|
t.Fatalf("encodable instructions must not be flagged: %+v", diags)
|
||
|
|
}
|
||
|
|
|
||
|
|
// A mnemonic that is neither in the table nor encodable fires
|
||
|
|
// unknown-instruction, not unencodable.
|
||
|
|
diags = lintSrc(t, `
|
||
|
|
#include "textflag.h"
|
||
|
|
TEXT ·f(SB), NOSPLIT, $0
|
||
|
|
FROBNICATE AX, BX
|
||
|
|
RET
|
||
|
|
`)
|
||
|
|
if codes(diags)[CodeUnencodable] != 0 || codes(diags)[CodeUnknownInstr] != 1 {
|
||
|
|
t.Fatalf("unknown instruction must fire unknown-instruction only: %+v", diags)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestEncodableMirror(t *testing.T) {
|
||
|
|
// Spot-check the predicate against instructions from every dispatch
|
||
|
|
// family of the encoder.
|
||
|
|
yes := []string{
|
||
|
|
"RET", "NOP", "CALL", "JMP", "JEQ", "JLT",
|
||
|
|
"MOVQ", "MOVL", "ADDQ", "CMPQ", "LEAQ", "TESTL",
|
||
|
|
"NOTL", "DECL", "SHRQ", "IMULQ", "PUSHQ", "POPQ",
|
||
|
|
"BSWAPL", "TZCNTQ", "MOVBLZX", "MOVOU", "MOVSD",
|
||
|
|
"PREFETCHT0", "PREFETCHNTA",
|
||
|
|
"VMOVDQU", "VPCMPUB", "VPCOMPRESSD", "VPERMB", "VPGATHERDD", "VPSCATTERDD",
|
||
|
|
"KMOVQ", "KANDNW", "VPMOVMSKB",
|
||
|
|
"CMOVLGT", "SETNE", "PSHUFB", "PADDB",
|
||
|
|
}
|
||
|
|
for _, m := range yes {
|
||
|
|
if !asm.Encodable(m) {
|
||
|
|
t.Errorf("Encodable(%q) = false, want true", m)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
no := []string{"FROBNICATE", "MOVXX", "CMOVXX", "SETXX"}
|
||
|
|
for _, m := range no {
|
||
|
|
if asm.Encodable(m) {
|
||
|
|
t.Errorf("Encodable(%q) = true, want false", m)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|