]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: fix mtocrf, cleanup other CR ops
authorPaul E. Murphy <murp@ibm.com>
Thu, 26 Aug 2021 22:14:12 +0000 (17:14 -0500)
committerLynn Boger <laboger@linux.vnet.ibm.com>
Mon, 11 Oct 2021 16:48:22 +0000 (16:48 +0000)
Fix "MOVW CRx, Rx" and "MOVFL Rx, constant", The FXM field was not
encoded correctly.

Generate mtocrf instead of mtcrf when a CRx argument is used. This
form is much faster.

Simplify several conditional statements which test if the register
argument is REG_CR or one of REG_CRx if the tested argument is known
to be matched as C_CREG. Likewise, a4 is (the From3 arg) is always
TYPE_NONE in the existing optab entries for type_ 69.

Change-Id: I3a4749b1cbfdfab6a2616586ae59e932e01dae50
Reviewed-on: https://go-review.googlesource.com/c/go/+/352789
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/internal/obj/ppc64/asm9.go

index 28ceb621cb3315d643f0c51f88858abc59587dab..b9da48acdd7c41540206936cf6fd5726281e3d47 100644 (file)
@@ -751,4 +751,17 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        MOVD XER, R3                    // 7c6102a6
        MOVFL CR3, CR1                  // 4c8c0000
 
+       MOVW CR0, R1                    // 7c380026
+       MOVW CR7, R1                    // 7c301026
+       MOVW CR, R1                     // 7c200026
+
+       MOVW R1, CR                     // 7c2ff120
+       MOVFL R1, CR                    // 7c2ff120
+       MOVW R1, CR2                    // 7c320120
+       MOVFL R1, CR2                   // 7c320120
+       MOVFL R1, $255                  // 7c2ff120
+       MOVFL R1, $1                    // 7c301120
+       MOVFL R1, $128                  // 7c380120
+       MOVFL R1, $3                    // 7c203120
+
        RET
index ff94fa72c75830a28c54e2afb48bb3d629e6c1df..0901d647929daf984b2bc679ea3d831bf41cdac8 100644 (file)
@@ -36,6 +36,7 @@ import (
        "fmt"
        "log"
        "math"
+       "math/bits"
        "sort"
 )
 
@@ -3353,32 +3354,30 @@ func (c *ctxt9) asmout(p *obj.Prog, o *Optab, out []uint32) {
                o1 = AOP_RRR(o1, uint32(r), 0, 0) | (uint32(v)&0x1f)<<16 | ((uint32(v)>>5)&0x1f)<<11
 
        case 67: /* mcrf crfD,crfS */
-               if p.From.Type != obj.TYPE_REG || p.From.Reg < REG_CR0 || REG_CR7 < p.From.Reg || p.To.Type != obj.TYPE_REG || p.To.Reg < REG_CR0 || REG_CR7 < p.To.Reg {
-                       c.ctxt.Diag("illegal CR field number\n%v", p)
+               if p.From.Reg == REG_CR || p.To.Reg == REG_CR {
+                       c.ctxt.Diag("CR argument must be a conditional register field (CR0-CR7)\n%v", p)
                }
                o1 = AOP_RRR(OP_MCRF, ((uint32(p.To.Reg) & 7) << 2), ((uint32(p.From.Reg) & 7) << 2), 0)
 
        case 68: /* mfcr rD; mfocrf CRM,rD */
-               if p.From.Type == obj.TYPE_REG && REG_CR0 <= p.From.Reg && p.From.Reg <= REG_CR7 {
-                       v := int32(1 << uint(7-(p.To.Reg&7)))                                 /* CR(n) */
-                       o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) | 1<<20 | uint32(v)<<12 /* new form, mfocrf */
-               } else {
-                       o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /* old form, whole register */
-               }
-
-       case 69: /* mtcrf CRM,rS */
-               var v int32
-               if p.From3Type() != obj.TYPE_NONE {
-                       if p.To.Reg != 0 {
-                               c.ctxt.Diag("can't use both mask and CR(n)\n%v", p)
-                       }
-                       v = c.regoff(p.GetFrom3()) & 0xff
-               } else {
-                       if p.To.Reg == 0 {
-                               v = 0xff /* CR */
-                       } else {
-                               v = 1 << uint(7-(p.To.Reg&7)) /* CR(n) */
-                       }
+               o1 = AOP_RRR(OP_MFCR, uint32(p.To.Reg), 0, 0) /*  form, whole register */
+               if p.From.Reg != REG_CR {
+                       v := uint32(1) << uint(7-(p.From.Reg&7)) /* CR(n) */
+                       o1 |= 1<<20 | v<<12                      /* new form, mfocrf */
+               }
+
+       case 69: /* mtcrf CRM,rS, mtocrf CRx,rS */
+               var v uint32
+               if p.To.Reg == REG_CR {
+                       v = 0xff
+               } else if p.To.Offset != 0 { // MOVFL gpr, constant
+                       v = uint32(p.To.Offset)
+               } else { // p.To.Reg == REG_CRx
+                       v = 1 << uint(7-(p.To.Reg&7))
+               }
+               // Use mtocrf form if only one CR field moved.
+               if bits.OnesCount32(v) == 1 {
+                       v |= 1 << 8
                }
 
                o1 = AOP_RRR(OP_MTCRF, uint32(p.From.Reg), 0, 0) | uint32(v)<<12