]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/asm,cmd/compile: generate preferred nop on PPC64
authorPaul E. Murphy <murp@ibm.com>
Tue, 1 Mar 2022 22:30:46 +0000 (16:30 -0600)
committerPaul Murphy <murp@ibm.com>
Thu, 3 Mar 2022 14:42:03 +0000 (14:42 +0000)
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 <cherryyz@google.com>
Trust: Paul Murphy <murp@ibm.com>
Run-TryBot: Paul Murphy <murp@ibm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/compile/internal/ppc64/ggen.go
src/cmd/internal/obj/ppc64/asm9.go

index 3ae6422bf9e26b0a1fb08e1f94f3a17a8965d3f1..7877be3336b43a2b27ad3cb2c4a8957153e45c7f 100644 (file)
@@ -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
 }
index 31fbb7f7bf9723237e816982f71043bc0ba96bd7..70ce9050b698fdeefd49a8112f656fa662795c46 100644 (file)
@@ -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) */