var xcmp [C_NCLASS][C_NCLASS]bool
// 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 {
case 8:
if pc&7 != 0 {
case 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:
ctxt.Diag("Unexpected alignment: %d for PCALIGN directive\n", a)
}
if m == 0 {
if p.As == obj.APCALIGN {
a := c.vregoff(&p.From)
- m = addpad(pc, a, ctxt)
+ m = addpad(pc, a, ctxt, cursym)
} else {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p)
if m == 0 {
if p.As == obj.APCALIGN {
a := c.vregoff(&p.From)
- m = addpad(pc, a, ctxt)
+ m = addpad(pc, a, ctxt, cursym)
} else {
if p.As != obj.ANOP && p.As != obj.AFUNCDATA && p.As != obj.APCDATA {
ctxt.Diag("zero-width instruction\n%v", p)
c.cursym.Size = pc
}
- if r := pc & funcAlignMask; r != 0 {
- pc += funcAlign - r
- }
-
c.cursym.Size = pc
/*
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)
+ v := addpad(p.Pc, aln, c.ctxt, c.cursym)
if v > 0 {
// Same padding instruction for all
for i = 0; i < int32(v/4); i++ {
"os"
"os/exec"
"path/filepath"
+ "regexp"
"strings"
"testing"
)
var invalidPCAlignSrc = `
TEXT test(SB),0,$0-0
ADD $2, R3
-PCALIGN $32
+PCALIGN $64
RET
`
+
var validPCAlignSrc = `
TEXT test(SB),0,$0-0
ADD $2, R3
PCALIGN $16
-MOVD $8, R4
-ADD $8, R4
-PCALIGN $16
+MOVD $8, R16
ADD $8, R4
+PCALIGN $32
+ADD $8, R3
PCALIGN $8
-ADD $4, R6
-PCALIGN $16
-ADD R2, R3, R4
+ADD $4, R8
RET
`
// PCALIGN directive, to verify correct values are and
// accepted, and incorrect values are flagged in error.
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)
dir, err := ioutil.TempDir("", "testpcalign")
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
tmpfile = filepath.Join(dir, "xi.s")