cmd/internal/obj/riscv: handle call, jmp and branch

Also provide REG_LR to more clearly define the link register.

Based on the riscv-go port.

Updates #27532

Change-Id: I0805f373682f93b3918a01c21d4ef34eb3817c75
Reviewed-on: https://go-review.googlesource.com/c/go/+/204627
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Joel Sing 2019-11-04 02:31:37 +11:00
parent 372efbbf31
commit 7cab55dfd3
4 changed files with 331 additions and 2 deletions

View file

@ -0,0 +1,79 @@
// Copyright 2019 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package riscv
import (
"bytes"
"fmt"
"internal/testenv"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"testing"
)
// TestLarge generates a very large file to verify that large
// program builds successfully, in particular, too-far
// conditional branches are fixed.
func TestLarge(t *testing.T) {
if testing.Short() {
t.Skip("Skip in short mode")
}
testenv.MustHaveGoBuild(t)
dir, err := ioutil.TempDir("", "testlarge")
if err != nil {
t.Fatalf("could not create directory: %v", err)
}
defer os.RemoveAll(dir)
// Generate a very large function.
buf := bytes.NewBuffer(make([]byte, 0, 7000000))
gen(buf)
tmpfile := filepath.Join(dir, "x.s")
err = ioutil.WriteFile(tmpfile, buf.Bytes(), 0644)
if err != nil {
t.Fatalf("can't write output: %v\n", err)
}
// Build generated file.
cmd := exec.Command(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 {
t.Errorf("Build failed: %v, output: %s", err, out)
}
}
// gen generates a very large program, with a very far conditional branch.
func gen(buf *bytes.Buffer) {
fmt.Fprintln(buf, "TEXT f(SB),0,$0-0")
fmt.Fprintln(buf, "BEQ X0, X0, label")
for i := 0; i < 1<<19; i++ {
fmt.Fprintln(buf, "ADD $0, X0, X0")
}
fmt.Fprintln(buf, "label:")
fmt.Fprintln(buf, "ADD $0, X0, X0")
}
// Issue 20348.
func TestNoRet(t *testing.T) {
dir, err := ioutil.TempDir("", "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 {
t.Fatal(err)
}
cmd := exec.Command(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)
}
}