From 2716dfd99580b63dc3b0b2dba4a31e50649f4922 Mon Sep 17 00:00:00 2001 From: Lynn Boger Date: Thu, 23 Mar 2023 13:19:02 -0500 Subject: [PATCH] cmd/internal/obj/ppc64: fix incorrect base reg causing segv This fixes a segv that was reported due to building minio. The problem occurred because of an incorrect selection of the base register, which was introduced by CL 306369. Fixes #59196 Change-Id: Ieb77b2afa8fb4e6f3943df5ce138679f6750d376 Reviewed-on: https://go-review.googlesource.com/c/go/+/478920 Run-TryBot: Lynn Boger Reviewed-by: Dmitri Shuralyov Reviewed-by: Archana Ravindar Reviewed-by: Heschi Kreinick Auto-Submit: Lynn Boger Reviewed-by: Paul Murphy TryBot-Result: Gopher Robot --- src/cmd/internal/obj/ppc64/asm9.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index dbc1a5b81950f..9516ea3cd6155 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -3288,8 +3288,15 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) { o1 |= uint32((v >> 16) & 0x3FFFF) o2 |= uint32(v & 0xFFFF) } else { - o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(v))) - o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(p.To.Reg), uint32(v)) + if o.a6 == C_REG { + // Reuse the base register when loading a GPR (C_REG) to avoid + // using REGTMP (R31) when possible. + o1 = AOP_IRR(OP_ADDIS, uint32(p.To.Reg), uint32(r), uint32(high16adjusted(v))) + o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(p.To.Reg), uint32(v)) + } else { + o1 = AOP_IRR(OP_ADDIS, uint32(REGTMP), uint32(r), uint32(high16adjusted(v))) + o2 = AOP_IRR(c.opload(p.As), uint32(p.To.Reg), uint32(REGTMP), uint32(v)) + } } // Sign extend MOVB if needed @@ -3681,8 +3688,8 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) { rel.Type = objabi.R_ADDRPOWER_TOCREL_DS } default: - reuseBaseReg := p.As != AFMOVD && p.As != AFMOVS - // Reuse To.Reg as base register if not FP move. + reuseBaseReg := o.a6 == C_REG + // Reuse To.Reg as base register if it is a GPR. o1, o2, rel = c.symbolAccess(p.From.Sym, v, p.To.Reg, inst, reuseBaseReg) }