127 lines
3.7 KiB
Go
127 lines
3.7 KiB
Go
// Copyright (c) 2026 Petr Balvín <opensource@petrbalvin.org> (https://petrbalvin.org)
|
|
// SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
package main
|
|
|
|
import (
|
|
"runtime"
|
|
"testing"
|
|
|
|
"sourcedock.dev/petrbalvin/gasm-sdk/arch"
|
|
)
|
|
|
|
func TestDerivedFamily(t *testing.T) {
|
|
for _, n := range []string{"JEQ", "JLT", "JCC", "CMOVLGT", "SETNE", "SETA"} {
|
|
if !derivedFamily(n) {
|
|
t.Errorf("derivedFamily(%q) = false, want true", n)
|
|
}
|
|
}
|
|
for _, n := range []string{"JMP", "ADDQ", "VPGATHERDD", "MOVBE", "PSHUFB"} {
|
|
if derivedFamily(n) {
|
|
t.Errorf("derivedFamily(%q) = true, want false", n)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSanitize(t *testing.T) {
|
|
if got := sanitize("VPCMP.UB"); got != "VPCMP_UB" {
|
|
t.Errorf("sanitize: got %q", got)
|
|
}
|
|
}
|
|
|
|
func TestAuditArch(t *testing.T) {
|
|
for in, want := range map[string]arch.Arch{
|
|
"amd64": arch.AMD64, "arm64": arch.ARM64,
|
|
"riscv64": arch.RISCV, "riscv": arch.RISCV,
|
|
"loong64": arch.LOONG64, "LOONG": arch.LOONG64,
|
|
} {
|
|
got, err := auditArch(in)
|
|
if err != nil || got != want {
|
|
t.Errorf("auditArch(%q) = %v, %v; want %v", in, got, err, want)
|
|
}
|
|
}
|
|
if _, err := auditArch("mips"); err == nil {
|
|
t.Error("auditArch(mips) must fail")
|
|
}
|
|
}
|
|
|
|
func TestGasmEncodable(t *testing.T) {
|
|
cases := []struct {
|
|
a arch.Arch
|
|
yes string
|
|
no string
|
|
}{
|
|
{arch.AMD64, "ADDQ", "NOSUCHMNEMONIC"},
|
|
{arch.ARM64, "ADD", "NOSUCHMNEMONIC"},
|
|
{arch.RISCV, "ADD", "NOSUCHMNEMONIC"},
|
|
{arch.LOONG64, "ADDV", "NOSUCHMNEMONIC"},
|
|
}
|
|
for _, c := range cases {
|
|
if !gasmEncodable(c.a, c.yes) {
|
|
t.Errorf("%s: %s should be encodable", c.a, c.yes)
|
|
}
|
|
if gasmEncodable(c.a, c.no) {
|
|
t.Errorf("%s: %s should not be encodable", c.a, c.no)
|
|
}
|
|
}
|
|
}
|
|
|
|
// TestBuildConstraint pins the //go:build reader: the constraint governs the
|
|
// leading comment block, the first non-comment line ends it (a tag below a
|
|
// #include governs nothing, exactly as go/build drops it), and a file
|
|
// without one admits every target.
|
|
func TestBuildConstraint(t *testing.T) {
|
|
admits := func(src, goarch, goos string) bool {
|
|
t.Helper()
|
|
e := buildConstraint(src)
|
|
if e == nil {
|
|
return true
|
|
}
|
|
return e.Eval(constraintTags(goarch, goos))
|
|
}
|
|
const ret = "TEXT \xc2\xb7f(SB), NOSPLIT, $0\n\tRET\n"
|
|
cases := []struct {
|
|
name string
|
|
src string
|
|
amd64, arm64 bool
|
|
}{
|
|
{"no constraint", ret, true, true},
|
|
{"x86 only", "//go:build 386 || amd64\n\n" + ret, true, false},
|
|
{"arm64 and linux", "//go:build arm64 && linux\n\n" + ret, false, true},
|
|
{"msan never", "//go:build msan\n\n" + ret, false, false},
|
|
{"experiment never", "//go:build goexperiment.runtimesecret\n\n" + ret, false, false},
|
|
{"below an include governs nothing", "#include \"textflag.h\"\n//go:build amd64\n" + ret, true, true},
|
|
{"unparsable narrows nothing", "//go:build (amd64\n" + ret, true, true},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.name, func(t *testing.T) {
|
|
if got := admits(c.src, "amd64", runtime.GOOS); got != c.amd64 {
|
|
t.Errorf("amd64 admission = %v, want %v", got, c.amd64)
|
|
}
|
|
if got := admits(c.src, "arm64", runtime.GOOS); got != c.arm64 {
|
|
t.Errorf("arm64 admission = %v, want %v", got, c.arm64)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestConstraintTags pins the tag set a plain `go build` sets: the GOOS and
|
|
// GOARCH, gc, unix on the unix-like GOOSes; nothing else is ever true.
|
|
func TestConstraintTags(t *testing.T) {
|
|
ok := constraintTags("amd64", "linux")
|
|
for _, tag := range []string{"amd64", "linux", "gc", "unix"} {
|
|
if !ok(tag) {
|
|
t.Errorf("tag %q = false, want true", tag)
|
|
}
|
|
}
|
|
for _, tag := range []string{"arm64", "freebsd", "darwin", "cgo", "race", "msan", "goexperiment.runtimesecret"} {
|
|
if ok(tag) {
|
|
t.Errorf("tag %q = true, want false", tag)
|
|
}
|
|
}
|
|
fb := constraintTags("arm64", "freebsd")
|
|
if !fb("unix") {
|
|
t.Error("unix on freebsd = false, want true")
|
|
}
|
|
}
|