From 6c17529af785d14fd317e19f878327539ea6cd47 Mon Sep 17 00:00:00 2001 From: Meng Zhuo Date: Tue, 29 Mar 2022 19:14:24 +0800 Subject: [PATCH] cmd/internal/obj: set morestack arg spilling and regabi prologue on riscv64 This CL spill arg registers before calling morestack, unspill after. Also, avoid X11,X12,X13 in function prologue, which may carry live argument value. Change-Id: I7a2841fbe306f62a7765e212f9f0be5c11ce7f8c Reviewed-on: https://go-review.googlesource.com/c/go/+/396655 Trust: mzh Run-TryBot: mzh TryBot-Result: Gopher Robot Reviewed-by: Cherry Mui --- src/cmd/internal/obj/riscv/obj.go | 72 ++++++++++++++++++------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 956d69ee2e..0f52f66779 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -415,17 +415,17 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { if cursym.Func().Text.From.Sym.Wrapper() { // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // - // MOV g_panic(g), X11 - // BNE X11, ZERO, adjust + // MOV g_panic(g), X5 + // BNE X5, ZERO, adjust // end: // NOP // ...rest of function.. // adjust: - // MOV panic_argp(X11), X12 - // ADD $(autosize+FIXED_FRAME), SP, X13 - // BNE X12, X13, end - // ADD $FIXED_FRAME, SP, X12 - // MOV X12, panic_argp(X11) + // MOV panic_argp(X5), X6 + // ADD $(autosize+FIXED_FRAME), SP, X7 + // BNE X6, X7, end + // ADD $FIXED_FRAME, SP, X6 + // MOV X6, panic_argp(X5) // JMP end // // The NOP is needed to give the jumps somewhere to land. @@ -435,11 +435,11 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { ldpanic.As = AMOV ldpanic.From = obj.Addr{Type: obj.TYPE_MEM, Reg: REGG, Offset: 4 * int64(ctxt.Arch.PtrSize)} // G.panic ldpanic.Reg = obj.REG_NONE - ldpanic.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X11} + ldpanic.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X5} bneadj := obj.Appendp(ldpanic, newprog) bneadj.As = ABNE - bneadj.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X11} + bneadj.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X5} bneadj.Reg = REG_ZERO bneadj.To.Type = obj.TYPE_BRANCH @@ -453,9 +453,9 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { getargp := obj.Appendp(last, newprog) getargp.As = AMOV - getargp.From = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_X11, Offset: 0} // Panic.argp + getargp.From = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_X5, Offset: 0} // Panic.argp getargp.Reg = obj.REG_NONE - getargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X12} + getargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X6} bneadj.To.SetTarget(getargp) @@ -463,12 +463,12 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { calcargp.As = AADDI calcargp.From = obj.Addr{Type: obj.TYPE_CONST, Offset: stacksize + ctxt.FixedFrameSize()} calcargp.Reg = REG_SP - calcargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X13} + calcargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X7} testargp := obj.Appendp(calcargp, newprog) testargp.As = ABNE - testargp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X12} - testargp.Reg = REG_X13 + testargp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X6} + testargp.Reg = REG_X7 testargp.To.Type = obj.TYPE_BRANCH testargp.To.SetTarget(endadj) @@ -476,13 +476,13 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) { adjargp.As = AADDI adjargp.From = obj.Addr{Type: obj.TYPE_CONST, Offset: int64(ctxt.Arch.PtrSize)} adjargp.Reg = REG_SP - adjargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X12} + adjargp.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X6} setargp := obj.Appendp(adjargp, newprog) setargp.As = AMOV - setargp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X12} + setargp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_X6} setargp.Reg = obj.REG_NONE - setargp.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_X11, Offset: 0} // Panic.argp + setargp.To = obj.Addr{Type: obj.TYPE_MEM, Reg: REG_X5, Offset: 0} // Panic.argp godone := obj.Appendp(setargp, newprog) godone.As = AJAL @@ -732,6 +732,11 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA // Save LR and REGCTXT const frameSize = 16 p = ctxt.StartUnsafePoint(p, newprog) + + // Spill Arguments. This has to happen before we open + // any more frame space. + p = cursym.Func().SpillRegisterArgs(p, newprog) + // MOV LR, -16(SP) p = obj.Appendp(p, newprog) p.As = AMOV @@ -778,13 +783,15 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA p.To = obj.Addr{Type: obj.TYPE_REG, Reg: REG_SP} p.Spadj = -frameSize + // Unspill arguments + p = cursym.Func().UnspillRegisterArgs(p, newprog) p = ctxt.EndUnsafePoint(p, newprog, -1) } // Jump back to here after morestack returns. startPred := p - // MOV g_stackguard(g), X10 + // MOV g_stackguard(g), X6 p = obj.Appendp(p, newprog) p.As = AMOV p.From.Type = obj.TYPE_MEM @@ -794,7 +801,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA p.From.Offset = 3 * int64(ctxt.Arch.PtrSize) // G.stackguard1 } p.To.Type = obj.TYPE_REG - p.To.Reg = REG_X10 + p.To.Reg = REG_X6 // Mark the stack bound check and morestack call async nonpreemptible. // If we get preempted here, when resumed the preemption request is @@ -811,7 +818,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA p = obj.Appendp(p, newprog) p.As = ABLTU p.From.Type = obj.TYPE_REG - p.From.Reg = REG_X10 + p.From.Reg = REG_X6 p.Reg = REG_SP p.To.Type = obj.TYPE_BRANCH to_done = p @@ -826,52 +833,56 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA // stack guard to incorrectly succeed. We explicitly // guard against underflow. // - // MOV $(framesize-StackSmall), X11 - // BLTU SP, X11, label-of-call-to-morestack + // MOV $(framesize-StackSmall), X7 + // BLTU SP, X7, label-of-call-to-morestack p = obj.Appendp(p, newprog) p.As = AMOV p.From.Type = obj.TYPE_CONST p.From.Offset = offset p.To.Type = obj.TYPE_REG - p.To.Reg = REG_X11 + p.To.Reg = REG_X7 p = obj.Appendp(p, newprog) p.As = ABLTU p.From.Type = obj.TYPE_REG p.From.Reg = REG_SP - p.Reg = REG_X11 + p.Reg = REG_X7 p.To.Type = obj.TYPE_BRANCH to_more = p } // Check against the stack guard. We've ensured this won't underflow. - // ADD $-(framesize-StackSmall), SP, X11 - // // if X11 > stackguard { goto done } - // BLTU stackguard, X11, done + // ADD $-(framesize-StackSmall), SP, X7 + // // if X7 > stackguard { goto done } + // BLTU stackguard, X7, done p = obj.Appendp(p, newprog) p.As = AADDI p.From.Type = obj.TYPE_CONST p.From.Offset = -offset p.Reg = REG_SP p.To.Type = obj.TYPE_REG - p.To.Reg = REG_X11 + p.To.Reg = REG_X7 p = obj.Appendp(p, newprog) p.As = ABLTU p.From.Type = obj.TYPE_REG - p.From.Reg = REG_X10 - p.Reg = REG_X11 + p.From.Reg = REG_X6 + p.Reg = REG_X7 p.To.Type = obj.TYPE_BRANCH to_done = p } + // Spill the register args that could be clobbered by the + // morestack code p = ctxt.EmitEntryStackMap(cursym, p, newprog) + p = cursym.Func().SpillRegisterArgs(p, newprog) // CALL runtime.morestack(SB) p = obj.Appendp(p, newprog) p.As = obj.ACALL p.To.Type = obj.TYPE_BRANCH + if cursym.CFunc() { p.To.Sym = ctxt.Lookup("runtime.morestackc") } else if !cursym.Func().Text.From.Sym.NeedCtxt() { @@ -884,6 +895,7 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA } jalToSym(ctxt, p, REG_X5) + p = cursym.Func().UnspillRegisterArgs(p, newprog) p = ctxt.EndUnsafePoint(p, newprog, -1) // JMP start -- 2.48.1