1
0
mirror of https://github.com/golang/go synced 2024-11-26 07:38:00 -07:00

cmd/internal/obj/mips: simplify huge frame prologue

CL 307010 for mips.

Change-Id: Ie9addea728548315fdbb8e46f75da4010a9796bb
Reviewed-on: https://go-review.googlesource.com/c/go/+/307051
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Austin Clements 2021-04-02 17:20:15 -04:00
parent 4702dd67a7
commit 2b63404ddb

View File

@ -648,16 +648,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
} }
func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
var mov, add, sub obj.As var mov, add obj.As
if c.ctxt.Arch.Family == sys.MIPS64 { if c.ctxt.Arch.Family == sys.MIPS64 {
add = AADDV add = AADDV
mov = AMOVV mov = AMOVV
sub = ASUBVU
} else { } else {
add = AADDU add = AADDU
mov = AMOVW mov = AMOVW
sub = ASUBU
} }
// MOV g_stackguard(g), R1 // MOV g_stackguard(g), R1
@ -691,81 +689,49 @@ func (c *ctxt0) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.Reg = REG_R1 p.Reg = REG_R1
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1 p.To.Reg = REG_R1
} else if framesize <= objabi.StackBig { } else {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
offset := int64(framesize) - objabi.StackSmall
if framesize > objabi.StackBig {
// Such a large stack we need to protect against underflow.
// The runtime guarantees SP > objabi.StackBig, but
// framesize is large enough that SP-framesize may
// underflow, causing a direct comparison with the
// stack guard to incorrectly succeed. We explicitly
// guard against underflow.
//
// SGTU $(framesize-StackSmall), SP, R2
// BNE R2, label-of-call-to-morestack
p = obj.Appendp(p, c.newprog)
p.As = ASGTU
p.From.Type = obj.TYPE_CONST
p.From.Offset = offset
p.Reg = REGSP
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p = obj.Appendp(p, c.newprog)
q = p
p.As = ABNE
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R2
p.To.Type = obj.TYPE_BRANCH
p.Mark |= BRANCH
}
// Check against the stack guard. We've ensured this won't underflow.
// ADD $-(framesize-StackSmall), SP, R2 // ADD $-(framesize-StackSmall), SP, R2
// SGTU R2, stackguard, R1 // SGTU R2, stackguard, R1
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = add p.As = add
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = -(int64(framesize) - objabi.StackSmall) p.From.Offset = -offset
p.Reg = REGSP p.Reg = REGSP
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REG_R2
p = obj.Appendp(p, c.newprog)
p.As = ASGTU
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R2
p.Reg = REG_R1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
} else {
// Such a large stack we need to protect against wraparound.
// If SP is close to zero:
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
// The +StackGuard on both sides is required to keep the left side positive:
// SP is allowed to be slightly below stackguard. See stack.h.
//
// Preemption sets stackguard to StackPreempt, a very large value.
// That breaks the math above, so we have to check for that explicitly.
// // stackguard is R1
// MOV $StackPreempt, R2
// BEQ R1, R2, label-of-call-to-morestack
// ADD $StackGuard, SP, R2
// SUB R1, R2
// MOV $(framesize+(StackGuard-StackSmall)), R1
// SGTU R2, R1, R1
p = obj.Appendp(p, c.newprog)
p.As = mov
p.From.Type = obj.TYPE_CONST
p.From.Offset = objabi.StackPreempt
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p = obj.Appendp(p, c.newprog)
q = p
p.As = ABEQ
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.Reg = REG_R2
p.To.Type = obj.TYPE_BRANCH
p.Mark |= BRANCH
p = obj.Appendp(p, c.newprog)
p.As = add
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(objabi.StackGuard)
p.Reg = REGSP
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p = obj.Appendp(p, c.newprog)
p.As = sub
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2
p = obj.Appendp(p, c.newprog)
p.As = mov
p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(framesize) + int64(objabi.StackGuard) - objabi.StackSmall
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = ASGTU p.As = ASGTU
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG