]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: generate MOVD mask constants in register
authorPaul E. Murphy <murp@ibm.com>
Tue, 19 Sep 2023 22:01:28 +0000 (17:01 -0500)
committerPaul Murphy <murp@ibm.com>
Thu, 5 Oct 2023 14:03:32 +0000 (14:03 +0000)
Add a new form of RLDC which maps directly to the ISA definition
of rldc: RLDC Rs, $sh, $mb, Ra. This is used to generate mask
constants described below.

Using MOVD $-1, Rx; RLDC Rx, $sh, $mb, Rx, any mask constant
can be generated. A mask is a contiguous series of 1 bits, which
may wrap.

Change-Id: Ifcaae1114080ad58b5fdaa3e5fc9019e2051f282
Reviewed-on: https://go-review.googlesource.com/c/go/+/531120
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Run-TryBot: Paul Murphy <murp@ibm.com>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/internal/obj/ppc64/asm9.go
src/cmd/internal/obj/ppc64/obj9.go
test/codegen/constants.go

index a8b9e33db3d88afab47cf56d812584b1b438af97..6f5182e1f93c003464ddcdafe739a7bd08c89204 100644 (file)
@@ -42,6 +42,10 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        MOVD $2199090364416, R5         // 60058001
        // Hex constant 0xFFFFFE0004000000
        MOVD $-2198956146688, R5        // 38a08001
+       // TODO: On GOPPC64={power8,power9}, this is preprocessed into MOVD $-1, R5; RLDC R5, $33, $63, R5.
+       //       This only captures the MOVD. Should the RLDC be appended to the encoding by the test?
+       // Hex constant 0xFFFFFFFE00000001
+       MOVD $-8589934591, R5           // 38a0ffff or 0602000038a00001
 
        MOVD 8(R3), R4                  // e8830008
        MOVD (R3)(R4), R5               // 7ca4182a
@@ -426,6 +430,10 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        RLDIMI $0, R4, $7, R6           // 788601cc
        RLDIMICC $0, R4, $7, R6         // 788601cd
        RLDC $0, R4, $15, R6            // 78860728
+       RLDC R3, $32, $12, R4           // 7864030a
+       RLDC R3, $8, $32, R4            // 78644028
+       RLDCCC R3, $32, $12, R4         // 7864030b
+       RLDCCC R3, $8, $32, R4          // 78644029
        RLDCCC $0, R4, $15, R6          // 78860729
        RLDCL $0, R4, $7, R6            // 78860770
        RLDCLCC $0, R4, $15, R6         // 78860721
index 65b8c583d91927ce980b622cc3f5d40d46680622..ef683f69aa3b6420863e4bf9307000bcf59c800f 100644 (file)
@@ -194,6 +194,7 @@ var optabBase = []Optab{
        {as: ACLRLSLWI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 62, size: 4},
        {as: ARLDMI, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 30, size: 4},
        {as: ARLDC, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
+       {as: ARLDC, a1: C_REG, a3: C_U8CON, a4: C_U8CON, a6: C_REG, type_: 9, size: 4},
        {as: ARLDCL, a1: C_SCON, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 29, size: 4},
        {as: ARLDCL, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
        {as: ARLDICL, a1: C_REG, a2: C_REG, a3: C_LCON, a6: C_REG, type_: 14, size: 4},
@@ -2723,6 +2724,14 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
                // Sign extend MOVB operations. This is ignored for other cases (o.size == 4).
                o2 = LOP_RRR(OP_EXTSB, uint32(p.To.Reg), uint32(p.To.Reg), 0)
 
+       case 9: /* RLDC Ra, $sh, $mb, Rb */
+               sh := uint32(p.RestArgs[0].Addr.Offset) & 0x3F
+               mb := uint32(p.RestArgs[1].Addr.Offset) & 0x3F
+               o1 = AOP_RRR(c.opirr(p.As), uint32(p.From.Reg), uint32(p.To.Reg), (uint32(sh) & 0x1F))
+               o1 |= (sh & 0x20) >> 4 // sh[5] is placed in bit 1.
+               o1 |= (mb & 0x1F) << 6 // mb[0:4] is placed in bits 6-10.
+               o1 |= (mb & 0x20)      // mb[5] is placed in bit 5
+
        case 10: /* sub Ra,[Rb],Rd => subf Rd,Ra,Rb */
                r := int(p.Reg)
 
index df0c36cde0fca662f379b39e97600f1680e59978..ab397892c2d89f86ff890d38403452dbf846dbb9 100644 (file)
@@ -39,6 +39,39 @@ import (
        "math/bits"
 )
 
+// Test if this value can encoded as a mask for
+// li -1, rx; rlic rx,rx,sh,mb.
+// Masks can also extend from the msb and wrap to
+// the lsb too. That is, the valid masks are 32 bit strings
+// of the form: 0..01..10..0 or 1..10..01..1 or 1...1
+func isPPC64DoublewordRotateMask(v64 int64) bool {
+       // Isolate rightmost 1 (if none 0) and add.
+       v := uint64(v64)
+       vp := (v & -v) + v
+       // Likewise, for the wrapping case.
+       vn := ^v
+       vpn := (vn & -vn) + vn
+       return (v&vp == 0 || vn&vpn == 0) && v != 0
+}
+
+// Encode a doubleword rotate mask into mb (mask begin) and
+// me (mask end, inclusive). Note, POWER ISA labels bits in
+// big endian order.
+func encodePPC64RLDCMask(mask int64) (mb, me int) {
+       // Determine boundaries and then decode them
+       mb = bits.LeadingZeros64(uint64(mask))
+       me = 64 - bits.TrailingZeros64(uint64(mask))
+       mbn := bits.LeadingZeros64(^uint64(mask))
+       men := 64 - bits.TrailingZeros64(^uint64(mask))
+       // Check for a wrapping mask (e.g bits at 0 and 63)
+       if mb == 0 && me == 64 {
+               // swap the inverted values
+               mb, me = men, mbn
+       }
+       // Note, me is inclusive.
+       return mb, me - 1
+}
+
 func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
        p.From.Class = 0
        p.To.Class = 0
@@ -97,11 +130,21 @@ func progedit(ctxt *obj.Link, p *obj.Prog, newprog obj.ProgAlloc) {
                                // Rewrite this value into MOVD $const>>shift, Rto; SLD $shift, Rto
                                q := obj.Appendp(p, c.newprog)
                                q.As = ASLD
-                               q.From.Type = obj.TYPE_CONST
-                               q.From.Offset = int64(shift)
+                               q.From.SetConst(int64(shift))
                                q.To = p.To
                                p.From.Offset >>= shift
                                p = q
+                               // Is this constant a mask value? If so, generate MOVD $-1, Rto; RLDIC Rto, ^me, mb, Rto
+                       } else if isPPC64DoublewordRotateMask(val) {
+                               mb, me := encodePPC64RLDCMask(val)
+                               q := obj.Appendp(p, c.newprog)
+                               q.As = ARLDC
+                               q.AddRestSourceConst((^int64(me)) & 0x3F)
+                               q.AddRestSourceConst(int64(mb))
+                               q.From = p.To
+                               q.To = p.To
+                               p.From.Offset = -1
+                               p = q
                        } else {
                                // Load the constant from memory.
                                p.From.Type = obj.TYPE_MEM
index 756aeda5f7f1b1ab554dc94840c32c7b4a8277b9..3ce17d0ad3a65b0318834e471371ad8c83827d2d 100644 (file)
@@ -6,6 +6,7 @@
 
 package codegen
 
+// A uint16 or sint16 constant shifted left.
 func shifted16BitConstants(out [64]uint64) {
        // ppc64x: "MOVD\t[$]8193,", "SLD\t[$]27,"
        out[0] = 0x0000010008000000
@@ -15,11 +16,18 @@ func shifted16BitConstants(out [64]uint64) {
        out[2] = 0xFFFF000000000000
        // ppc64x: "MOVD\t[$]65535", "SLD\t[$]44,"
        out[3] = 0x0FFFF00000000000
+}
 
-       // ppc64x: "MOVD\t[$]i64.fffff00000000001[(]SB[)]"
-       out[4] = 0xFFFFF00000000001
-       // ppc64x: "MOVD\t[$]i64.fffff80000000001[(]SB[)]"
-       out[5] = 0xFFFFF80000000001
-       // ppc64x: "MOVD\t[$]i64.0ffff80000000000[(]SB[)]"
-       out[6] = 0x0FFFF80000000000
+// A contiguous set of 1 bits, potentially wrapping.
+func contiguousMaskConstants(out [64]uint64) {
+       // ppc64x: "MOVD\t[$]-1", "RLDC\tR[0-9]+, [$]44, [$]63,"
+       out[0] = 0xFFFFF00000000001
+       // ppc64x: "MOVD\t[$]-1", "RLDC\tR[0-9]+, [$]43, [$]63,"
+       out[1] = 0xFFFFF80000000001
+       // ppc64x: "MOVD\t[$]-1", "RLDC\tR[0-9]+, [$]43, [$]4,"
+       out[2] = 0x0FFFF80000000000
+       // ppc64x/power8: "MOVD\t[$]-1", "RLDC\tR[0-9]+, [$]33, [$]63,"
+       // ppc64x/power9: "MOVD\t[$]-1", "RLDC\tR[0-9]+, [$]33, [$]63,"
+       // ppc64x/power10: "MOVD\t[$]-8589934591,"
+       out[3] = 0xFFFFFFFE00000001
 }