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.
17 // TestLargeBranch generates a large function with a very far conditional
18 // branch, in order to ensure that it assembles successfully.
19 func TestLargeBranch(t *testing.T) {
21 t.Skip("Skipping test in short mode")
23 testenv.MustHaveGoBuild(t)
25 dir, err := os.MkdirTemp("", "testlargebranch")
27 t.Fatalf("Could not create directory: %v", err)
29 defer os.RemoveAll(dir)
31 // Generate a very large function.
32 buf := bytes.NewBuffer(make([]byte, 0, 7000000))
35 tmpfile := filepath.Join(dir, "x.s")
36 if err := os.WriteFile(tmpfile, buf.Bytes(), 0644); err != nil {
37 t.Fatalf("Failed to write file: %v", err)
40 // Assemble generated file.
41 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
42 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
43 out, err := cmd.CombinedOutput()
45 t.Errorf("Build failed: %v, output: %s", err, out)
49 func genLargeBranch(buf *bytes.Buffer) {
50 fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
51 fmt.Fprintln(buf, "BEQ X0, X0, label")
52 for i := 0; i < 1<<19; i++ {
53 fmt.Fprintln(buf, "ADD $0, X0, X0")
55 fmt.Fprintln(buf, "label:")
56 fmt.Fprintln(buf, "ADD $0, X0, X0")
59 // TestLargeCall generates a large function (>1MB of text) with a call to
60 // a following function, in order to ensure that it assembles and links
62 func TestLargeCall(t *testing.T) {
64 t.Skip("Skipping test in short mode")
66 testenv.MustHaveGoBuild(t)
68 dir, err := os.MkdirTemp("", "testlargecall")
70 t.Fatalf("could not create directory: %v", err)
72 defer os.RemoveAll(dir)
74 if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largecall"), 0644); err != nil {
75 t.Fatalf("Failed to write file: %v\n", err)
85 if err := os.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
86 t.Fatalf("failed to write main: %v\n", err)
89 // Generate a very large function with call.
90 buf := bytes.NewBuffer(make([]byte, 0, 7000000))
93 if err := os.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
94 t.Fatalf("Failed to write file: %v\n", err)
97 // Build generated files.
98 cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal")
100 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
101 out, err := cmd.CombinedOutput()
103 t.Errorf("Build failed: %v, output: %s", err, out)
106 if runtime.GOARCH == "riscv64" && testenv.HasCGO() {
107 cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-linkmode=external")
109 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
110 out, err := cmd.CombinedOutput()
112 t.Errorf("Build failed: %v, output: %s", err, out)
117 func genLargeCall(buf *bytes.Buffer) {
118 fmt.Fprintln(buf, "TEXT ·x(SB),0,$0-0")
119 fmt.Fprintln(buf, "CALL ·y(SB)")
120 for i := 0; i < 1<<19; i++ {
121 fmt.Fprintln(buf, "ADD $0, X0, X0")
123 fmt.Fprintln(buf, "RET")
124 fmt.Fprintln(buf, "TEXT ·y(SB),0,$0-0")
125 fmt.Fprintln(buf, "ADD $0, X0, X0")
126 fmt.Fprintln(buf, "RET")
130 func TestNoRet(t *testing.T) {
131 dir, err := os.MkdirTemp("", "testnoret")
135 defer os.RemoveAll(dir)
136 tmpfile := filepath.Join(dir, "x.s")
137 if err := os.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
140 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
141 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
142 if out, err := cmd.CombinedOutput(); err != nil {
143 t.Errorf("%v\n%s", err, out)
147 func TestImmediateSplitting(t *testing.T) {
148 dir, err := os.MkdirTemp("", "testimmsplit")
152 defer os.RemoveAll(dir)
153 tmpfile := filepath.Join(dir, "x.s")
191 if err := os.WriteFile(tmpfile, []byte(asm), 0644); err != nil {
194 cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
195 cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
196 if out, err := cmd.CombinedOutput(); err != nil {
197 t.Errorf("%v\n%s", err, out)
201 func TestBranch(t *testing.T) {
202 if runtime.GOARCH != "riscv64" {
203 t.Skip("Requires riscv64 to run")
206 testenv.MustHaveGoBuild(t)
208 cmd := testenv.Command(t, testenv.GoToolPath(t), "test")
209 cmd.Dir = "testdata/testbranch"
210 if out, err := testenv.CleanCmdEnv(cmd).CombinedOutput(); err != nil {
211 t.Errorf("Branch test failed: %v\n%s", err, out)