diff options
| author | Srinivas Pokala <Pokala.Srinivas@ibm.com> | 2025-11-11 04:47:55 +0100 |
|---|---|---|
| committer | Keith Randall <khr@golang.org> | 2025-11-24 10:21:41 -0800 |
| commit | 85e60800893df03c5b071f66fa2dde5e00fdf295 (patch) | |
| tree | dd1ad82bc2be84282d83f062c36d6e2168533b5c /src/cmd/internal/obj | |
| parent | 24697419c54c046370c3431fb45842689c042984 (diff) | |
| download | go-85e60800893df03c5b071f66fa2dde5e00fdf295.tar.xz | |
cmd/internal/obj: set morestack arg spilling and regabi prologue on
s390x
This CL spill arg registers before calling morestack, unspill them
after morestack call. It also avoid clobbering the register that
could contain incoming argument values. Change registers on s390x to
avoid regABI arguments.
Update #40724
Change-Id: I67b20552410dd23ef0b86f14b9c5bfed9f9723a6
Reviewed-on: https://go-review.googlesource.com/c/go/+/719421
Reviewed-by: Vishwanatha HD <vishwanatha.hd@ibm.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: David Chase <drchase@google.com>
Diffstat (limited to 'src/cmd/internal/obj')
| -rw-r--r-- | src/cmd/internal/obj/s390x/a.out.go | 4 | ||||
| -rw-r--r-- | src/cmd/internal/obj/s390x/objz.go | 50 |
2 files changed, 34 insertions, 20 deletions
diff --git a/src/cmd/internal/obj/s390x/a.out.go b/src/cmd/internal/obj/s390x/a.out.go index caf5ec0935..6b16d7a9bd 100644 --- a/src/cmd/internal/obj/s390x/a.out.go +++ b/src/cmd/internal/obj/s390x/a.out.go @@ -139,8 +139,8 @@ const ( REG_RESERVED // end of allocated registers REGARG = -1 // -1 disables passing the first argument in register - REGRT1 = REG_R3 // used during zeroing of the stack - not reserved - REGRT2 = REG_R4 // used during zeroing of the stack - not reserved + REGRT1 = REG_R1 // used during zeroing of the stack - not reserved + REGRT2 = REG_R10 // used during zeroing of the stack - not reserved REGTMP = REG_R10 // scratch register used in the assembler and linker REGTMP2 = REG_R11 // scratch register used in the assembler and linker REGCTXT = REG_R12 // context for closures diff --git a/src/cmd/internal/obj/s390x/objz.go b/src/cmd/internal/obj/s390x/objz.go index 44c1a7d586..4bfc1f7b2c 100644 --- a/src/cmd/internal/obj/s390x/objz.go +++ b/src/cmd/internal/obj/s390x/objz.go @@ -506,7 +506,13 @@ func (c *ctxtz) stacksplitPre(p *obj.Prog, framesize int32) (pPre, pPreempt, pCh // Save LR and REGCTXT const frameSize = 16 p = c.ctxt.StartUnsafePoint(p, c.newprog) + + // Spill arguments. This has to happen before we open + // any more frame space. + p = c.cursym.Func().SpillRegisterArgs(p, c.newprog) + // MOVD LR, -16(SP) + p = obj.Appendp(p, c.newprog) p.As = AMOVD p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_LR} @@ -549,10 +555,12 @@ func (c *ctxtz) stacksplitPre(p *obj.Prog, framesize int32) (pPre, pPreempt, pCh p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REGSP} p.Spadj = -frameSize + // Unspill arguments + p = c.cursym.Func().UnspillRegisterArgs(p, c.newprog) p = c.ctxt.EndUnsafePoint(p, c.newprog, -1) } - // MOVD g_stackguard(g), R3 + // MOVD g_stackguard(g), R10 p = obj.Appendp(p, c.newprog) // Jump back to here after morestack returns. pCheck = p @@ -565,7 +573,7 @@ func (c *ctxtz) stacksplitPre(p *obj.Prog, framesize int32) (pPre, pPreempt, pCh p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1 } p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R3 + p.To.Reg = REG_R10 // Mark the stack bound check and morestack call async nonpreemptible. // If we get preempted here, when resumed the preemption request is @@ -579,7 +587,7 @@ func (c *ctxtz) stacksplitPre(p *obj.Prog, framesize int32) (pPre, pPreempt, pCh p = obj.Appendp(p, c.newprog) p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 + p.From.Reg = REG_R10 p.Reg = REGSP p.As = ACMPUBGE p.To.Type = obj.TYPE_BRANCH @@ -598,40 +606,40 @@ func (c *ctxtz) stacksplitPre(p *obj.Prog, framesize int32) (pPre, pPreempt, pCh // stack guard to incorrectly succeed. We explicitly // guard against underflow. // - // MOVD $(framesize-StackSmall), R4 - // CMPUBLT SP, R4, label-of-call-to-morestack + // MOVD $(framesize-StackSmall), R11 + // CMPUBLT SP, R11, label-of-call-to-morestack 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.To.Reg = REG_R11 p = obj.Appendp(p, c.newprog) pPreempt = p p.As = ACMPUBLT p.From.Type = obj.TYPE_REG p.From.Reg = REGSP - p.Reg = REG_R4 + p.Reg = REG_R11 p.To.Type = obj.TYPE_BRANCH } // Check against the stack guard. We've ensured this won't underflow. - // ADD $-(framesize-StackSmall), SP, R4 - // CMPUBGE stackguard, R4, label-of-call-to-morestack + // ADD $-(framesize-StackSmall), SP, R11 + // CMPUBGE stackguard, R11, label-of-call-to-morestack p = obj.Appendp(p, c.newprog) p.As = AADD p.From.Type = obj.TYPE_CONST p.From.Offset = -offset p.Reg = REGSP p.To.Type = obj.TYPE_REG - p.To.Reg = REG_R4 + p.To.Reg = REG_R11 p = obj.Appendp(p, c.newprog) p.From.Type = obj.TYPE_REG - p.From.Reg = REG_R3 - p.Reg = REG_R4 + p.From.Reg = REG_R10 + p.Reg = REG_R11 p.As = ACMPUBGE p.To.Type = obj.TYPE_BRANCH @@ -654,18 +662,22 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre, pPreempt, pCheck *obj.Prog, fr pcdata := c.ctxt.EmitEntryStackMap(c.cursym, spfix, c.newprog) pcdata = c.ctxt.StartUnsafePoint(pcdata, c.newprog) + if pPreempt != nil { + pPreempt.To.SetTarget(pcdata) + } + pPre.To.SetTarget(pcdata) + + // Spill the register args that could be clobbered by the + // morestack code. + spill := c.cursym.Func().SpillRegisterArgs(pcdata, c.newprog) // MOVD LR, R5 - p = obj.Appendp(pcdata, c.newprog) - pPre.To.SetTarget(p) + p = obj.Appendp(spill, c.newprog) p.As = AMOVD p.From.Type = obj.TYPE_REG p.From.Reg = REG_LR p.To.Type = obj.TYPE_REG p.To.Reg = REG_R5 - if pPreempt != nil { - pPreempt.To.SetTarget(p) - } // BL runtime.morestack(SB) p = obj.Appendp(p, c.newprog) @@ -680,10 +692,12 @@ func (c *ctxtz) stacksplitPost(p *obj.Prog, pPre, pPreempt, pCheck *obj.Prog, fr p.To.Sym = c.ctxt.Lookup("runtime.morestack") } + // The instructions which unspill regs should be preemptible. p = c.ctxt.EndUnsafePoint(p, c.newprog, -1) + unspill := c.cursym.Func().UnspillRegisterArgs(p, c.newprog) // BR pCheck - p = obj.Appendp(p, c.newprog) + p = obj.Appendp(unspill, c.newprog) p.As = ABR p.To.Type = obj.TYPE_BRANCH |
