-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathstdlib_cpu_x86_test.go
More file actions
145 lines (133 loc) · 3.69 KB
/
stdlib_cpu_x86_test.go
File metadata and controls
145 lines (133 loc) · 3.69 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//go:build !llgo
// +build !llgo
package plan9asm
import (
"os"
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"
)
func TestStdlibInternalCPU_X86_CompileX86Triples(t *testing.T) {
llc, _, ok := findLlcAndClang(t)
if !ok {
t.Skip("llc not found")
}
goroot := runtime.GOROOT()
src, err := os.ReadFile(filepath.Join(goroot, "src", "internal", "cpu", "cpu_x86.s"))
if err != nil {
t.Fatal(err)
}
file, err := Parse(ArchAMD64, string(src))
if err != nil {
t.Fatal(err)
}
resolve := func(sym string) string {
if strings.HasPrefix(sym, "·") {
return "internal/cpu." + strings.TrimPrefix(sym, "·")
}
return strings.ReplaceAll(sym, "·", ".")
}
// func cpuid(eaxArg, ecxArg uint32) (eax, ebx, ecx, edx uint32)
cpuidRet := LLVMType("{ i32, i32, i32, i32 }")
// func xgetbv() (eax, edx uint32)
xgetbvRet := LLVMType("{ i32, i32 }")
sigs := map[string]FuncSig{
"internal/cpu.cpuid": {
Name: "internal/cpu.cpuid",
Args: []LLVMType{I32, I32},
Ret: cpuidRet,
Frame: FrameLayout{
Params: []FrameSlot{
{Offset: 0, Type: I32, Index: 0, Field: -1}, // eaxArg
{Offset: 4, Type: I32, Index: 1, Field: -1}, // ecxArg
},
Results: []FrameSlot{
{Offset: 8, Type: I32, Index: 0, Field: -1}, // eax
{Offset: 12, Type: I32, Index: 1, Field: -1}, // ebx
{Offset: 16, Type: I32, Index: 2, Field: -1}, // ecx
{Offset: 20, Type: I32, Index: 3, Field: -1}, // edx
},
},
},
"internal/cpu.xgetbv": {
Name: "internal/cpu.xgetbv",
Ret: xgetbvRet,
Frame: FrameLayout{
Results: []FrameSlot{
{Offset: 0, Type: I32, Index: 0, Field: -1}, // eax
{Offset: 4, Type: I32, Index: 1, Field: -1}, // edx
},
},
},
"internal/cpu.getGOAMD64level": {
Name: "internal/cpu.getGOAMD64level",
Ret: I32,
Frame: FrameLayout{
Results: []FrameSlot{
{Offset: 0, Type: I32, Index: 0, Field: -1},
},
},
},
}
triples := []string{
"x86_64-unknown-linux-gnu",
"x86_64-apple-macosx",
}
if hostTriple := testTargetTriple(runtime.GOOS, runtime.GOARCH); strings.HasPrefix(hostTriple, "x86_64-") {
dup := false
for _, t := range triples {
if t == hostTriple {
dup = true
break
}
}
if !dup {
triples = append(triples, hostTriple)
}
}
compiled := 0
for _, triple := range triples {
t.Run(triple, func(t *testing.T) {
ll, err := Translate(file, Options{
TargetTriple: triple,
ResolveSym: resolve,
Sigs: sigs,
})
if err != nil {
// Host triple may not be x86_64; only enforce for x86_64 triples.
if strings.HasPrefix(triple, "x86_64-") {
t.Fatalf("translate failed: %v", err)
}
t.Skipf("translate skipped for non-x86 triple %q: %v", triple, err)
}
if !strings.HasPrefix(triple, "x86_64-") {
t.Skip("llc compilation only meaningful for x86_64 triples")
}
tmp := t.TempDir()
llPath := filepath.Join(tmp, "cpu_x86.ll")
objPath := filepath.Join(tmp, "cpu_x86.o")
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 strings.Contains(s, "No available targets") ||
strings.Contains(s, "no targets are registered") ||
strings.Contains(s, "unknown target triple") ||
strings.Contains(s, "unknown target") ||
strings.Contains(s, "is not a registered target") {
t.Skipf("llc does not support triple %q: %s", triple, strings.TrimSpace(s))
}
t.Fatalf("llc failed for triple %q: %v\n%s", triple, err, s)
}
compiled++
})
}
if compiled == 0 {
t.Fatalf("expected at least one successful llc compilation")
}
}