[release-branch.go1.21] cmd/internal/obj/arm64: fix frame pointer restore in epilogue

For leaf but nonzero-frame functions.

Currently we're not restoring it properly. We also need to restore
it before popping the stack frame, so that the frame won't get
clobbered by a signal handler in the meantime.

For #63830
Fixes #65449

Needs a test, but I'm not at all sure how we would actually do that. Leaving for inspiration.

Change-Id: I273a25f2a838f05a959c810145cccc5428eaf164
Reviewed-on: https://go-review.googlesource.com/c/go/+/538635
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Eric Fang <eric.fang@arm.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: David Chase <drchase@google.com>
(cherry picked from commit c9888bdfe2cdd85d14d7d184863d2e8bc42ff73c)
Reviewed-on: https://go-review.googlesource.com/c/go/+/560735
TryBot-Bypass: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
diff --git a/src/cmd/internal/obj/arm64/obj7.go b/src/cmd/internal/obj/arm64/obj7.go
index f963f62..f7cca30 100644
--- a/src/cmd/internal/obj/arm64/obj7.go
+++ b/src/cmd/internal/obj/arm64/obj7.go
@@ -826,21 +826,24 @@
 			p.To = obj.Addr{}
 			if c.cursym.Func().Text.Mark&LEAF != 0 {
 				if c.autosize != 0 {
+					// Restore frame pointer.
+					// ADD $framesize-8, RSP, R29
+					p.As = AADD
+					p.From.Type = obj.TYPE_CONST
+					p.From.Offset = int64(c.autosize) - 8
+					p.Reg = REGSP
+					p.To.Type = obj.TYPE_REG
+					p.To.Reg = REGFP
+
+					// Pop stack frame.
+					// ADD $framesize, RSP, RSP
+					p = obj.Appendp(p, c.newprog)
 					p.As = AADD
 					p.From.Type = obj.TYPE_CONST
 					p.From.Offset = int64(c.autosize)
 					p.To.Type = obj.TYPE_REG
 					p.To.Reg = REGSP
 					p.Spadj = -c.autosize
-
-					// Frame pointer.
-					p = obj.Appendp(p, c.newprog)
-					p.As = ASUB
-					p.From.Type = obj.TYPE_CONST
-					p.From.Offset = 8
-					p.Reg = REGSP
-					p.To.Type = obj.TYPE_REG
-					p.To.Reg = REGFP
 				}
 			} else {
 				aoffset := c.autosize