1
0
mirror of https://github.com/golang/go synced 2024-11-26 06:38:00 -07:00

cmd/internal/obj/ppc64: simplify huge frame prologue

CL 307010 for ppc64.

I spent a long time trying to figure out how to use the carry bit from
ADDCCC to further simplify this (like what we do on arm64), but gave
up after I couldn't figure out how to access the carry bit without
just adding more instructions.

Change-Id: I6cad51b93616865b203cb16554f16121375aabbc
Reviewed-on: https://go-review.googlesource.com/c/go/+/307149
Trust: Austin Clements <austin@google.com>
Run-TryBot: Austin Clements <austin@google.com>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
Austin Clements 2021-04-02 17:20:15 -04:00
parent 2b63404ddb
commit a06b08e7d1

View File

@ -1081,80 +1081,65 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.From.Reg = REG_R3 p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP p.To.Reg = REGSP
} else if framesize <= objabi.StackBig {
// large stack: SP-framesize < stackguard-StackSmall
// ADD $-(framesize-StackSmall), SP, R4
// CMP stackguard, R4
p = obj.Appendp(p, c.newprog)
p.As = AADD
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_R4
p = obj.Appendp(p, c.newprog)
p.As = ACMPU
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
} else { } else {
// Such a large stack we need to protect against wraparound. // large stack: SP-framesize < stackguard-StackSmall
// If SP is close to zero: offset := int64(framesize) - objabi.StackSmall
// SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall) if framesize > objabi.StackBig {
// The +StackGuard on both sides is required to keep the left side positive: // Such a large stack we need to protect against underflow.
// SP is allowed to be slightly below stackguard. See stack.h. // The runtime guarantees SP > objabi.StackBig, but
// // framesize is large enough that SP-framesize may
// Preemption sets stackguard to StackPreempt, a very large value. // underflow, causing a direct comparison with the
// That breaks the math above, so we have to check for that explicitly. // stack guard to incorrectly succeed. We explicitly
// // stackguard is R3 // guard against underflow.
// CMP R3, $StackPreempt //
// BEQ label-of-call-to-morestack // CMPU SP, $(framesize-StackSmall)
// ADD $StackGuard, SP, R4 // BLT label-of-call-to-morestack
// SUB R3, R4 if offset <= 0xffff {
// MOVD $(framesize+(StackGuard-StackSmall)), R31 p = obj.Appendp(p, c.newprog)
// CMPU R31, R4 p.As = ACMPU
p.From.Type = obj.TYPE_REG
p.From.Reg = REGSP
p.To.Type = obj.TYPE_CONST
p.To.Offset = offset
} else {
// Constant is too big for CMPU.
p = obj.Appendp(p, c.newprog)
p.As = AMOVD
p.From.Type = obj.TYPE_CONST
p.From.Offset = offset
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(p, c.newprog)
p.As = ACMPU
p.From.Type = obj.TYPE_REG
p.From.Reg = REGSP
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
}
p = obj.Appendp(p, c.newprog)
q = p
p.As = ABLT
p.To.Type = obj.TYPE_BRANCH
}
// Check against the stack guard. We've ensured this won't underflow.
// ADD $-(framesize-StackSmall), SP, R4
// CMPU stackguard, R4
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = ACMP
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_CONST
p.To.Offset = objabi.StackPreempt
p = obj.Appendp(p, c.newprog)
q = p
p.As = ABEQ
p.To.Type = obj.TYPE_BRANCH
p = obj.Appendp(p, c.newprog)
p.As = AADD p.As = AADD
p.From.Type = obj.TYPE_CONST p.From.Type = obj.TYPE_CONST
p.From.Offset = int64(objabi.StackGuard) p.From.Offset = -offset
p.Reg = REGSP p.Reg = REGSP
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4 p.To.Reg = REG_R4
p = obj.Appendp(p, c.newprog)
p.As = ASUB
p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4
p = obj.Appendp(p, c.newprog)
p.As = AMOVD
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 = REGTMP
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = ACMPU p.As = ACMPU
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGTMP p.From.Reg = REG_R3
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R4 p.To.Reg = REG_R4
} }