diff --git a/src/cmd/compile/internal/ppc64/ggen.go b/src/cmd/compile/internal/ppc64/ggen.go index 3ae6422bf9..7877be3336 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 31fbb7f7bf..70ce9050b6 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) */