From 2b63404ddb04abec5279f0fa574cc06dcef242cf Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 2 Apr 2021 17:20:15 -0400 Subject: [PATCH] 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 Run-TryBot: Austin Clements TryBot-Result: Go Bot Reviewed-by: Cherry Zhang --- src/cmd/internal/obj/mips/obj0.go | 100 ++++++++++-------------------- 1 file changed, 33 insertions(+), 67 deletions(-) diff --git a/src/cmd/internal/obj/mips/obj0.go b/src/cmd/internal/obj/mips/obj0.go index 91bba90d41..1f31d0c4cd 100644 --- a/src/cmd/internal/obj/mips/obj0.go +++ b/src/cmd/internal/obj/mips/obj0.go @@ -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 { - var mov, add, sub obj.As + var mov, add obj.As if c.ctxt.Arch.Family == sys.MIPS64 { add = AADDV mov = AMOVV - sub = ASUBVU } else { add = AADDU mov = AMOVW - sub = ASUBU } // 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.To.Type = obj.TYPE_REG p.To.Reg = REG_R1 - } else if framesize <= objabi.StackBig { - // large stack: SP-framesize < stackguard-StackSmall - // ADD $-(framesize-StackSmall), SP, R2 - // SGTU R2, stackguard, R1 - p = obj.Appendp(p, c.newprog) - - p.As = add - p.From.Type = obj.TYPE_CONST - p.From.Offset = -(int64(framesize) - objabi.StackSmall) - p.Reg = REGSP - p.To.Type = obj.TYPE_REG - 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) + // 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.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 = 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 + // SGTU R2, stackguard, R1 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.From.Offset = -offset 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.As = ASGTU p.From.Type = obj.TYPE_REG -- 2.48.1