[dev.typeparams] cmd/internal/obj/arm64: use ABI-compatible registers in function prologue

Avoid using R1, R2, etc. in function prologue, which may carry
live argument values.

Change-Id: I80322b3f7e8fda7aaff622aaa99bc76d02e09727
Reviewed-on: https://go-review.googlesource.com/c/go/+/322852
Trust: Cherry Mui <cherryyz@google.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
Cherry Mui 2021-05-25 18:08:36 -04:00
parent 4bb927f82e
commit a4b2a04bc5

View file

@ -52,7 +52,7 @@ var complements = []obj.As{
} }
func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog { func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
// MOV g_stackguard(g), R1 // MOV g_stackguard(g), RT1
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = AMOVD p.As = AMOVD
@ -63,7 +63,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1 p.From.Offset = 3 * int64(c.ctxt.Arch.PtrSize) // G.stackguard1
} }
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R1 p.To.Reg = REGRT1
// Mark the stack bound check and morestack call async nonpreemptible. // Mark the stack bound check and morestack call async nonpreemptible.
// If we get preempted here, when resumed the preemption request is // If we get preempted here, when resumed the preemption request is
@ -74,25 +74,25 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
q := (*obj.Prog)(nil) q := (*obj.Prog)(nil)
if framesize <= objabi.StackSmall { if framesize <= objabi.StackSmall {
// small stack: SP < stackguard // small stack: SP < stackguard
// MOV SP, R2 // MOV SP, RT2
// CMP stackguard, R2 // CMP stackguard, RT2
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = AMOVD p.As = AMOVD
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REGSP p.From.Reg = REGSP
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REGRT2
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REGRT1
p.Reg = REG_R2 p.Reg = REGRT2
} else if framesize <= objabi.StackBig { } else if framesize <= objabi.StackBig {
// large stack: SP-framesize < stackguard-StackSmall // large stack: SP-framesize < stackguard-StackSmall
// SUB $(framesize-StackSmall), SP, R2 // SUB $(framesize-StackSmall), SP, RT2
// CMP stackguard, R2 // CMP stackguard, RT2
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = ASUB p.As = ASUB
@ -100,13 +100,13 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.From.Offset = int64(framesize) - objabi.StackSmall p.From.Offset = int64(framesize) - objabi.StackSmall
p.Reg = REGSP p.Reg = REGSP
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REGRT2
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REGRT1
p.Reg = REG_R2 p.Reg = REGRT2
} else { } else {
// Such a large stack we need to protect against underflow. // Such a large stack we need to protect against underflow.
// The runtime guarantees SP > objabi.StackBig, but // The runtime guarantees SP > objabi.StackBig, but
@ -115,10 +115,10 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
// stack guard to incorrectly succeed. We explicitly // stack guard to incorrectly succeed. We explicitly
// guard against underflow. // guard against underflow.
// //
// SUBS $(framesize-StackSmall), SP, R2 // SUBS $(framesize-StackSmall), SP, RT2
// // On underflow, jump to morestack // // On underflow, jump to morestack
// BLO label_of_call_to_morestack // BLO label_of_call_to_morestack
// CMP stackguard, R2 // CMP stackguard, RT2
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = ASUBS p.As = ASUBS
@ -126,7 +126,7 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.From.Offset = int64(framesize) - objabi.StackSmall p.From.Offset = int64(framesize) - objabi.StackSmall
p.Reg = REGSP p.Reg = REGSP
p.To.Type = obj.TYPE_REG p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R2 p.To.Reg = REGRT2
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
q = p q = p
@ -136,8 +136,8 @@ func (c *ctxt7) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p = obj.Appendp(p, c.newprog) p = obj.Appendp(p, c.newprog)
p.As = ACMP p.As = ACMP
p.From.Type = obj.TYPE_REG p.From.Type = obj.TYPE_REG
p.From.Reg = REG_R1 p.From.Reg = REGRT1
p.Reg = REG_R2 p.Reg = REGRT2
} }
// BLS do-morestack // BLS do-morestack
@ -631,38 +631,38 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
if c.cursym.Func().Text.From.Sym.Wrapper() { if c.cursym.Func().Text.From.Sym.Wrapper() {
// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame // if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
// //
// MOV g_panic(g), R1 // MOV g_panic(g), RT1
// CBNZ checkargp // CBNZ checkargp
// end: // end:
// NOP // NOP
// ... function body ... // ... function body ...
// checkargp: // checkargp:
// MOV panic_argp(R1), R2 // MOV panic_argp(RT1), RT2
// ADD $(autosize+8), RSP, R3 // ADD $(autosize+8), RSP, R20
// CMP R2, R3 // CMP RT2, R20
// BNE end // BNE end
// ADD $8, RSP, R4 // ADD $8, RSP, R20
// MOVD R4, panic_argp(R1) // MOVD R20, panic_argp(RT1)
// B end // B end
// //
// The NOP is needed to give the jumps somewhere to land. // The NOP is needed to give the jumps somewhere to land.
// It is a liblink NOP, not an ARM64 NOP: it encodes to 0 instruction bytes. // It is a liblink NOP, not an ARM64 NOP: it encodes to 0 instruction bytes.
q = q1 q = q1
// MOV g_panic(g), R1 // MOV g_panic(g), RT1
q = obj.Appendp(q, c.newprog) q = obj.Appendp(q, c.newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_MEM q.From.Type = obj.TYPE_MEM
q.From.Reg = REGG q.From.Reg = REGG
q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic q.From.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R1 q.To.Reg = REGRT1
// CBNZ R1, checkargp // CBNZ RT1, checkargp
cbnz := obj.Appendp(q, c.newprog) cbnz := obj.Appendp(q, c.newprog)
cbnz.As = ACBNZ cbnz.As = ACBNZ
cbnz.From.Type = obj.TYPE_REG cbnz.From.Type = obj.TYPE_REG
cbnz.From.Reg = REG_R1 cbnz.From.Reg = REGRT1
cbnz.To.Type = obj.TYPE_BRANCH cbnz.To.Type = obj.TYPE_BRANCH
// Empty branch target at the top of the function body // Empty branch target at the top of the function body
@ -674,33 +674,33 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
for last = end; last.Link != nil; last = last.Link { for last = end; last.Link != nil; last = last.Link {
} }
// MOV panic_argp(R1), R2 // MOV panic_argp(RT1), RT2
mov := obj.Appendp(last, c.newprog) mov := obj.Appendp(last, c.newprog)
mov.As = AMOVD mov.As = AMOVD
mov.From.Type = obj.TYPE_MEM mov.From.Type = obj.TYPE_MEM
mov.From.Reg = REG_R1 mov.From.Reg = REGRT1
mov.From.Offset = 0 // Panic.argp mov.From.Offset = 0 // Panic.argp
mov.To.Type = obj.TYPE_REG mov.To.Type = obj.TYPE_REG
mov.To.Reg = REG_R2 mov.To.Reg = REGRT2
// CBNZ branches to the MOV above // CBNZ branches to the MOV above
cbnz.To.SetTarget(mov) cbnz.To.SetTarget(mov)
// ADD $(autosize+8), SP, R3 // ADD $(autosize+8), SP, R20
q = obj.Appendp(mov, c.newprog) q = obj.Appendp(mov, c.newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = int64(c.autosize) + 8 q.From.Offset = int64(c.autosize) + 8
q.Reg = REGSP q.Reg = REGSP
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R3 q.To.Reg = REG_R20
// CMP R2, R3 // CMP RT2, R20
q = obj.Appendp(q, c.newprog) q = obj.Appendp(q, c.newprog)
q.As = ACMP q.As = ACMP
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R2 q.From.Reg = REGRT2
q.Reg = REG_R3 q.Reg = REG_R20
// BNE end // BNE end
q = obj.Appendp(q, c.newprog) q = obj.Appendp(q, c.newprog)
@ -708,22 +708,22 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q.To.Type = obj.TYPE_BRANCH q.To.Type = obj.TYPE_BRANCH
q.To.SetTarget(end) q.To.SetTarget(end)
// ADD $8, SP, R4 // ADD $8, SP, R20
q = obj.Appendp(q, c.newprog) q = obj.Appendp(q, c.newprog)
q.As = AADD q.As = AADD
q.From.Type = obj.TYPE_CONST q.From.Type = obj.TYPE_CONST
q.From.Offset = 8 q.From.Offset = 8
q.Reg = REGSP q.Reg = REGSP
q.To.Type = obj.TYPE_REG q.To.Type = obj.TYPE_REG
q.To.Reg = REG_R4 q.To.Reg = REG_R20
// MOV R4, panic_argp(R1) // MOV R20, panic_argp(RT1)
q = obj.Appendp(q, c.newprog) q = obj.Appendp(q, c.newprog)
q.As = AMOVD q.As = AMOVD
q.From.Type = obj.TYPE_REG q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R4 q.From.Reg = REG_R20
q.To.Type = obj.TYPE_MEM q.To.Type = obj.TYPE_MEM
q.To.Reg = REG_R1 q.To.Reg = REGRT1
q.To.Offset = 0 // Panic.argp q.To.Offset = 0 // Panic.argp
// B end // B end