1
0
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:
Lynn Boger 2021-08-16 09:37:07 -05:00
parent 03df68d3c3
commit 0edc6c4fa0

View File

@ -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)