github.com/golangaccount/cmd.internal@v0.0.0-20191108101845-8306c88f1d22/obj/arm64/asm_test.go (about)

     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  }