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)
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
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
}
}
p = c.stacksplit(p, c.autosize) // emit split check
}
- aoffset = c.autosize
+ aoffset := c.autosize
if aoffset > 0xF0 {
aoffset = 0xF0
}
}
} else {
/* want write-back pre-indexed SP+autosize -> SP, loading REGLINK*/
- aoffset = c.autosize
+ aoffset := c.autosize
if aoffset > 0xF0 {
aoffset = 0xF0