]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/internal/obj/mips: support NOFRAME
authorAustin Clements <austin@google.com>
Wed, 24 Jan 2018 22:17:38 +0000 (17:17 -0500)
committerAustin Clements <austin@google.com>
Mon, 12 Feb 2018 21:41:27 +0000 (21:41 +0000)
This passes toolstash -cmp with one exception: assembly functions that
were declared with a frame size of -4 (or -8) used to record
locals=0xfffffffffffffffc in the object file and now record
locals=0x0. This doesn't affect anything.

Change-Id: I0d15e81770e54222ae329ce4496da06016736771
Reviewed-on: https://go-review.googlesource.com/92041
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
src/cmd/internal/obj/mips/obj0.go

index ae9d1282a4accf5a3137094e259844b17d25b2a8..477f5531cc0da5cb0ef42f887e762292594a7658 100644 (file)
@@ -139,6 +139,19 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 
        p := c.cursym.Func.Text
        textstksiz := p.To.Offset
+       if textstksiz == -ctxt.FixedFrameSize() {
+               // 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)
@@ -278,15 +291,42 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                o := p.As
                switch o {
                case obj.ATEXT:
-                       autosize = int32(textstksiz + ctxt.FixedFrameSize())
-                       if (p.Mark&LEAF != 0) && autosize <= int32(ctxt.FixedFrameSize()) {
-                               autosize = 0
-                       } else if autosize&4 != 0 && c.ctxt.Arch.Family == sys.MIPS64 {
+                       autosize = int32(textstksiz)
+
+                       if p.Mark&LEAF != 0 && autosize == 0 {
+                               // A leaf function with no locals has no frame.
+                               p.From.Sym.Set(obj.AttrNoFrame, true)
+                       }
+
+                       if !p.From.Sym.NoFrame() {
+                               // If there is a stack frame at all, it includes
+                               // space to save the LR.
+                               autosize += int32(c.ctxt.FixedFrameSize())
+                       }
+
+                       if autosize&4 != 0 && c.ctxt.Arch.Family == sys.MIPS64 {
                                autosize += 4
                        }
 
+                       if autosize == 0 && c.cursym.Func.Text.Mark&LEAF == 0 {
+                               if c.cursym.Func.Text.From.Sym.NoSplit() {
+                                       if ctxt.Debugvlog {
+                                               ctxt.Logf("save suppressed in: %s\n", c.cursym.Name)
+                                       }
+
+                                       c.cursym.Func.Text.Mark |= LEAF
+                               }
+                       }
+
                        p.To.Offset = int64(autosize) - ctxt.FixedFrameSize()
 
+                       if c.cursym.Func.Text.Mark&LEAF != 0 {
+                               c.cursym.Set(obj.AttrLeaf, true)
+                               if p.From.Sym.NoFrame() {
+                                       break
+                               }
+                       }
+
                        if !p.From.Sym.NoSplit() {
                                p = c.stacksplit(p, autosize) // emit split check
                        }
@@ -316,22 +356,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                q.To.Type = obj.TYPE_REG
                                q.To.Reg = REGSP
                                q.Spadj = +autosize
-                       } else if c.cursym.Func.Text.Mark&LEAF == 0 {
-                               if c.cursym.Func.Text.From.Sym.NoSplit() {
-                                       if ctxt.Debugvlog {
-                                               ctxt.Logf("save suppressed in: %s\n", c.cursym.Name)
-                                       }
-
-                                       c.cursym.Func.Text.Mark |= LEAF
-                               }
                        }
 
-                       if c.cursym.Func.Text.Mark&LEAF != 0 {
-                               c.cursym.Set(obj.AttrLeaf, true)
-                               break
-                       }
-
-                       if c.cursym.Func.Text.From.Sym.Wrapper() {
+                       if c.cursym.Func.Text.From.Sym.Wrapper() && c.cursym.Func.Text.Mark&LEAF == 0 {
                                // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
                                //
                                //      MOV     g_panic(g), R1
@@ -346,6 +373,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
                                //
                                // The NOP is needed to give the jumps somewhere to land.
                                // It is a liblink NOP, not an mips NOP: it encodes to 0 instruction bytes.
+                               //
+                               // We don't generate this for leafs because that means the wrapped
+                               // function was inlined into the wrapper.
 
                                q = obj.Appendp(q, newprog)
 
@@ -604,11 +634,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
 }
 
 func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
-       // Leaf function with no frame is effectively NOSPLIT.
-       if framesize == 0 {
-               return p
-       }
-
        var mov, add, sub obj.As
 
        if c.ctxt.Arch.Family == sys.MIPS64 {