diff options
| author | Austin Clements <austin@google.com> | 2021-04-02 17:20:15 -0400 |
|---|---|---|
| committer | Austin Clements <austin@google.com> | 2021-04-05 16:22:14 +0000 |
| commit | 2b63404ddb04abec5279f0fa574cc06dcef242cf (patch) | |
| tree | 4425912027cdd88a12cb3c97f0f02b68b6c67d83 /src/cmd/internal/obj/mips/obj0.go | |
| parent | 4702dd67a7dcf1eac2309218807287bcd48d4e09 (diff) | |
| download | go-2b63404ddb04abec5279f0fa574cc06dcef242cf.tar.xz | |
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>
Diffstat (limited to 'src/cmd/internal/obj/mips/obj0.go')
| -rw-r--r-- | src/cmd/internal/obj/mips/obj0.go | 98 |
1 files changed, 32 insertions, 66 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,82 +689,50 @@ 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 { + } else { // 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 + 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_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 = 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 p.From.Reg = REG_R2 |
