From 24dd8cfe23b2ffc0641611dd6299c037cb459807 Mon Sep 17 00:00:00 2001 From: Austin Clements Date: Fri, 2 Apr 2021 16:59:22 -0400 Subject: [PATCH] cmd/internal/obj/arm: simplify huge frame prologue CL 307010 for arm. Change-Id: I14d939eb8aa6f594927054a2595f8c270a0b607f Reviewed-on: https://go-review.googlesource.com/c/go/+/307049 Trust: Austin Clements Run-TryBot: Austin Clements TryBot-Result: Go Bot Reviewed-by: Cherry Zhang --- src/cmd/internal/obj/arm/a.out.go | 4 +-- src/cmd/internal/obj/arm/obj5.go | 58 ++++++++++--------------------- 2 files changed, 21 insertions(+), 41 deletions(-) diff --git a/src/cmd/internal/obj/arm/a.out.go b/src/cmd/internal/obj/arm/a.out.go index a1d9e28b96..fd695ad0c9 100644 --- a/src/cmd/internal/obj/arm/a.out.go +++ b/src/cmd/internal/obj/arm/a.out.go @@ -163,8 +163,8 @@ const ( C_SFCON C_LFCON - C_RACON - C_LACON + C_RACON /* <=0xff rotated constant offset from auto */ + C_LACON /* Large Auto CONstant, i.e. large offset from SP */ C_SBRA C_LBRA diff --git a/src/cmd/internal/obj/arm/obj5.go b/src/cmd/internal/obj/arm/obj5.go index 7de04302d9..edb384806b 100644 --- a/src/cmd/internal/obj/arm/obj5.go +++ b/src/cmd/internal/obj/arm/obj5.go @@ -680,57 +680,37 @@ func (c *ctxt5) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { p.From.Reg = REG_R1 p.Reg = REG_R2 } 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. - // CMP $StackPreempt, R1 - // MOVW.NE $StackGuard(SP), R2 - // SUB.NE R1, R2 - // MOVW.NE $(framesize+(StackGuard-StackSmall)), R3 - // CMP.NE R3, R2 - p = obj.Appendp(p, c.newprog) - - p.As = ACMP - p.From.Type = obj.TYPE_CONST - p.From.Offset = int64(uint32(objabi.StackPreempt & (1<<32 - 1))) - p.Reg = REG_R1 - - p = obj.Appendp(p, c.newprog) - p.As = AMOVW - p.From.Type = obj.TYPE_ADDR - p.From.Reg = REGSP - p.From.Offset = int64(objabi.StackGuard) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R2 - p.Scond = C_SCOND_NE + // 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. + // + // // Try subtracting from SP and check for underflow. + // // If this underflows, it sets C to 0. + // SUB.S $(framesize-StackSmall), SP, R2 + // // If C is 1 (unsigned >=), compare with guard. + // CMP.HS stackguard, R2 p = obj.Appendp(p, c.newprog) p.As = ASUB - p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R1 + p.Scond = C_SBIT + 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.Scond = C_SCOND_NE - - p = obj.Appendp(p, c.newprog) - p.As = AMOVW - p.From.Type = obj.TYPE_ADDR - p.From.Offset = int64(framesize) + (int64(objabi.StackGuard) - objabi.StackSmall) - p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R3 - p.Scond = C_SCOND_NE p = obj.Appendp(p, c.newprog) p.As = ACMP + p.Scond = C_SCOND_HS p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 + p.From.Reg = REG_R1 p.Reg = REG_R2 - p.Scond = C_SCOND_NE } - // BLS call-to-morestack + // BLS call-to-morestack (C is 0 or Z is 1) bls := obj.Appendp(p, c.newprog) bls.As = ABLS bls.To.Type = obj.TYPE_BRANCH