diff --git a/stdlib_arm64_test_helpers_test.go b/stdlib_arm64_test_helpers_test.go new file mode 100644 index 0000000..c7d8b5a --- /dev/null +++ b/stdlib_arm64_test_helpers_test.go @@ -0,0 +1,53 @@ +//go:build !llgo +// +build !llgo + +package plan9asm + +import ( + "os" + "os/exec" + "path/filepath" + "strings" + "testing" +) + +const arm64LinuxGNUTriple = "aarch64-unknown-linux-gnu" + +func testGOROOT(t *testing.T) string { + t.Helper() + if goroot := os.Getenv("GOROOT"); goroot != "" { + return goroot + } + goroot, err := testGoEnv("GOROOT") + if err != nil || goroot == "" { + t.Skip("GOROOT not available") + } + return goroot +} + +func testGoEnv(key string) (string, error) { + out, err := exec.Command("go", "env", key).CombinedOutput() + if err != nil { + return "", err + } + return strings.TrimSpace(string(out)), nil +} + +func compileLLVMToObject(t *testing.T, llc, triple, llName, objName, ll string) { + t.Helper() + tmp := t.TempDir() + llPath := filepath.Join(tmp, llName) + objPath := filepath.Join(tmp, objName) + if err := os.WriteFile(llPath, []byte(ll), 0644); err != nil { + t.Fatal(err) + } + cmd := exec.Command(llc, "-mtriple="+triple, "-filetype=obj", llPath, "-o", objPath) + out, err := cmd.CombinedOutput() + if err != nil { + s := string(out) + if llcUnsupportedTarget(s) { + t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s)) + } + t.Fatalf("llc failed: %v\n%s", err, s) + } +} diff --git a/stdlib_cpu_arm64_test.go b/stdlib_cpu_arm64_test.go index 0cc199f..de1c28a 100644 --- a/stdlib_cpu_arm64_test.go +++ b/stdlib_cpu_arm64_test.go @@ -5,25 +5,23 @@ package plan9asm import ( "os" - "os/exec" "path/filepath" - "runtime" "strings" "testing" ) func TestStdlibInternalCPU_ARM64_Compile(t *testing.T) { - if runtime.GOARCH != "arm64" { - t.Skip("host is not arm64") - } llc, _, ok := findLlcAndClang(t) if !ok { t.Skip("llc not found") } - goroot := runtime.GOROOT() + goroot := testGOROOT(t) src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "cpu", "cpu_arm64.s")) if err != nil { + if os.IsNotExist(err) { + t.Skip("internal/cpu/cpu_arm64.s not present in this GOROOT") + } t.Fatal(err) } @@ -55,23 +53,14 @@ func TestStdlibInternalCPU_ARM64_Compile(t *testing.T) { }, } ll, err := Translate(file, Options{ - TargetTriple: testTargetTriple(runtime.GOOS, runtime.GOARCH), + TargetTriple: arm64LinuxGNUTriple, ResolveSym: resolve, Sigs: sigs, + Goarch: "arm64", }) if err != nil { t.Fatal(err) } - tmp := t.TempDir() - llPath := filepath.Join(tmp, "cpu.ll") - objPath := filepath.Join(tmp, "cpu.o") - if err := os.WriteFile(llPath, []byte(ll), 0644); err != nil { - t.Fatal(err) - } - cmd := exec.Command(llc, "-filetype=obj", llPath, "-o", objPath) - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf("llc failed: %v\n%s", err, string(out)) - } + compileLLVMToObject(t, llc, arm64LinuxGNUTriple, "cpu.ll", "cpu.o", ll) } diff --git a/stdlib_runtime_sys_arm64_test.go b/stdlib_runtime_sys_arm64_test.go index 6335023..d6f2c37 100644 --- a/stdlib_runtime_sys_arm64_test.go +++ b/stdlib_runtime_sys_arm64_test.go @@ -5,23 +5,18 @@ package plan9asm import ( "os" - "os/exec" "path/filepath" - "runtime" "strings" "testing" ) func TestStdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { - if runtime.GOARCH != "arm64" { - t.Skip("host is not arm64") - } llc, _, ok := findLlcAndClang(t) if !ok { t.Skip("llc not found") } - goroot := runtime.GOROOT() + goroot := testGOROOT(t) src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "runtime", "sys", "dit_arm64.s")) if err != nil { if os.IsNotExist(err) { @@ -61,24 +56,49 @@ func TestStdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { }, } ll, err := Translate(file, Options{ - TargetTriple: testTargetTriple(runtime.GOOS, runtime.GOARCH), + TargetTriple: arm64LinuxGNUTriple, ResolveSym: resolve, Sigs: sigs, - Goarch: runtime.GOARCH, + Goarch: "arm64", }) if err != nil { t.Fatal(err) } - tmp := t.TempDir() - llPath := filepath.Join(tmp, "dit.ll") - objPath := filepath.Join(tmp, "dit.o") - if err := os.WriteFile(llPath, []byte(ll), 0644); err != nil { + compileLLVMToObject(t, llc, arm64LinuxGNUTriple, "dit.ll", "dit.o", ll) +} + +func TestTranslateGoModule_StdlibInternalRuntimeSys_ARM64_Compile(t *testing.T) { + llc, _, ok := findLlcAndClang(t) + if !ok { + t.Skip("llc not found") + } + + goroot := testGOROOT(t) + src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "runtime", "sys", "dit_arm64.s")) + if err != nil { + if os.IsNotExist(err) { + t.Skip("internal/runtime/sys/dit_arm64.s not present in this GOROOT") + } t.Fatal(err) } - cmd := exec.Command(llc, "-filetype=obj", llPath, "-o", objPath) - out, err := cmd.CombinedOutput() + pkg := mustGoPackage(t, "internal/runtime/sys", `package sys +func EnableDIT() bool +func DITEnabled() bool +func DisableDIT() +`) + + tr, err := TranslateGoModule(pkg, src, GoModuleOptions{ + FileName: "dit_arm64.s", + GOOS: "linux", + GOARCH: "arm64", + TargetTriple: arm64LinuxGNUTriple, + ResolveSym: testResolveSym("internal/runtime/sys"), + }) if err != nil { - t.Fatalf("llc failed: %v\n%s", err, string(out)) + t.Fatal(err) } + defer tr.Module.Dispose() + + compileLLVMToObject(t, llc, arm64LinuxGNUTriple, "dit-gomod.ll", "dit-gomod.o", tr.Module.String()) }