mirror of
https://github.com/golang/go
synced 2024-11-17 03:04:44 -07:00
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 <mzh@golangcn.org> Run-TryBot: mzh <mzh@golangcn.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
2de2f6df64
commit
6c17529af7
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user