From 694182d77b1a0e3676214ad0e361bdbdafde33a1 Mon Sep 17 00:00:00 2001 From: Paul Murphy Date: Wed, 8 Oct 2025 14:34:09 -0500 Subject: [PATCH] cmd/internal/obj/ppc64: improve large prologue generation Avoid needing an unsafe section to store LR and adjust SP for large constants by using the stdux (MOVDU) instruction. This is also a few instructions shorter as the large constant adjustment is only created once. Change-Id: I6ff7a24181cdadb1846a33129fc148dcf59b76d5 Reviewed-on: https://go-review.googlesource.com/c/go/+/710197 Reviewed-by: Keith Randall Reviewed-by: Keith Randall Reviewed-by: David Chase Auto-Submit: Keith Randall LUCI-TryBot-Result: Go LUCI --- src/cmd/internal/obj/ppc64/obj9.go | 38 +++++++++++++----------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go index 5615b70aad..bae2965639 100644 --- a/src/cmd/internal/obj/ppc64/obj9.go +++ b/src/cmd/internal/obj/ppc64/obj9.go @@ -903,44 +903,38 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { q.To.Reg = REGSP q.Spadj = autosize } else { - // Frame size is too large for a MOVDU instruction. - // Store link register before decrementing SP, so if a signal comes - // during the execution of the function prologue, the traceback - // code will not see a half-updated stack frame. - // This sequence is not async preemptible, as if we open a frame - // at the current SP, it will clobber the saved LR. + // Frame size is too large for an stdu MOVDU instruction, use stdux MOVDU. q = obj.Appendp(q, c.newprog) q.As = AMOVD q.Pos = p.Pos q.From.Type = obj.TYPE_REG q.From.Reg = REG_LR q.To.Type = obj.TYPE_REG - q.To.Reg = REG_R29 // REGTMP may be used to synthesize large offset in the next instruction - - q = c.ctxt.StartUnsafePoint(q, c.newprog) + q.To.Reg = REG_R29 + // Create stack adjustment in REGTMP q = obj.Appendp(q, c.newprog) q.As = AMOVD q.Pos = p.Pos - q.From.Type = obj.TYPE_REG - q.From.Reg = REG_R29 - q.To.Type = obj.TYPE_MEM - q.To.Offset = int64(-autosize) - q.To.Reg = REGSP + q.From.Type = obj.TYPE_CONST + q.From.Offset = int64(-autosize) + q.To.Type = obj.TYPE_REG + q.To.Reg = REGTMP prologueEnd = q + // MOVDU R29, R31(R1) q = obj.Appendp(q, c.newprog) - q.As = AADD + q.As = AMOVDU q.Pos = p.Pos - q.From.Type = obj.TYPE_CONST - q.From.Offset = int64(-autosize) - q.To.Type = obj.TYPE_REG - q.To.Reg = REGSP - q.Spadj = +autosize - - q = c.ctxt.EndUnsafePoint(q, c.newprog, -1) + q.From.Type = obj.TYPE_REG + q.From.Reg = REG_R29 + q.To.Type = obj.TYPE_MEM + q.To.Reg = REGTMP + q.To.Index = REGSP + q.Spadj = autosize } + prologueEnd.Pos = prologueEnd.Pos.WithXlogue(src.PosPrologueEnd) } else if c.cursym.Func().Text.Mark&LEAF == 0 { // A very few functions that do not return to their caller -- 2.52.0