1
0
mirror of https://github.com/golang/go synced 2024-11-19 21:14:43 -07:00

cmd/internal/obj/arm64: support NOFRAME

In addition, this makes the arm64 prologue code generation much closer
to the pattern used on other platforms.

This passes toolstash -cmp with one exception: assembly functions that
were declared with a frame size of -8 used to record
locals=0xfffffffffffffff8 in the object file and now record
locals=0x0. This doesn't affect anything.

Change-Id: I0d15e81770e54222ae329ce4496da06016736770
Reviewed-on: https://go-review.googlesource.com/92040
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Austin Clements 2018-01-24 17:17:38 -05:00
parent 99e37e98b4
commit 75b56a0895

View File

@ -443,7 +443,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p := c.cursym.Func.Text
textstksiz := p.To.Offset
aoffset := int32(textstksiz)
if textstksiz == -8 {
// Historical way to mark NOFRAME.
p.From.Sym.Set(obj.AttrNoFrame, true)
textstksiz = 0
}
if textstksiz < 0 {
c.ctxt.Diag("negative frame size %d - did you mean NOFRAME?", textstksiz)
}
if p.From.Sym.NoFrame() {
if textstksiz != 0 {
c.ctxt.Diag("NOFRAME functions must have a frame size of 0, not %d", textstksiz)
}
}
c.cursym.Func.Args = p.To.Val.(int32)
c.cursym.Func.Locals = int32(textstksiz)
@ -521,14 +533,20 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
switch o {
case obj.ATEXT:
c.cursym.Func.Text = p
if textstksiz < 0 {
c.autosize = 0
} else {
c.autosize = int32(textstksiz + 8)
c.autosize = int32(textstksiz)
if p.Mark&LEAF != 0 && c.autosize == 0 {
// A leaf function with no locals has no frame.
p.From.Sym.Set(obj.AttrNoFrame, true)
}
if (c.cursym.Func.Text.Mark&LEAF != 0) && c.autosize <= 8 {
c.autosize = 0
} else if c.autosize&(16-1) != 0 {
if !p.From.Sym.NoFrame() {
// If there is a stack frame at all, it includes
// space to save the LR.
c.autosize += 8
}
if c.autosize != 0 && c.autosize&(16-1) != 0 {
// The frame includes an LR.
// If the frame size is 8, it's only an LR,
// so there's no potential for breaking references to
@ -544,17 +562,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
c.ctxt.Diag("%v: unaligned frame size %d - must be 8 mod 16 (or 0)", p, c.autosize-8)
}
}
p.To.Offset = int64(c.autosize) - 8
if c.autosize == 0 && !(c.cursym.Func.Text.Mark&LEAF != 0) {
if c.autosize == 0 && c.cursym.Func.Text.Mark&LEAF == 0 {
if c.ctxt.Debugvlog {
c.ctxt.Logf("save suppressed in: %s\n", c.cursym.Func.Text.From.Sym.Name)
}
c.cursym.Func.Text.Mark |= LEAF
}
if c.cursym.Func.Text.Mark&LEAF != 0 {
c.cursym.Set(obj.AttrLeaf, true)
if c.autosize == 0 {
// FP offsets need an updated p.To.Offset.
p.To.Offset = int64(c.autosize) - 8
if cursym.Func.Text.Mark&LEAF != 0 {
cursym.Set(obj.AttrLeaf, true)
if p.From.Sym.NoFrame() {
break
}
}
@ -563,7 +583,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
p = c.stacksplit(p, c.autosize) // emit split check
}
aoffset = c.autosize
aoffset := c.autosize
if aoffset > 0xF0 {
aoffset = 0xF0
}
@ -740,7 +760,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
}
} else {
/* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
aoffset = c.autosize
aoffset := c.autosize
if aoffset > 0xF0 {
aoffset = 0xF0