aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLynn Boger <laboger@linux.vnet.ibm.com>2021-08-16 09:37:07 -0500
committerLynn Boger <laboger@linux.vnet.ibm.com>2021-09-15 22:07:58 +0000
commit0edc6c4fa088a74bef98d55cc93ffa387d4f7b2d (patch)
treec5df9aa15aed16311d86d670ee8fee2da2f41f27
parent03df68d3c33e83a23cf5f22389a37f2d09721bef (diff)
downloadgo-0edc6c4fa088a74bef98d55cc93ffa387d4f7b2d.tar.gz
go-0edc6c4fa088a74bef98d55cc93ffa387d4f7b2d.zip
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>
-rw-r--r--src/cmd/internal/obj/ppc64/obj9.go63
1 files changed, 35 insertions, 28 deletions
diff --git a/src/cmd/internal/obj/ppc64/obj9.go b/src/cmd/internal/obj/ppc64/obj9.go
index c2722b0afb..ee93fe048b 100644
--- a/src/cmd/internal/obj/ppc64/obj9.go
+++ b/src/cmd/internal/obj/ppc64/obj9.go
@@ -294,9 +294,9 @@ func (c *ctxt9) rewriteToUseGot(p *obj.Prog) {
// BL (LR)
var sym *obj.LSym
if p.As == obj.ADUFFZERO {
- sym = c.ctxt.Lookup("runtime.duffzero")
+ sym = c.ctxt.LookupABI("runtime.duffzero", obj.ABIInternal)
} else {
- sym = c.ctxt.Lookup("runtime.duffcopy")
+ sym = c.ctxt.LookupABI("runtime.duffcopy", obj.ABIInternal)
}
offset := p.To.Offset
p.As = AMOVD
@@ -687,7 +687,6 @@ func preprocess(ctxt *obj.Link, cursym *obj.LSym, newprog obj.ProgAlloc) {
q.From.Reg = REG_LR
q.To.Type = obj.TYPE_REG
q.To.Reg = REGTMP
-
prologueEnd = q
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.Offset = 4 * int64(c.ctxt.Arch.PtrSize) // G.panic
q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_R3
+ q.To.Reg = REG_R22
q = obj.Appendp(q, c.newprog)
q.As = ACMP
q.From.Type = obj.TYPE_REG
q.From.Reg = REG_R0
q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_R3
+ q.To.Reg = REG_R22
q = obj.Appendp(q, c.newprog)
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.As = AMOVD
q.From.Type = obj.TYPE_MEM
- q.From.Reg = REG_R3
+ q.From.Reg = REG_R22
q.From.Offset = 0 // Panic.argp
q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_R4
+ q.To.Reg = REG_R23
q = obj.Appendp(q, c.newprog)
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.Reg = REGSP
q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_R5
+ q.To.Reg = REG_R24
q = obj.Appendp(q, c.newprog)
q.As = ACMP
q.From.Type = obj.TYPE_REG
- q.From.Reg = REG_R4
+ q.From.Reg = REG_R23
q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_R5
+ q.To.Reg = REG_R24
q = obj.Appendp(q, c.newprog)
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.Reg = REGSP
q.To.Type = obj.TYPE_REG
- q.To.Reg = REG_R6
+ q.To.Reg = REG_R25
q = obj.Appendp(q, c.newprog)
q.As = AMOVD
q.From.Type = obj.TYPE_REG
- q.From.Reg = REG_R6
+ q.From.Reg = REG_R25
q.To.Type = obj.TYPE_MEM
- q.To.Reg = REG_R3
+ q.To.Reg = REG_R22
q.To.Offset = 0 // Panic.argp
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 {
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.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.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.
// 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.From.Type = obj.TYPE_REG
- p.From.Reg = REG_R3
+ p.From.Reg = REG_R22
p.To.Type = obj.TYPE_REG
p.To.Reg = REGSP
} else {
@@ -1108,14 +1107,14 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.From.Type = obj.TYPE_CONST
p.From.Offset = offset
p.To.Type = obj.TYPE_REG
- p.To.Reg = REG_R4
+ p.To.Reg = REG_R23
p = obj.Appendp(p, c.newprog)
p.As = ACMPU
p.From.Type = obj.TYPE_REG
p.From.Reg = REGSP
p.To.Type = obj.TYPE_REG
- p.To.Reg = REG_R4
+ p.To.Reg = REG_R23
}
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.Reg = REGSP
p.To.Type = obj.TYPE_REG
- p.To.Reg = REG_R4
+ p.To.Reg = REG_R23
p = obj.Appendp(p, c.newprog)
p.As = ACMPU
p.From.Type = obj.TYPE_REG
- p.From.Reg = REG_R3
+ p.From.Reg = REG_R22
p.To.Type = obj.TYPE_REG
- p.To.Reg = REG_R4
+ p.To.Reg = REG_R23
}
// q1: BLT done
@@ -1151,17 +1150,25 @@ func (c *ctxt9) stacksplit(p *obj.Prog, framesize int32) *obj.Prog {
p.As = ABLT
p.To.Type = obj.TYPE_BRANCH
- // MOVD LR, R5
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.From.Type = obj.TYPE_REG
p.From.Reg = REG_LR
p.To.Type = obj.TYPE_REG
p.To.Reg = REG_R5
- if q != nil {
- q.To.SetTarget(p)
- }
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
// 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.
-
- // MOVD R12, 8(SP)
+ // MOVD R2, 8(SP)
p = obj.Appendp(p, c.newprog)
p.As = AMOVD
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 = 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
p = obj.Appendp(p, c.newprog)