1
2
3
4
5 package arm64
6
7 import (
8 "bytes"
9 "fmt"
10 "internal/testenv"
11 "io/ioutil"
12 "os"
13 "os/exec"
14 "path/filepath"
15 "regexp"
16 "testing"
17 )
18
19
20
21
22
23
24 func TestLarge(t *testing.T) {
25 if testing.Short() {
26 t.Skip("Skip in short mode")
27 }
28 testenv.MustHaveGoBuild(t)
29
30 dir, err := ioutil.TempDir("", "testlarge")
31 if err != nil {
32 t.Fatalf("could not create directory: %v", err)
33 }
34 defer os.RemoveAll(dir)
35
36
37 buf := bytes.NewBuffer(make([]byte, 0, 7000000))
38 gen(buf)
39
40 tmpfile := filepath.Join(dir, "x.s")
41 err = ioutil.WriteFile(tmpfile, buf.Bytes(), 0644)
42 if err != nil {
43 t.Fatalf("can't write output: %v\n", err)
44 }
45
46 pattern := `0x0080\s00128\s\(.*\)\tMOVD\t\$3,\sR3`
47
48
49 cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-S", "-o", filepath.Join(dir, "test.o"), tmpfile)
50 cmd.Env = append(os.Environ(), "GOOS=linux")
51 out, err := cmd.CombinedOutput()
52 if err != nil {
53 t.Errorf("Assemble failed: %v, output: %s", err, out)
54 }
55 matched, err := regexp.MatchString(pattern, string(out))
56 if err != nil {
57 t.Fatal(err)
58 }
59 if !matched {
60 t.Errorf("The alignment is not correct: %t, output:%s\n", matched, out)
61 }
62
63
64 cmd = exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
65 cmd.Env = append(os.Environ(), "GOOS=linux")
66 out, err = cmd.CombinedOutput()
67 if err != nil {
68 t.Errorf("Build failed: %v, output: %s", err, out)
69 }
70 }
71
72
73 func gen(buf *bytes.Buffer) {
74 fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
75 fmt.Fprintln(buf, "TBZ $5, R0, label")
76 fmt.Fprintln(buf, "CBZ R0, label")
77 fmt.Fprintln(buf, "BEQ label")
78 fmt.Fprintln(buf, "PCALIGN $128")
79 fmt.Fprintln(buf, "MOVD $3, R3")
80 for i := 0; i < 1<<19; i++ {
81 fmt.Fprintln(buf, "MOVD R0, R1")
82 }
83 fmt.Fprintln(buf, "label:")
84 fmt.Fprintln(buf, "RET")
85 }
86
87
88 func TestNoRet(t *testing.T) {
89 dir, err := ioutil.TempDir("", "testnoret")
90 if err != nil {
91 t.Fatal(err)
92 }
93 defer os.RemoveAll(dir)
94 tmpfile := filepath.Join(dir, "x.s")
95 if err := ioutil.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
96 t.Fatal(err)
97 }
98 cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
99 cmd.Env = append(os.Environ(), "GOOS=linux")
100 if out, err := cmd.CombinedOutput(); err != nil {
101 t.Errorf("%v\n%s", err, out)
102 }
103 }
104
105
106
107 func TestPCALIGN(t *testing.T) {
108 testenv.MustHaveGoBuild(t)
109 dir, err := ioutil.TempDir("", "testpcalign")
110 if err != nil {
111 t.Fatal(err)
112 }
113 defer os.RemoveAll(dir)
114 tmpfile := filepath.Join(dir, "test.s")
115 tmpout := filepath.Join(dir, "test.o")
116
117 code1 := []byte("TEXT ·foo(SB),$0-0\nMOVD $0, R0\nPCALIGN $8\nMOVD $1, R1\nRET\n")
118 code2 := []byte("TEXT ·foo(SB),$0-0\nMOVD $0, R0\nPCALIGN $16\nMOVD $2, R2\nRET\n")
119
120 out1 := `0x0008\s00008\s\(.*\)\tMOVD\t\$1,\sR1`
121
122 out2 := `0x0010\s00016\s\(.*\)\tMOVD\t\$2,\sR2`
123 var testCases = []struct {
124 name string
125 code []byte
126 out string
127 }{
128 {"8-byte alignment", code1, out1},
129 {"16-byte alignment", code2, out2},
130 }
131
132 for _, test := range testCases {
133 if err := ioutil.WriteFile(tmpfile, test.code, 0644); err != nil {
134 t.Fatal(err)
135 }
136 cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-S", "-o", tmpout, tmpfile)
137 cmd.Env = append(os.Environ(), "GOOS=linux")
138 out, err := cmd.CombinedOutput()
139 if err != nil {
140 t.Errorf("The %s build failed: %v, output: %s", test.name, err, out)
141 continue
142 }
143
144 matched, err := regexp.MatchString(test.out, string(out))
145 if err != nil {
146 t.Fatal(err)
147 }
148 if !matched {
149 t.Errorf("The %s testing failed!\ninput: %s\noutput: %s\n", test.name, test.code, out)
150 }
151 }
152 }
153
154 func testvmovq() (r1, r2 uint64)
155
156
157 func TestVMOVQ(t *testing.T) {
158 a, b := testvmovq()
159 if a != 0x7040201008040201 || b != 0x3040201008040201 {
160 t.Errorf("TestVMOVQ got: a=0x%x, b=0x%x, want: a=0x7040201008040201, b=0x3040201008040201", a, b)
161 }
162 }
163
View as plain text