From: Austin Clements Date: Fri, 2 Apr 2021 21:20:15 +0000 (-0400) Subject: cmd/internal/obj/riscv: simplify huge frame prologue X-Git-Tag: go1.17beta1~851 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=042f4cbb6f;p=gostls13.git cmd/internal/obj/riscv: simplify huge frame prologue CL 307010 for riscv64. Some of the comments on the other prologue paths were wrong, so this CL also fixes them up. Change-Id: Icdca1ade3a47ae6e2467af832690d40689dbe1b6 Reviewed-on: https://go-review.googlesource.com/c/go/+/307150 Trust: Austin Clements Run-TryBot: Austin Clements Reviewed-by: Cherry Zhang --- diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index ee6fb0909b..a305edab4b 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -984,8 +984,9 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA var to_done, to_more *obj.Prog if framesize <= objabi.StackSmall { - // small stack: SP < stackguard - // BLTU SP, stackguard, done + // small stack + // // if SP > stackguard { goto done } + // BLTU stackguard, SP, done p = obj.Appendp(p, newprog) p.As = ABLTU p.From.Type = obj.TYPE_REG @@ -993,80 +994,48 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA p.Reg = REG_SP p.To.Type = obj.TYPE_BRANCH to_done = p - } else if framesize <= objabi.StackBig { + } else { // large stack: SP-framesize < stackguard-StackSmall - // ADD $-(framesize-StackSmall), SP, X11 - // BLTU X11, stackguard, done - p = obj.Appendp(p, newprog) - // TODO(sorear): logic inconsistent with comment, but both match all non-x86 arches - p.As = AADDI - p.From.Type = obj.TYPE_CONST - p.From.Offset = -(int64(framesize) - objabi.StackSmall) - p.Reg = REG_SP - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_X11 + 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. + // + // MOV $(framesize-StackSmall), X11 + // BLTU SP, X11, label-of-call-to-morestack - p = obj.Appendp(p, newprog) - p.As = ABLTU - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_X10 - p.Reg = REG_X11 - p.To.Type = obj.TYPE_BRANCH - to_done = p - } 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 X10 - // MOV $StackPreempt, X11 - // BEQ X10, X11, more - // ADD $StackGuard, SP, X11 - // SUB X10, X11 - // MOV $(framesize+(StackGuard-StackSmall)), X10 - // BGTU X11, X10, done - p = obj.Appendp(p, newprog) - p.As = AMOV - p.From.Type = obj.TYPE_CONST - p.From.Offset = objabi.StackPreempt - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_X11 + p = obj.Appendp(p, newprog) + p.As = AMOV + p.From.Type = obj.TYPE_CONST + p.From.Offset = offset + p.To.Type = obj.TYPE_REG + p.To.Reg = REG_X11 - p = obj.Appendp(p, newprog) - to_more = p - p.As = ABEQ - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_X10 - p.Reg = REG_X11 - p.To.Type = obj.TYPE_BRANCH + p = obj.Appendp(p, newprog) + p.As = ABLTU + p.From.Type = obj.TYPE_REG + p.From.Reg = REG_SP + p.Reg = REG_X11 + p.To.Type = obj.TYPE_BRANCH + to_more = p + } + // Check against the stack guard. We've ensured this won't underflow. + // ADD $-(framesize-StackSmall), SP, X11 + // // if X11 > stackguard { goto done } + // BLTU stackguard, X11, done p = obj.Appendp(p, newprog) p.As = AADDI p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(objabi.StackGuard) + p.From.Offset = -offset p.Reg = REG_SP p.To.Type = obj.TYPE_REG p.To.Reg = REG_X11 - p = obj.Appendp(p, newprog) - p.As = ASUB - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_X10 - p.Reg = REG_X11 - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_X11 - - p = obj.Appendp(p, newprog) - p.As = AMOV - 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_X10 - p = obj.Appendp(p, newprog) p.As = ABLTU p.From.Type = obj.TYPE_REG