mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: for arm64 epilog, do SP increment with a single instruction
That way, the frame is atomically popped. Previously, for big frames the SP was unwound in two steps (because arm64 can only add constants up to 1<<12 in a single instruction). Fixes #73259 Change-Id: I382c249194ad7bc9fc19607c27487c58d90d49e5 Reviewed-on: https://go-review.googlesource.com/c/go/+/689235 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Keith Randall <khr@google.com>
This commit is contained in:
parent
5dac42363b
commit
f7cc61e7d7
1 changed files with 43 additions and 12 deletions
|
|
@ -907,6 +907,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
p.To.Reg = REGFP
|
p.To.Reg = REGFP
|
||||||
p.To.Offset = REGLINK
|
p.To.Offset = REGLINK
|
||||||
|
|
||||||
|
if aoffset < 1<<12 {
|
||||||
// ADD $aoffset, RSP, RSP
|
// ADD $aoffset, RSP, RSP
|
||||||
q = newprog()
|
q = newprog()
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
|
|
@ -919,6 +920,36 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
||||||
q.Link = p.Link
|
q.Link = p.Link
|
||||||
p.Link = q
|
p.Link = q
|
||||||
p = q
|
p = q
|
||||||
|
} else {
|
||||||
|
// Put frame size in a separate register and
|
||||||
|
// add it in with a single instruction,
|
||||||
|
// so we never have a partial frame during
|
||||||
|
// the epilog. See issue 73259.
|
||||||
|
|
||||||
|
// MOVD $aoffset, REGTMP
|
||||||
|
q = newprog()
|
||||||
|
q.As = AMOVD
|
||||||
|
q.From.Type = obj.TYPE_CONST
|
||||||
|
q.From.Offset = int64(aoffset)
|
||||||
|
q.To.Type = obj.TYPE_REG
|
||||||
|
q.To.Reg = REGTMP
|
||||||
|
q.Pos = p.Pos
|
||||||
|
q.Link = p.Link
|
||||||
|
p.Link = q
|
||||||
|
p = q
|
||||||
|
// ADD REGTMP, RSP, RSP
|
||||||
|
q = newprog()
|
||||||
|
q.As = AADD
|
||||||
|
q.From.Type = obj.TYPE_REG
|
||||||
|
q.From.Reg = REGTMP
|
||||||
|
q.To.Type = obj.TYPE_REG
|
||||||
|
q.To.Reg = REGSP
|
||||||
|
q.Spadj = -aoffset
|
||||||
|
q.Pos = p.Pos
|
||||||
|
q.Link = p.Link
|
||||||
|
p.Link = q
|
||||||
|
p = q
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If enabled, this code emits 'MOV PC, R27' before every 'MOV LR, PC',
|
// If enabled, this code emits 'MOV PC, R27' before every 'MOV LR, PC',
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue