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 := t.TempDir()
35 err := os.WriteFile(filepath.Join(tmpdir, "go.mod"), []byte(fmt.Sprintf("module %s\n", mname)), 0666)
36 if err != nil {
37 t.Fatal(err)
38 }
39 tmpfile, err := os.Create(filepath.Join(tmpdir, "input.s"))
40 if err != nil {
41 t.Fatal(err)
42 }
43 defer tmpfile.Close()
44 _, err = tmpfile.WriteString(source)
45 if err != nil {
46 t.Fatal(err)
47 }
48 tmpfile2, err := os.Create(filepath.Join(tmpdir, "input.go"))
49 if err != nil {
50 t.Fatal(err)
51 }
52 defer tmpfile2.Close()
53 _, err = tmpfile2.WriteString(goData)
54 if err != nil {
55 t.Fatal(err)
56 }
57
58 cmd := testenv.Command(t,
59 testenv.GoToolPath(t), "build", "-o",
60 filepath.Join(tmpdir, "output"))
61
62 cmd.Env = append(os.Environ(),
63 "GOARCH=amd64", "GOOS=linux", "GOPATH="+filepath.Join(tmpdir, "_gopath"))
64 cmd.Dir = tmpdir
65
66 out, err := cmd.CombinedOutput()
67 if err != nil {
68 t.Fatalf("error %s output %s", err, out)
69 }
70 cmd2 := testenv.Command(t,
71 testenv.GoToolPath(t), "tool", "objdump", "-s", "testASM",
72 filepath.Join(tmpdir, "output"))
73 cmd2.Env = cmd.Env
74 cmd2.Dir = tmpdir
75 objout, err := cmd2.CombinedOutput()
76 if err != nil {
77 t.Fatalf("error %s output %s", err, objout)
78 }
79
80 return objout
81 }
82
83 func TestVexEvexPCrelative(t *testing.T) {
84 testenv.MustHaveGoBuild(t)
85 LOOP:
86 for _, reg := range []string{"Y0", "Y8", "Z0", "Z8", "Z16", "Z24"} {
87 asm := fmt.Sprintf(asmData, reg)
88 objout := objdumpOutput(t, "pcrelative", asm)
89 data := bytes.Split(objout, []byte("\n"))
90 for idx := len(data) - 1; idx >= 0; idx-- {
91
92 if bytes.Contains(data[idx], []byte("RET")) {
93 if testing.Short() {
94 break LOOP
95 }
96 continue LOOP
97 }
98 }
99 t.Errorf("VMOVUPS zeros<>(SB), %s overwrote RET", reg)
100 }
101 }
102
View as plain text