mirror of
https://github.com/golang/go
synced 2024-11-17 10:44:43 -07:00
cmd/internal/obj/ppc64: generate prologue code compatible with new ABI
This changes the ppc64 prologue to avoid clobbering the registers that could contain incoming argument values. This means preserving the values in R3 - R10 and R14 - R19 for ppc64. Instead of modifying R3, R4, R5 and R6 the registers R22, R23, R24 and R25 are used. The argument registers that could be clobbered by the call to morestack are saved and restored around that call. Change-Id: If354c3dc73f2c8537ef4e513e5a4c05d7bd22866 Reviewed-on: https://go-review.googlesource.com/c/go/+/343872 Trust: Lynn Boger <laboger@linux.vnet.ibm.com> Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
This commit is contained in:
parent
03df68d3c3
commit
0edc6c4fa0
@ -294,9 +294,9 @@ func (c *ctxt9) rewriteToUseGot(p *obj.Prog) {
|
|||||||
// BL (LR)
|
// BL (LR)
|
||||||
var sym *obj.LSym
|
var sym *obj.LSym
|
||||||
if p.As == obj.ADUFFZERO {
|
if p.As == obj.ADUFFZERO {
|
||||||
sym = c.ctxt.Lookup("runtime.duffzero")
|
sym = c.ctxt.LookupABI("runtime.duffzero", obj.ABIInternal)
|
||||||
} else {
|
} else {
|
||||||
sym = c.ctxt.Lookup("runtime.duffcopy")
|
sym = c.ctxt.LookupABI("runtime.duffcopy", obj.ABIInternal)
|
||||||
}
|
}
|
||||||
offset := p.To.Offset
|
offset := p.To.Offset
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
@ -687,7 +687,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.From.Reg = REG_LR
|
q.From.Reg = REG_LR
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REGTMP
|
q.To.Reg = REGTMP
|
||||||
|
|
||||||
prologueEnd = q
|
prologueEnd = q
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
@ -787,14 +786,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
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_R3
|
q.To.Reg = REG_R22
|
||||||
|
|
||||||
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_R0
|
q.From.Reg = REG_R0
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R3
|
q.To.Reg = REG_R22
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ABEQ
|
q.As = ABEQ
|
||||||
@ -804,10 +803,10 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
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 = REG_R3
|
q.From.Reg = REG_R22
|
||||||
q.From.Offset = 0 // Panic.argp
|
q.From.Offset = 0 // Panic.argp
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R4
|
q.To.Reg = REG_R23
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = AADD
|
q.As = AADD
|
||||||
@ -815,14 +814,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.From.Offset = int64(autosize) + c.ctxt.FixedFrameSize()
|
q.From.Offset = int64(autosize) + c.ctxt.FixedFrameSize()
|
||||||
q.Reg = REGSP
|
q.Reg = REGSP
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R5
|
q.To.Reg = REG_R24
|
||||||
|
|
||||||
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_R4
|
q.From.Reg = REG_R23
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R5
|
q.To.Reg = REG_R24
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
q.As = ABNE
|
q.As = ABNE
|
||||||
@ -835,14 +834,14 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
q.From.Offset = c.ctxt.FixedFrameSize()
|
q.From.Offset = c.ctxt.FixedFrameSize()
|
||||||
q.Reg = REGSP
|
q.Reg = REGSP
|
||||||
q.To.Type = obj.TYPE_REG
|
q.To.Type = obj.TYPE_REG
|
||||||
q.To.Reg = REG_R6
|
q.To.Reg = REG_R25
|
||||||
|
|
||||||
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_R6
|
q.From.Reg = REG_R25
|
||||||
q.To.Type = obj.TYPE_MEM
|
q.To.Type = obj.TYPE_MEM
|
||||||
q.To.Reg = REG_R3
|
q.To.Reg = REG_R22
|
||||||
q.To.Offset = 0 // Panic.argp
|
q.To.Offset = 0 // Panic.argp
|
||||||
|
|
||||||
q = obj.Appendp(q, c.newprog)
|
q = obj.Appendp(q, c.newprog)
|
||||||
@ -1051,7 +1050,7 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
|
|||||||
func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
||||||
p0 := p // save entry point, but skipping the two instructions setting R2 in shared mode
|
p0 := p // save entry point, but skipping the two instructions setting R2 in shared mode
|
||||||
|
|
||||||
// MOVD g_stackguard(g), R3
|
// MOVD g_stackguard(g), R22
|
||||||
p = obj.Appendp(p, c.newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
|
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
@ -1062,7 +1061,7 @@ func (c *ctxt9) 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_R3
|
p.To.Reg = REG_R22
|
||||||
|
|
||||||
// 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
|
||||||
@ -1078,7 +1077,7 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||||||
|
|
||||||
p.As = ACMPU
|
p.As = ACMPU
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REG_R3
|
p.From.Reg = REG_R22
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REGSP
|
p.To.Reg = REGSP
|
||||||
} else {
|
} else {
|
||||||
@ -1108,14 +1107,14 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||||||
p.From.Type = obj.TYPE_CONST
|
p.From.Type = obj.TYPE_CONST
|
||||||
p.From.Offset = offset
|
p.From.Offset = offset
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R4
|
p.To.Reg = REG_R23
|
||||||
|
|
||||||
p = obj.Appendp(p, c.newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
p.As = ACMPU
|
p.As = ACMPU
|
||||||
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_R4
|
p.To.Reg = REG_R23
|
||||||
}
|
}
|
||||||
|
|
||||||
p = obj.Appendp(p, c.newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
@ -1134,14 +1133,14 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||||||
p.From.Offset = -offset
|
p.From.Offset = -offset
|
||||||
p.Reg = REGSP
|
p.Reg = REGSP
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R4
|
p.To.Reg = REG_R23
|
||||||
|
|
||||||
p = obj.Appendp(p, c.newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
p.As = ACMPU
|
p.As = ACMPU
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REG_R3
|
p.From.Reg = REG_R22
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R4
|
p.To.Reg = REG_R23
|
||||||
}
|
}
|
||||||
|
|
||||||
// q1: BLT done
|
// q1: BLT done
|
||||||
@ -1151,17 +1150,25 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||||||
p.As = ABLT
|
p.As = ABLT
|
||||||
p.To.Type = obj.TYPE_BRANCH
|
p.To.Type = obj.TYPE_BRANCH
|
||||||
|
|
||||||
// MOVD LR, R5
|
|
||||||
p = obj.Appendp(p, c.newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
|
p.As = obj.ANOP // zero-width place holder
|
||||||
|
|
||||||
|
if q != nil {
|
||||||
|
q.To.SetTarget(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spill the register args that could be clobbered by the
|
||||||
|
// morestack code.
|
||||||
|
|
||||||
|
spill := c.cursym.Func().SpillRegisterArgs(p, c.newprog)
|
||||||
|
|
||||||
|
// MOVD LR, R5
|
||||||
|
p = obj.Appendp(spill, c.newprog)
|
||||||
p.As = AMOVD
|
p.As = AMOVD
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = REG_LR
|
p.From.Reg = REG_LR
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = REG_R5
|
p.To.Reg = REG_R5
|
||||||
if q != nil {
|
|
||||||
q.To.SetTarget(p)
|
|
||||||
}
|
|
||||||
|
|
||||||
p = c.ctxt.EmitEntryStackMap(c.cursym, p, c.newprog)
|
p = c.ctxt.EmitEntryStackMap(c.cursym, p, c.newprog)
|
||||||
|
|
||||||
@ -1181,8 +1188,7 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||||||
// Fortunately, in shared mode, 8(SP) and 16(SP) are reserved in
|
// Fortunately, in shared mode, 8(SP) and 16(SP) are reserved in
|
||||||
// the caller's frame, but not used (0(SP) is caller's saved LR,
|
// the caller's frame, but not used (0(SP) is caller's saved LR,
|
||||||
// 24(SP) is caller's saved R2). Use 8(SP) to save this function's R2.
|
// 24(SP) is caller's saved R2). Use 8(SP) to save this function's R2.
|
||||||
|
// MOVD R2, 8(SP)
|
||||||
// MOVD R12, 8(SP)
|
|
||||||
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
|
||||||
@ -1249,7 +1255,8 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
|
|||||||
p.To.Reg = REG_R2
|
p.To.Reg = REG_R2
|
||||||
}
|
}
|
||||||
|
|
||||||
p = c.ctxt.EndUnsafePoint(p, c.newprog, -1)
|
unspill := c.cursym.Func().UnspillRegisterArgs(p, c.newprog)
|
||||||
|
p = c.ctxt.EndUnsafePoint(unspill, c.newprog, -1)
|
||||||
|
|
||||||
// BR start
|
// BR start
|
||||||
p = obj.Appendp(p, c.newprog)
|
p = obj.Appendp(p, c.newprog)
|
||||||
|
Loading…
Reference in New Issue
Block a user