From: Lynn Boger Date: Tue, 17 Mar 2020 13:24:47 +0000 (-0400) Subject: cmd/internal/obj/ppc64: fix PCALIGN on ppc64le X-Git-Tag: go1.15beta1~766 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=60a964ea45db28eb7a4ca291008473da7d3d2c70;p=gostls13.git cmd/internal/obj/ppc64: fix PCALIGN on ppc64le 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 Reviewed-by: Cherry Zhang Reviewed-by: Carlos Eduardo Seo TryBot-Result: Gobot Gobot --- diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index b62eda8b14..90bee3d9b6 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -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 index 0000000000..fff478e552 --- /dev/null +++ b/src/cmd/internal/obj/ppc64/asm_test.go @@ -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") + } +}