1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
19 // TestLargeBranch generates a large function with a very far conditional
20 // branch, in order to ensure that it assembles successfully.
21 func TestLargeBranch(t *testing.T) {
23 t.Skip("Skipping test in short mode")
25 testenv.MustHaveGoBuild(t)
27 dir, err := ioutil.TempDir("", "testlargebranch")
29 t.Fatalf("Could not create directory: %v", err)
31 defer os.RemoveAll(dir)
33 // Generate a very large function.
34 buf := bytes.NewBuffer(make([]byte, 0, 7000000))
37 tmpfile := filepath.Join(dir, "x.s")
38 if err := ioutil.WriteFile(tmpfile, buf.Bytes(), 0644); err != nil {
39 t.Fatalf("Failed to write file: %v", err)
42 // Assemble generated file.
43 cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
44 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
45 out, err := cmd.CombinedOutput()
47 t.Errorf("Build failed: %v, output: %s", err, out)
51 func genLargeBranch(buf *bytes.Buffer) {
52 fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
53 fmt.Fprintln(buf, "BEQ X0, X0, label")
54 for i := 0; i < 1<<19; i++ {
55 fmt.Fprintln(buf, "ADD $0, X0, X0")
57 fmt.Fprintln(buf, "label:")
58 fmt.Fprintln(buf, "ADD $0, X0, X0")
61 // TestLargeCall generates a large function (>1MB of text) with a call to
62 // a following function, in order to ensure that it assembles and links
64 func TestLargeCall(t *testing.T) {
66 t.Skip("Skipping test in short mode")
68 testenv.MustHaveGoBuild(t)
70 dir, err := ioutil.TempDir("", "testlargecall")
72 t.Fatalf("could not create directory: %v", err)
74 defer os.RemoveAll(dir)
76 if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largecall"), 0644); err != nil {
77 t.Fatalf("Failed to write file: %v\n", err)
87 if err := ioutil.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
88 t.Fatalf("failed to write main: %v\n", err)
91 // Generate a very large function with call.
92 buf := bytes.NewBuffer(make([]byte, 0, 7000000))
95 if err := ioutil.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
96 t.Fatalf("Failed to write file: %v\n", err)
99 // Build generated files.
100 cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal")
102 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
103 out, err := cmd.CombinedOutput()
105 t.Errorf("Build failed: %v, output: %s", err, out)
108 if runtime.GOARCH == "riscv64" && testenv.HasCGO() {
109 cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=external")
111 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
112 out, err := cmd.CombinedOutput()
114 t.Errorf("Build failed: %v, output: %s", err, out)
119 func genLargeCall(buf *bytes.Buffer) {
120 fmt.Fprintln(buf, "TEXT ·x(SB),0,$0-0")
121 fmt.Fprintln(buf, "CALL ·y(SB)")
122 for i := 0; i < 1<<19; i++ {
123 fmt.Fprintln(buf, "ADD $0, X0, X0")
125 fmt.Fprintln(buf, "RET")
126 fmt.Fprintln(buf, "TEXT ·y(SB),0,$0-0")
127 fmt.Fprintln(buf, "ADD $0, X0, X0")
128 fmt.Fprintln(buf, "RET")
132 func TestNoRet(t *testing.T) {
133 dir, err := ioutil.TempDir("", "testnoret")
137 defer os.RemoveAll(dir)
138 tmpfile := filepath.Join(dir, "x.s")
139 if err := ioutil.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
142 cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
143 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
144 if out, err := cmd.CombinedOutput(); err != nil {
145 t.Errorf("%v\n%s", err, out)
149 func TestImmediateSplitting(t *testing.T) {
150 dir, err := ioutil.TempDir("", "testimmsplit")
154 defer os.RemoveAll(dir)
155 tmpfile := filepath.Join(dir, "x.s")
193 if err := ioutil.WriteFile(tmpfile, []byte(asm), 0644); err != nil {
196 cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
197 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
198 if out, err := cmd.CombinedOutput(); err != nil {
199 t.Errorf("%v\n%s", err, out)
203 func TestBranch(t *testing.T) {
204 if runtime.GOARCH != "riscv64" {
205 t.Skip("Requires riscv64 to run")
208 testenv.MustHaveGoBuild(t)
210 cmd := exec.Command(testenv.GoToolPath(t), "test")
211 cmd.Dir = "testdata/testbranch"
212 if out, err := testenv.CleanCmdEnv(cmd).CombinedOutput(); err != nil {
213 t.Errorf("Branch test failed: %v\n%s", err, out)