]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: fix PCALIGN on ppc64le
authorLynn Boger <laboger@linux.vnet.ibm.com>
Tue, 17 Mar 2020 13:24:47 +0000 (09:24 -0400)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Tue, 24 Mar 2020 20:55:08 +0000 (20:55 +0000)
This fixes a potential issue with the previous implementation
of PCALIGN on ppc64. Previously PCALIGN was processed inside of
asmout and indicated the padding size by setting the value in
the optab, changing it back after the alignment instructions
were added. Now PCALIGN is processed outside of asmout, and optab
is not changed.

Change-Id: I8b0093a0e2b7e06176af27e05150d04ae2c55d60
Reviewed-on: https://go-review.googlesource.com/c/go/+/225198
Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/internal/obj/ppc64/asm9.go
src/cmd/internal/obj/ppc64/asm_test.go [new file with mode: 0644]

index b62eda8b148624db6a71fdbb931f82724e8bf3f8..90bee3d9b6c241fdb6594abe13381588962d5842 100644 (file)
@@ -627,8 +627,6 @@ func addpad(pc, a int64, ctxt *obj.Link) int {
                }
        case 16:
                switch pc % 16 {
-               // When currently aligned to 4, avoid 3 NOPs and set to
-               // 8 byte alignment which should still help.
                case 4, 12:
                        return 4
                case 8:
@@ -758,15 +756,20 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                if int(o.size) > 4*len(out) {
                        log.Fatalf("out array in span9 is too small, need at least %d for %v", o.size/4, p)
                }
-               origsize := o.size
-               c.asmout(p, o, out[:])
-               if origsize == 0 && o.size > 0 {
-                       for i = 0; i < int32(o.size/4); i++ {
-                               c.ctxt.Arch.ByteOrder.PutUint32(bp, out[0])
-                               bp = bp[4:]
+               // asmout is not set up to add large amounts of padding
+               if o.type_ == 0 && p.As == obj.APCALIGN {
+                       pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
+                       aln := c.vregoff(&p.From)
+                       v := addpad(p.Pc, aln, c.ctxt)
+                       if v > 0 {
+                               // Same padding instruction for all
+                               for i = 0; i < int32(v/4); i++ {
+                                       c.ctxt.Arch.ByteOrder.PutUint32(bp, pad)
+                                       bp = bp[4:]
+                               }
                        }
-                       o.size = origsize
                } else {
+                       c.asmout(p, o, out[:])
                        for i = 0; i < int32(o.size/4); i++ {
                                c.ctxt.Arch.ByteOrder.PutUint32(bp, out[i])
                                bp = bp[4:]
@@ -2387,19 +2390,6 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
                prasm(p)
 
        case 0: /* pseudo ops */
-               if p.As == obj.APCALIGN {
-                       aln := c.vregoff(&p.From)
-                       v := addpad(p.Pc, aln, c.ctxt)
-                       if v > 0 {
-                               for i := 0; i < 6; i++ {
-                                       out[i] = uint32(0)
-                               }
-                               o.size = int8(v)
-                               out[0] = LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
-                               return
-                       }
-                       o.size = 0
-               }
                break
 
        case 1: /* mov r1,r2 ==> OR Rs,Rs,Ra */
diff --git a/src/cmd/internal/obj/ppc64/asm_test.go b/src/cmd/internal/obj/ppc64/asm_test.go
new file mode 100644 (file)
index 0000000..fff478e
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright 2020 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 ppc64
+
+import (
+       "internal/testenv"
+       "io/ioutil"
+       "os"
+       "os/exec"
+       "path/filepath"
+       "strings"
+       "testing"
+)
+
+var invalidPCAlignSrc = `
+TEXT test(SB),0,$0-0
+ADD $2, R3
+PCALIGN $32
+RET
+`
+var validPCAlignSrc = `
+TEXT test(SB),0,$0-0
+ADD $2, R3
+PCALIGN $16
+MOVD $8, R4
+ADD $8, R4
+PCALIGN $16
+ADD $8, R4
+PCALIGN $8
+ADD $4, R6
+PCALIGN $16
+ADD R2, R3, R4
+RET
+`
+
+// TestPCalign generates two asm files containing the
+// PCALIGN directive, to verify correct values are and
+// accepted, and incorrect values are flagged in error.
+func TestPCalign(t *testing.T) {
+       testenv.MustHaveGoBuild(t)
+
+       dir, err := ioutil.TempDir("", "testpcalign")
+       if err != nil {
+               t.Fatalf("could not create directory: %v", err)
+       }
+       defer os.RemoveAll(dir)
+
+       // generate a test with valid uses of PCALIGN
+
+       tmpfile := filepath.Join(dir, "x.s")
+       err = ioutil.WriteFile(tmpfile, []byte(validPCAlignSrc), 0644)
+       if err != nil {
+               t.Fatalf("can't write output: %v\n", err)
+       }
+
+       // build generated file without errors and assemble it
+       cmd := exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "x.o"), "-S", tmpfile)
+       cmd.Env = append(os.Environ(), "GOARCH=ppc64le", "GOOS=linux")
+       out, err := cmd.CombinedOutput()
+       if err != nil {
+               t.Errorf("Build failed: %v, output: %s", err, out)
+       }
+
+       // generate a test with invalid use of PCALIGN
+
+       tmpfile = filepath.Join(dir, "xi.s")
+       err = ioutil.WriteFile(tmpfile, []byte(invalidPCAlignSrc), 0644)
+       if err != nil {
+               t.Fatalf("can't write output: %v\n", err)
+       }
+
+       // build test with errors and check for messages
+       cmd = exec.Command(testenv.GoToolPath(t), "tool", "asm", "-o", filepath.Join(dir, "xi.o"), "-S", tmpfile)
+       cmd.Env = append(os.Environ(), "GOARCH=ppc64le", "GOOS=linux")
+       out, err = cmd.CombinedOutput()
+       if !strings.Contains(string(out), "Unexpected alignment") {
+               t.Errorf("Invalid alignment not detected for PCALIGN\n")
+       }
+}