diff --git a/src/cmd/internal/obj/riscv/obj.go b/src/cmd/internal/obj/riscv/obj.go index 5b598b5757..0a09b7fc14 100644 --- a/src/cmd/internal/obj/riscv/obj.go +++ b/src/cmd/internal/obj/riscv/obj.go @@ -984,19 +984,20 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA // unnecessarily. See issue #35470. p = ctxt.StartUnsafePoint(p, newprog) - var to_done, to_more *obj.Prog + var to_more *obj.Prog + to_more_big := (*obj.Prog)(nil) if framesize <= abi.StackSmall { // small stack - // // if SP > stackguard { goto done } - // BLTU stackguard, SP, done + // // if SP <= stackguard { goto label-of-call-to-morestack } + // BGEU stackguard, SP, label-of-call-to-morestack p = obj.Appendp(p, newprog) - p.As = ABLTU + p.As = ABGEU p.From.Type = obj.TYPE_REG p.From.Reg = REG_X6 p.Reg = REG_SP p.To.Type = obj.TYPE_BRANCH - to_done = p + to_more = p } else { // large stack: SP-framesize < stackguard-StackSmall offset := int64(framesize) - abi.StackSmall @@ -1024,13 +1025,13 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA p.From.Reg = REG_SP p.Reg = REG_X7 p.To.Type = obj.TYPE_BRANCH - to_more = p + to_more_big = p } // Check against the stack guard. We've ensured this won't underflow. // ADD $-(framesize-StackSmall), SP, X7 - // // if X7 > stackguard { goto done } - // BLTU stackguard, X7, done + // // if X7 <= stackguard { goto label-of-call-to-morestack } + // BLTU stackguard, X7, label-of-call-to-morestack p = obj.Appendp(p, newprog) p.As = AADDI p.From.Type = obj.TYPE_CONST @@ -1040,53 +1041,65 @@ func stacksplit(ctxt *obj.Link, p *obj.Prog, cursym *obj.LSym, newprog obj.ProgA p.To.Reg = REG_X7 p = obj.Appendp(p, newprog) - p.As = ABLTU + p.As = ABGEU p.From.Type = obj.TYPE_REG p.From.Reg = REG_X6 p.Reg = REG_X7 p.To.Type = obj.TYPE_BRANCH - to_done = p + to_more = p } + end := ctxt.EndUnsafePoint(p, newprog, -1) + + var last *obj.Prog + for last = cursym.Func().Text; last.Link != nil; last = last.Link { + } + + // Now we are at the end of the function, but logically + // we are still in function prologue. We need to fix the + // SP data and PCDATA. + spfix := obj.Appendp(last, newprog) + spfix.As = obj.ANOP + spfix.Spadj = -int32(framesize) + + pcdata := ctxt.EmitEntryStackMap(cursym, spfix, newprog) + pcdata = ctxt.StartUnsafePoint(pcdata, newprog) + + if to_more_big != nil { + to_more_big.To.SetTarget(pcdata) + } + to_more.To.SetTarget(pcdata) + // Spill the register args that could be clobbered by the // morestack code - p = ctxt.EmitEntryStackMap(cursym, p, newprog) - p = cursym.Func().SpillRegisterArgs(p, newprog) + spill := cursym.Func().SpillRegisterArgs(pcdata, newprog) // CALL runtime.morestack(SB) - p = obj.Appendp(p, newprog) - p.As = obj.ACALL - p.To.Type = obj.TYPE_BRANCH + call := obj.Appendp(spill, newprog) + call.As = obj.ACALL + call.To.Type = obj.TYPE_BRANCH if cursym.CFunc() { - p.To.Sym = ctxt.Lookup("runtime.morestackc") + call.To.Sym = ctxt.Lookup("runtime.morestackc") } else if !cursym.Func().Text.From.Sym.NeedCtxt() { - p.To.Sym = ctxt.Lookup("runtime.morestack_noctxt") + call.To.Sym = ctxt.Lookup("runtime.morestack_noctxt") } else { - p.To.Sym = ctxt.Lookup("runtime.morestack") + call.To.Sym = ctxt.Lookup("runtime.morestack") } - if to_more != nil { - to_more.To.SetTarget(p) - } - jalToSym(ctxt, p, REG_X5) + jalToSym(ctxt, call, REG_X5) - // The instructions which unspill regs should be preemptible. - p = ctxt.EndUnsafePoint(p, newprog, -1) - p = cursym.Func().UnspillRegisterArgs(p, newprog) + pcdata = ctxt.EndUnsafePoint(call, newprog, -1) + unspill := cursym.Func().UnspillRegisterArgs(pcdata, newprog) // JMP start - p = obj.Appendp(p, newprog) - p.As = AJAL - p.To = obj.Addr{Type: obj.TYPE_BRANCH} - p.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO} - p.To.SetTarget(startPred.Link) + jmp := obj.Appendp(unspill, newprog) + jmp.As = AJAL + jmp.To = obj.Addr{Type: obj.TYPE_BRANCH} + jmp.From = obj.Addr{Type: obj.TYPE_REG, Reg: REG_ZERO} + jmp.To.SetTarget(startPred.Link) + jmp.Spadj = +int32(framesize) - // placeholder for to_done's jump target - p = obj.Appendp(p, newprog) - p.As = obj.ANOP // zero-width place holder - to_done.To.SetTarget(p) - - return p + return end } // signExtend sign extends val starting at bit bit.