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:
parent
99e37e98b4
commit
75b56a0895
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user