Home | History | Annotate | Download | only in arm64
      1 // Copyright 2016 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.
      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 	"testing"
     16 )
     17 
     18 // TestLarge generates a very large file to verify that large
     19 // program builds successfully, in particular, too-far
     20 // conditional branches are fixed.
     21 func TestLarge(t *testing.T) {
     22 	if testing.Short() {
     23 		t.Skip("Skip in short mode")
     24 	}
     25 	testenv.MustHaveGoBuild(t)
     26 
     27 	dir, err := ioutil.TempDir("", "testlarge")
     28 	if err != nil {
     29 		t.Fatalf("could not create directory: %v", err)
     30 	}
     31 	defer os.RemoveAll(dir)
     32 
     33 	// generate a very large function
     34 	buf := bytes.NewBuffer(make([]byte, 0, 7000000))
     35 	gen(buf)
     36 
     37 	tmpfile := filepath.Join(dir, "x.s")
     38 	err = ioutil.WriteFile(tmpfile, buf.Bytes(), 0644)
     39 	if err != nil {
     40 		t.Fatalf("can't write output: %v\n", err)
     41 	}
     42 
     43 	// build generated file
     44 	cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), tmpfile)
     45 	cmd.Env = []string{"GOARCH=arm64", "GOOS=linux"}
     46 	out, err := cmd.CombinedOutput()
     47 	if err != nil {
     48 		t.Errorf("Build failed: %v, output: %s", err, out)
     49 	}
     50 }
     51 
     52 // gen generates a very large program, with a very far conditional branch.
     53 func gen(buf *bytes.Buffer) {
     54 	fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
     55 	fmt.Fprintln(buf, "CBZ R0, label")
     56 	fmt.Fprintln(buf, "BEQ label")
     57 	for i := 0; i < 1<<19; i++ {
     58 		fmt.Fprintln(buf, "MOVD R0, R1")
     59 	}
     60 	fmt.Fprintln(buf, "label:")
     61 	fmt.Fprintln(buf, "RET")
     62 }
     63