8000 [release-branch.go1.23] cmd/compile: for arm64 epilog, do SP incremen… · golang/go@e8794e6 · GitHub
[go: up one dir, main page]

Skip to content

Commit e8794e6

Browse files
randall77Mark Freeman
authored andcommitted
[release-branch.go1.23] 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 #74693 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> (cherry picked from commit f7cc61e) Reviewed-on: https://go-review.googlesource.com/c/go/+/689595
1 parent 6c9c80b commit e8794e6

File tree

1 file changed

+43
-12
lines changed

1 file changed

+43
-12
lines changed

src/cmd/internal/obj/arm64/obj7.go

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -882,18 +882,49 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
882882
p.To.Reg = REGFP
883883
p.To.Offset = REGLINK
884884

885-
// ADD $aoffset, RSP, RSP
886-
q = newprog()
887-
q.As = AADD
888-
q.From.Type = obj.TYPE_CONST
889-
q.From.Offset = int64(aoffset)
890-
q.To.Type = obj.TYPE_REG
891-
q.To.Reg = REGSP
892-
q.Spadj = -aoffset
893-
q.Pos = p.Pos
894-
q.Link = p.Link
895-
p.Link = q
896-
p = q
885+
if aoffset < 1<<12 {
886+
// ADD $aoffset, RSP, RSP
887+
q = newprog()
888+
q.As = AADD
889+
q.From.Type = obj.TYPE_CONST
890+
q.From.Offset = int64(aoffset)
891+
q.To.Type = obj.TYPE_REG
892+
q.To.Reg = REGSP
893+
q.Spadj = -aoffset
894+
q.Pos = p.Pos
895+
q.Link = p.Link
896+
p.Link = q
897+
p = q
898+
} else {
899+
// Put frame size in a separate register and
900+
// add it in with a single instruction,
901+
// so we never have a partial frame during
902+
// the epilog. See issue 73259.
903+
904+
// MOVD $aoffset, REGTMP
905+
q = newprog()
906+
q.As = AMOVD
907+
q.From.Type = obj.TYPE_CONST
908+
q.From.Offset = int64(aoffset)
909+
q.To.Type = obj.TYPE_REG
910+
q.To.Reg = REGTMP
911+
q.Pos = p.Pos
912+
q.Link = p.Link
913+
p.Link = q
914+
p = q
915+
// ADD REGTMP, RSP, RSP
916+
q = newprog()
917+
q.As = AADD
918+
q.From.Type = obj.TYPE_REG
919+
q.From.Reg = REGTMP
920+
q.To.Type = obj.TYPE_REG
921+
q.To.Reg = REGSP
922+
q.Spadj = -aoffset
923+
q.Pos = p.Pos
924+
q.Link = p.Link
925+
p.Link = q
926+
p = q
927+
}
897928
}
898929

899930
// If enabled, this code emits 'MOV PC, R27' before every 'MOV LR, PC',

0 commit comments

Comments
 (0)
0