mirror of https://github.com/golang/go.git
[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:
parent
4bb927f82e
commit
a4b2a04bc5
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue