1
0
mirror of https://github.com/golang/go synced 2024-11-17 06:04:47 -07:00

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 <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>
This commit is contained in:
Lynn Boger 2020-03-17 09:24:47 -04:00
parent 191118a821
commit 60a964ea45
2 changed files with 93 additions and 22 deletions

View 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 */

View File

@ -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")
}
}