]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/loong64: add testcases for assembler
authorlimeidan <limeidan@loongson.cn>
Wed, 7 Aug 2024 09:59:54 +0000 (17:59 +0800)
committerabner chenc <chenguoqi@loongson.cn>
Thu, 15 Aug 2024 00:52:05 +0000 (00:52 +0000)
Change-Id: Ib2c8e0bc314c0f2b58f69a5340355cac4786a91f
Reviewed-on: https://go-review.googlesource.com/c/go/+/604175
Reviewed-by: David Chase <drchase@google.com>
Reviewed-by: Carlos Amedee <carlos@golang.org>
Reviewed-by: abner chenc <chenguoqi@loongson.cn>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/cmd/internal/obj/loong64/asm_test.go

index a35de61df6ae227a6fd20815b4f24c0762b1d831..69f97bff57bb04018653d6ac78364351603b8a58 100644 (file)
@@ -10,6 +10,8 @@ import (
        "internal/testenv"
        "os"
        "path/filepath"
+       "regexp"
+       "runtime"
        "testing"
 )
 
@@ -83,3 +85,116 @@ func genLargeBranch(buf *bytes.Buffer) {
        fmt.Fprintln(buf, "ADDV $0, R0, R0")
        fmt.Fprintln(buf, "RET")
 }
+
+// TestPCALIGN verifies the correctness of the PCALIGN by checking if the
+// code can be aligned to the alignment value.
+func TestPCALIGN(t *testing.T) {
+       testenv.MustHaveGoBuild(t)
+       dir := t.TempDir()
+       tmpfile := filepath.Join(dir, "testpcalign.s")
+       tmpout := filepath.Join(dir, "testpcalign.o")
+
+       code1 := []byte("TEXT ·foo(SB),$0-0\nMOVW $0, R0\nPCALIGN $8\nADDV $8, R0\nRET\n")
+       code2 := []byte("TEXT ·foo(SB),$0-0\nMOVW $0, R0\nPCALIGN $16\nADDV $16, R0\nRET\n")
+       code3 := []byte("TEXT ·foo(SB),$0-0\nMOVW $0, R0\nPCALIGN $32\nADDV $32, R0\nRET\n")
+       out1 := `0x0008\s00008\s\(.*\)\s*ADDV\s\$8,\sR0`
+       out2 := `0x0010\s00016\s\(.*\)\s*ADDV\s\$16,\sR0`
+       out3 := `0x0020\s00032\s\(.*\)\s*ADDV\s\$32,\sR0`
+       var testCases = []struct {
+               name   string
+               source []byte
+               want   string
+       }{
+               {"pcalign8", code1, out1},
+               {"pcalign16", code2, out2},
+               {"pcalign32", code3, out3},
+       }
+       for _, test := range testCases {
+               if err := os.WriteFile(tmpfile, test.source, 0644); err != nil {
+                       t.Fatal(err)
+               }
+               cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-S", "-o", tmpout, tmpfile)
+               cmd.Env = append(os.Environ(), "GOARCH=loong64", "GOOS=linux")
+               out, err := cmd.CombinedOutput()
+               if err != nil {
+                       t.Errorf("The %s build failed: %v, output: %s", test.name, err, out)
+                       continue
+               }
+               matched, err := regexp.MatchString(test.want, string(out))
+               if err != nil {
+                       t.Fatal(err)
+               }
+               if !matched {
+                       t.Errorf("The %s testing failed!\ninput: %s\noutput: %s\n", test.name, test.source, out)
+               }
+       }
+}
+
+func TestNoRet(t *testing.T) {
+       dir := t.TempDir()
+       tmpfile := filepath.Join(dir, "testnoret.s")
+       tmpout := filepath.Join(dir, "testnoret.o")
+       if err := os.WriteFile(tmpfile, []byte("TEXT ·foo(SB),$0-0\nNOP\n"), 0644); err != nil {
+               t.Fatal(err)
+       }
+       cmd := testenv.Command(t, testenv.GoToolPath(t), "tool", "asm", "-o", tmpout, tmpfile)
+       cmd.Env = append(os.Environ(), "GOARCH=loong64", "GOOS=linux")
+       if out, err := cmd.CombinedOutput(); err != nil {
+               t.Errorf("%v\n%s", err, out)
+       }
+}
+
+func TestLargeCall(t *testing.T) {
+       if testing.Short() {
+               t.Skip("Skipping test in short mode")
+       }
+       if runtime.GOARCH != "loong64" {
+               t.Skip("Require loong64 to run")
+       }
+       testenv.MustHaveGoBuild(t)
+
+       dir := t.TempDir()
+
+       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 main() {
+        a()
+}
+
+func a()
+`
+       if err := os.WriteFile(filepath.Join(dir, "largecall.go"), []byte(main), 0644); err != nil {
+               t.Fatalf("failed to write main: %v\n", err)
+       }
+
+       // Generate a very large call instruction.
+       buf := bytes.NewBuffer(make([]byte, 0, 7000000))
+       genLargeCall(buf)
+
+       if err := os.WriteFile(filepath.Join(dir, "largecall.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")
+       cmd.Dir = dir
+       out, err := cmd.CombinedOutput()
+       if err != nil {
+               t.Errorf("Build failed: %v, output: %s", err, out)
+       }
+}
+
+func genLargeCall(buf *bytes.Buffer) {
+       fmt.Fprintln(buf, "TEXT main·a(SB),0,$0-8")
+       fmt.Fprintln(buf, "CALL b(SB)")
+       for i := 0; i <= ((1 << 26) + 26); i++ {
+               fmt.Fprintln(buf, "ADDV $0, R0, R0")
+       }
+       fmt.Fprintln(buf, "RET")
+       fmt.Fprintln(buf, "TEXT b(SB),0,$0-8")
+       fmt.Fprintln(buf, "ADDV $0, R0, R0")
+       fmt.Fprintln(buf, "RET")
+}