1
2
3
4
5 package x86_test
6
7 import (
8 "bytes"
9 "fmt"
10 "internal/testenv"
11 "os"
12 "path/filepath"
13 "testing"
14 )
15
16 const asmData = `
17 GLOBL zeros<>(SB),8,$64
18 TEXT ·testASM(SB),4,$0
19 VMOVUPS zeros<>(SB), %s // PC relative relocation is off by 1, for Y8-Y15, Z8-15 and Z24-Z31
20 RET
21 `
22
23 const goData = `
24 package main
25
26 func testASM()
27
28 func main() {
29 testASM()
30 }
31 `
32
33 func objdumpOutput(t *testing.T, mname, source string) []byte {
34 tmpdir, err := os.MkdirTemp("", mname)
35 if err != nil {
36 t.Fatal(err)
37 }
38 defer os.RemoveAll(tmpdir)
39 err = os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte(fmt.Sprintf("module %s\n", mname)), 0666)
40 if err != nil {
41 t.Fatal(err)
42 }
43 tmpfile, err := os.Create(filepath.Join(tmpdir, "input.s"))
44 if err != nil {
45 t.Fatal(err)
46 }
47 defer tmpfile.Close()
48 _, err = tmpfile.WriteString(source)
49 if err != nil {
50 t.Fatal(err)
51 }
52 tmpfile2, err := os.Create(filepath.Join(tmpdir, "input.go"))
53 if err != nil {
54 t.Fatal(err)
55 }
56 defer tmpfile2.Close()
57 _, err = tmpfile2.WriteString(goData)
58 if err != nil {
59 t.Fatal(err)
60 }
61
62 cmd := testenv.Command(t,
63 testenv.GoToolPath(t), "build", "-o",
64 filepath.Join(tmpdir, "output"))
65
66 cmd.Env = append(os.Environ(),
67 "GOARCH=amd64", "GOOS=linux", "GOPATH="+filepath.Join(tmpdir, "_gopath"))
68 cmd.Dir = tmpdir
69
70 out, err := cmd.CombinedOutput()
71 if err != nil {
72 t.Fatalf("error %s output %s", err, out)
73 }
74 cmd2 := testenv.Command(t,
75 testenv.GoToolPath(t), "tool", "objdump", "-s", "testASM",
76 filepath.Join(tmpdir, "output"))
77 cmd2.Env = cmd.Env
78 cmd2.Dir = tmpdir
79 objout, err := cmd2.CombinedOutput()
80 if err != nil {
81 t.Fatalf("error %s output %s", err, objout)
82 }
83
84 return objout
85 }
86
87 func TestVexEvexPCrelative(t *testing.T) {
88 testenv.MustHaveGoBuild(t)
89 LOOP:
90 for _, reg := range []string{"Y0", "Y8", "Z0", "Z8", "Z16", "Z24"} {
91 asm := fmt.Sprintf(asmData, reg)
92 objout := objdumpOutput(t, "pcrelative", asm)
93 data := bytes.Split(objout, []byte("\n"))
94 for idx := len(data) - 1; idx >= 0; idx-- {
95
96 if bytes.Contains(data[idx], []byte("RET")) {
97 if testing.Short() {
98 break LOOP
99 }
100 continue LOOP
101 }
102 }
103 t.Errorf("VMOVUPS zeros<>(SB), %s overwrote RET", reg)
104 }
105 }
106
View as plain text