aboutsummaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorAustin Clements <austin@google.com>2021-04-02 17:20:15 -0400
committerAustin Clements <austin@google.com>2021-04-05 16:22:14 +0000
commit2b63404ddb04abec5279f0fa574cc06dcef242cf (patch)
tree4425912027cdd88a12cb3c97f0f02b68b6c67d83 /src/cmd
parent4702dd67a7dcf1eac2309218807287bcd48d4e09 (diff)
downloadgo-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')
-rw-r--r--src/cmd/internal/obj/mips/obj0.go98
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