mirror of https://github.com/golang/go.git
cmd/internal/obj/ppc64: add support for pcalign 32 on ppc64x
Previous PCALIGN support on ppc64x only accepted 8 and 16 byte alignment since the default function alignment was 16. Now that the function's alignment can be set to a larger value when needed, PCALIGN can accept 32. When this happens then the function's alignment will be changed to 32. Test has been updated to recognized this new value. Change-Id: If82c3cd50d7c686fcf8a9e819708b15660cdfa63 Reviewed-on: https://go-review.googlesource.com/c/go/+/227775 Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
162f1bf7c2
commit
37470c0664
|
|
@ -620,7 +620,7 @@ var oprange [ALAST & obj.AMask][]Optab
|
||||||
var xcmp [C_NCLASS][C_NCLASS]bool
|
var xcmp [C_NCLASS][C_NCLASS]bool
|
||||||
|
|
||||||
// padding bytes to add to align code as requested
|
// padding bytes to add to align code as requested
|
||||||
func addpad(pc, a int64, ctxt *obj.Link) int {
|
func addpad(pc, a int64, ctxt *obj.Link, cursym *obj.LSym) int {
|
||||||
switch a {
|
switch a {
|
||||||
case 8:
|
case 8:
|
||||||
if pc&7 != 0 {
|
if pc&7 != 0 {
|
||||||
|
|
@ -633,6 +633,21 @@ func addpad(pc, a int64, ctxt *obj.Link) int {
|
||||||
case 8:
|
case 8:
|
||||||
return 8
|
return 8
|
||||||
}
|
}
|
||||||
|
case 32:
|
||||||
|
switch pc & 31 {
|
||||||
|
case 4, 20:
|
||||||
|
return 12
|
||||||
|
case 8, 24:
|
||||||
|
return 8
|
||||||
|
case 12, 28:
|
||||||
|
return 4
|
||||||
|
}
|
||||||
|
// The default function alignment is 16, but
|
||||||
|
// if 32 byte alignment is requested then the
|
||||||
|
// function needs to be aligned to 32.
|
||||||
|
if cursym.Func.Align < 32 {
|
||||||
|
cursym.Func.Align = 32
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
|
ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
|
||||||
}
|
}
|
||||||
|
|
@ -663,7 +678,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
if m == 0 {
|
if m == 0 {
|
||||||
if p.As == obj.APCALIGN {
|
if p.As == obj.APCALIGN {
|
||||||
a := c.vregoff(&p.From)
|
a := c.vregoff(&p.From)
|
||||||
m = addpad(pc, a, ctxt)
|
m = addpad(pc, a, ctxt, cursym)
|
||||||
} else {
|
} else {
|
||||||
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
|
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
|
||||||
ctxt.Diag("zero-width instruction\n%v", p)
|
ctxt.Diag("zero-width instruction\n%v", p)
|
||||||
|
|
@ -721,7 +736,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
if m == 0 {
|
if m == 0 {
|
||||||
if p.As == obj.APCALIGN {
|
if p.As == obj.APCALIGN {
|
||||||
a := c.vregoff(&p.From)
|
a := c.vregoff(&p.From)
|
||||||
m = addpad(pc, a, ctxt)
|
m = addpad(pc, a, ctxt, cursym)
|
||||||
} else {
|
} else {
|
||||||
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
|
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
|
||||||
ctxt.Diag("zero-width instruction\n%v", p)
|
ctxt.Diag("zero-width instruction\n%v", p)
|
||||||
|
|
@ -736,10 +751,6 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
c.cursym.Size = pc
|
c.cursym.Size = pc
|
||||||
}
|
}
|
||||||
|
|
||||||
if r := pc & funcAlignMask; r != 0 {
|
|
||||||
pc += funcAlign - r
|
|
||||||
}
|
|
||||||
|
|
||||||
c.cursym.Size = pc
|
c.cursym.Size = pc
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -761,7 +772,7 @@ func span9(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
if o.type_ == 0 && p.As == obj.APCALIGN {
|
if o.type_ == 0 && p.As == obj.APCALIGN {
|
||||||
pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
|
pad := LOP_RRR(OP_OR, REGZERO, REGZERO, REGZERO)
|
||||||
aln := c.vregoff(&p.From)
|
aln := c.vregoff(&p.From)
|
||||||
v := addpad(p.Pc, aln, c.ctxt)
|
v := addpad(p.Pc, aln, c.ctxt, c.cursym)
|
||||||
if v > 0 {
|
if v > 0 {
|
||||||
// Same padding instruction for all
|
// Same padding instruction for all
|
||||||
for i = 0; i < int32(v/4); i++ {
|
for i = 0; i < int32(v/4); i++ {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
@ -17,21 +18,20 @@ import (
|
||||||
var invalidPCAlignSrc = `
|
var invalidPCAlignSrc = `
|
||||||
TEXT test(SB),0,$0-0
|
TEXT test(SB),0,$0-0
|
||||||
ADD $2, R3
|
ADD $2, R3
|
||||||
PCALIGN $32
|
PCALIGN $64
|
||||||
RET
|
RET
|
||||||
`
|
`
|
||||||
|
|
||||||
var validPCAlignSrc = `
|
var validPCAlignSrc = `
|
||||||
TEXT test(SB),0,$0-0
|
TEXT test(SB),0,$0-0
|
||||||
ADD $2, R3
|
ADD $2, R3
|
||||||
PCALIGN $16
|
PCALIGN $16
|
||||||
MOVD $8, R4
|
MOVD $8, R16
|
||||||
ADD $8, R4
|
|
||||||
PCALIGN $16
|
|
||||||
ADD $8, R4
|
ADD $8, R4
|
||||||
|
PCALIGN $32
|
||||||
|
ADD $8, R3
|
||||||
PCALIGN $8
|
PCALIGN $8
|
||||||
ADD $4, R6
|
ADD $4, R8
|
||||||
PCALIGN $16
|
|
||||||
ADD R2, R3, R4
|
|
||||||
RET
|
RET
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
@ -39,6 +39,10 @@ RET
|
||||||
// PCALIGN directive, to verify correct values are and
|
// PCALIGN directive, to verify correct values are and
|
||||||
// accepted, and incorrect values are flagged in error.
|
// accepted, and incorrect values are flagged in error.
|
||||||
func TestPCalign(t *testing.T) {
|
func TestPCalign(t *testing.T) {
|
||||||
|
var pattern8 = `0x...8\s.*ADD\s..,\sR8`
|
||||||
|
var pattern16 = `0x...[80]\s.*MOVD\s..,\sR16`
|
||||||
|
var pattern32 = `0x...0\s.*ADD\s..,\sR3`
|
||||||
|
|
||||||
testenv.MustHaveGoBuild(t)
|
testenv.MustHaveGoBuild(t)
|
||||||
|
|
||||||
dir, err := ioutil.TempDir("", "testpcalign")
|
dir, err := ioutil.TempDir("", "testpcalign")
|
||||||
|
|
@ -63,6 +67,30 @@ func TestPCalign(t *testing.T) {
|
||||||
t.Errorf("Build failed: %v, output: %s", err, out)
|
t.Errorf("Build failed: %v, output: %s", err, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
matched, err := regexp.MatchString(pattern8, string(out))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
t.Errorf("The 8 byte alignment is not correct: %t, output:%s\n", matched, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
matched, err = regexp.MatchString(pattern16, string(out))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
t.Errorf("The 16 byte alignment is not correct: %t, output:%s\n", matched, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
matched, err = regexp.MatchString(pattern32, string(out))
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
t.Errorf("The 32 byte alignment is not correct: %t, output:%s\n", matched, out)
|
||||||
|
}
|
||||||
|
|
||||||
// generate a test with invalid use of PCALIGN
|
// generate a test with invalid use of PCALIGN
|
||||||
|
|
||||||
tmpfile = filepath.Join(dir, "xi.s")
|
tmpfile = filepath.Join(dir, "xi.s")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue