mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/internal/obj/mips: support NOFRAME
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>
This commit is contained in:
parent
75b56a0895
commit
e940358fc9
1 changed files with 48 additions and 23 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue