From 86371b0360302b68c29f5eb39b02b82a52e0e341 Mon Sep 17 00:00:00 2001 From: "Paul E. Murphy" Date: Tue, 1 Mar 2022 16:30:46 -0600 Subject: [PATCH] cmd/asm,cmd/compile: generate preferred nop on PPC64 The preferred form of nop is ori 0,0,0. What was being generated was or 0,0,0. Fix a quirk in the assembler which effectively treats OR $0,Rx,Ry as OR R0,Rx,Ry, and update the compiler to generate the preferred form. Change-Id: I5ac4bf0258cff05b9eba516a767daebfc9e31bc7 Reviewed-on: https://go-review.googlesource.com/c/go/+/388974 Reviewed-by: Cherry Mui Trust: Paul Murphy Run-TryBot: Paul Murphy TryBot-Result: Gopher Robot --- src/cmd/compile/internal/ppc64/ggen.go | 7 +++---- src/cmd/internal/obj/ppc64/asm9.go | 8 +++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/cmd/compile/internal/ppc64/ggen.go b/src/cmd/compile/internal/ppc64/ggen.go index 3ae6422bf9e26..7877be3336b43 100644 --- a/src/cmd/compile/internal/ppc64/ggen.go +++ b/src/cmd/compile/internal/ppc64/ggen.go @@ -46,10 +46,9 @@ func zerorange(pp *objw.Progs, p *obj.Prog, off, cnt int64, _ *uint32) *obj.Prog } func ginsnop(pp *objw.Progs) *obj.Prog { + // Generate the preferred hardware nop: ori 0,0,0 p := pp.Prog(ppc64.AOR) - p.From.Type = obj.TYPE_REG - p.From.Reg = ppc64.REG_R0 - p.To.Type = obj.TYPE_REG - p.To.Reg = ppc64.REG_R0 + p.From = obj.Addr{Type: obj.TYPE_CONST, Offset: 0} + p.To = obj.Addr{Type: obj.TYPE_REG, Reg: ppc64.REG_R0} return p } diff --git a/src/cmd/internal/obj/ppc64/asm9.go b/src/cmd/internal/obj/ppc64/asm9.go index 31fbb7f7bf972..70ce9050b698f 100644 --- a/src/cmd/internal/obj/ppc64/asm9.go +++ b/src/cmd/internal/obj/ppc64/asm9.go @@ -2552,7 +2552,13 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) { case AROTLW: o1 = OP_RLW(OP_RLWNM, uint32(p.To.Reg), uint32(r), uint32(p.From.Reg), 0, 31) default: - o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) + if p.As == AOR && p.From.Type == obj.TYPE_CONST && p.From.Offset == 0 { + // Compile "OR $0, Rx, Ry" into ori. If Rx == Ry == 0, this is the preferred + // hardware no-op. This happens because $0 matches C_REG before C_ZCON. + o1 = LOP_IRR(OP_ORI, uint32(p.To.Reg), uint32(r), 0) + } else { + o1 = LOP_RRR(c.oprrr(p.As), uint32(p.To.Reg), uint32(r), uint32(p.From.Reg)) + } } case 7: /* mov r, soreg ==> stw o(r) */