"bytes"
"fmt"
"internal/testenv"
- "io/ioutil"
"os"
- "os/exec"
"path/filepath"
"runtime"
"testing"
}
testenv.MustHaveGoBuild(t)
- dir, err := ioutil.TempDir("", "testlargebranch")
+ dir, err := os.MkdirTemp("", "testlargebranch")
if err != nil {
t.Fatalf("Could not create directory: %v", err)
}
genLargeBranch(buf)
tmpfile := filepath.Join(dir, "x.s")
- if err := ioutil.WriteFile(tmpfile, buf.Bytes(), 0644); err != nil {
+ if err := os.WriteFile(tmpfile, buf.Bytes(), 0644); err != nil {
t.Fatalf("Failed to write file: %v", err)
}
// Assemble generated file.
- cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
out, err := cmd.CombinedOutput()
if err != nil {
}
testenv.MustHaveGoBuild(t)
- dir, err := ioutil.TempDir("", "testlargecall")
+ dir, err := os.MkdirTemp("", "testlargecall")
if err != nil {
t.Fatalf("could not create directory: %v", err)
}
defer os.RemoveAll(dir)
- if err := ioutil.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largecall"), 0644); err != nil {
+ if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largecall"), 0644); err != nil {
t.Fatalf("Failed to write file: %v\n", err)
}
main := `package main
func x()
func y()
`
- if err := ioutil.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
+ if err := os.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
t.Fatalf("failed to write main: %v\n", err)
}
buf := bytes.NewBuffer(make([]byte, 0, 7000000))
genLargeCall(buf)
- if err := ioutil.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
+ if err := os.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
t.Fatalf("Failed to write file: %v\n", err)
}
// Build generated files.
- cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal")
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-linkmode=internal")
cmd.Dir = dir
cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
out, err := cmd.CombinedOutput()
}
if runtime.GOARCH == "riscv64" && testenv.HasCGO() {
- cmd := exec.Command(testenv.GoToolPath(t), "build", "-ldflags=-linkmode=external")
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-ldflags=-linkmode=external")
cmd.Dir = dir
cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
out, err := cmd.CombinedOutput()
fmt.Fprintln(buf, "RET")
}
+// TestLargeJump generates a large jump (>1MB of text) with a JMP to the
+// end of the function, in order to ensure that it assembles correctly.
+func TestLargeJump(t *testing.T) {
+ if testing.Short() {
+ t.Skip("Skipping test in short mode")
+ }
+ if runtime.GOARCH != "riscv64" {
+ t.Skip("Require riscv64 to run")
+ }
+ testenv.MustHaveGoBuild(t)
+
+ dir := t.TempDir()
+
+ if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte("module largejump"), 0644); err != nil {
+ t.Fatalf("Failed to write file: %v\n", err)
+ }
+ main := `package main
+
+import "fmt"
+
+func main() {
+ fmt.Print(x())
+}
+
+func x() uint64
+`
+ if err := os.WriteFile(filepath.Join(dir, "x.go"), []byte(main), 0644); err != nil {
+ t.Fatalf("failed to write main: %v\n", err)
+ }
+
+ // Generate a very large jump instruction.
+ buf := bytes.NewBuffer(make([]byte, 0, 7000000))
+ genLargeJump(buf)
+
+ if err := os.WriteFile(filepath.Join(dir, "x.s"), buf.Bytes(), 0644); err != nil {
+ t.Fatalf("Failed to write file: %v\n", err)
+ }
+
+ // Build generated files.
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "build", "-o", "x.exe")
+ cmd.Dir = dir
+ out, err := cmd.CombinedOutput()
+ if err != nil {
+ t.Errorf("Build failed: %v, output: %s", err, out)
+ }
+
+ cmd = testenv.Command(t, filepath.Join(dir, "x.exe"))
+ out, err = cmd.CombinedOutput()
+ if string(out) != "1" {
+ t.Errorf(`Got test output %q, want "1"`, string(out))
+ }
+}
+
+func genLargeJump(buf *bytes.Buffer) {
+ fmt.Fprintln(buf, "TEXT ·x(SB),0,$0-8")
+ fmt.Fprintln(buf, "MOV X0, X10")
+ fmt.Fprintln(buf, "JMP end")
+ for i := 0; i < 1<<18; i++ {
+ fmt.Fprintln(buf, "ADD $1, X10, X10")
+ }
+ fmt.Fprintln(buf, "end:")
+ fmt.Fprintln(buf, "ADD $1, X10, X10")
+ fmt.Fprintln(buf, "MOV X10, r+0(FP)")
+ fmt.Fprintln(buf, "RET")
+}
+
// Issue 20348.
func TestNoRet(t *testing.T) {
- dir, err := ioutil.TempDir("", "testnoret")
+ dir, err := os.MkdirTemp("", "testnoret")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
tmpfile := filepath.Join(dir, "x.s")
- if err := ioutil.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
+ if err := os.WriteFile(tmpfile, []byte("TEXT ·stub(SB),$0-0\nNOP\n"), 0644); err != nil {
t.Fatal(err)
}
- cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
if out, err := cmd.CombinedOutput(); err != nil {
t.Errorf("%v\n%s", err, out)
}
func TestImmediateSplitting(t *testing.T) {
- dir, err := ioutil.TempDir("", "testimmsplit")
+ dir, err := os.MkdirTemp("", "testimmsplit")
if err != nil {
t.Fatal(err)
}
MOVF F6, 4096(X5)
MOVD F6, 4096(X5)
`
- if err := ioutil.WriteFile(tmpfile, []byte(asm), 0644); err != nil {
+ if err := os.WriteFile(tmpfile, []byte(asm), 0644); err != nil {
t.Fatal(err)
}
- cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
cmd.Env = append(os.Environ(), "GOARCH=riscv64", "GOOS=linux")
if out, err := cmd.CombinedOutput(); err != nil {
t.Errorf("%v\n%s", err, out)
testenv.MustHaveGoBuild(t)
- cmd := exec.Command(testenv.GoToolPath(t), "test")
+ cmd := testenv.Command(t, testenv.GoToolPath(t), "test")
cmd.Dir = "testdata/testbranch"
if out, err := testenv.CleanCmdEnv(cmd).CombinedOutput(); err != nil {
t.Errorf("Branch test failed: %v\n%s", err, out)