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:
parent
191118a821
commit
60a964ea45
@ -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 */
|
||||
|
81
src/cmd/internal/obj/ppc64/asm_test.go
Normal file
81
src/cmd/internal/obj/ppc64/asm_test.go
Normal 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")
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user