]> Cypherpunks.ru repositories - gostls13.git/commitdiff
cmd/internal/obj/ppc64: refactor maskgen
authorPaul E. Murphy <murp@ibm.com>
Wed, 27 Sep 2023 15:42:37 +0000 (10:42 -0500)
committerPaul Murphy <murp@ibm.com>
Fri, 20 Oct 2023 19:23:58 +0000 (19:23 +0000)
Refactor maskgen into decodeMask32. This is derived from
from combining encodePPC64RotateMask and isWordRotateMask.

Also, truncate me returned from decodeMask32/64 to
be within range of [0,32/64).

Change-Id: Ie9efff93d400b3066ac85276b1ad3c57c2fcf31b
Reviewed-on: https://go-review.googlesource.com/c/go/+/536298
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Lynn Boger <laboger@linux.vnet.ibm.com>
Run-TryBot: Paul Murphy <murp@ibm.com>
Reviewed-by: Than McIntosh <thanm@google.com>
src/cmd/asm/internal/asm/testdata/ppc64.s
src/cmd/internal/obj/ppc64/asm9.go

index 6f5182e1f93c003464ddcdafe739a7bd08c89204..cc8d6c84d38df78b0f7aaa57cc6b53e334129c26 100644 (file)
@@ -409,6 +409,9 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
        EXTSHCC R3, R4                  // 7c640735
        EXTSW R3, R4                    // 7c6407b4
        EXTSWCC R3, R4                  // 7c6407b5
+       RLWMI $7, R3, $4026531855, R6   // 50663f06
+       RLWMI $7, R3, $1, R6            // 50663ffe
+       RLWMI $7, R3, $2147483648, R6   // 50663800
        RLWMI $7, R3, $65535, R6        // 50663c3e
        RLWMI $7, R3, $16, $31, R6      // 50663c3e
        RLWMICC $7, R3, $65535, R6      // 50663c3f
index 0b7c5879caf81783cff8a7e61bc2832804e5c7f3..73642bd209bee045a0e4d85dcf108cd2f04579fe 100644 (file)
@@ -2490,6 +2490,32 @@ func (c *ctxt9) symbolAccess(s *obj.LSym, d int64, reg int16, op uint32, reuse b
        return
 }
 
+// Determine the mask begin (mb) and mask end (me) values
+// for a valid word rotate mask. A valid 32 bit mask is of
+// the form 1+0*1+ or 0*1+0*.
+//
+// Note, me is inclusive.
+func decodeMask32(mask uint32) (mb, me uint32, valid bool) {
+       mb = uint32(bits.LeadingZeros32(mask))
+       me = uint32(32 - bits.TrailingZeros32(mask))
+       mbn := uint32(bits.LeadingZeros32(^mask))
+       men := uint32(32 - bits.TrailingZeros32(^mask))
+       // Check for a wrapping mask (e.g bits at 0 and 31)
+       if mb == 0 && me == 32 {
+               // swap the inverted values
+               mb, me = men, mbn
+       }
+
+       // Validate mask is of the binary form 1+0*1+ or 0*1+0*
+       // Isolate rightmost 1 (if none 0) and add.
+       v := mask
+       vp := (v & -v) + v
+       // Likewise, check for the wrapping (inverted) case.
+       vn := ^v
+       vpn := (vn & -vn) + vn
+       return mb, (me - 1) & 31, (v&vp == 0 || vn&vpn == 0) && v != 0
+}
+
 // Decompose a mask of contiguous bits into a begin (mb) and
 // end (me) value.
 //
@@ -2502,55 +2528,7 @@ func decodeMask64(mask int64) (mb, me uint32, valid bool) {
        mb = uint32(bits.LeadingZeros64(m))
        me = uint32(64 - bits.TrailingZeros64(m))
        valid = ((m&-m)+m)&m == 0 && m != 0
-       return mb, me - 1, valid
-}
-
-/*
- * 32-bit masks
- */
-func getmask(m *[2]uint32, v uint32) bool {
-       m[1] = 0
-       m[0] = 0
-       if v != ^uint32(0) && v&(1<<31) != 0 && v&1 != 0 { /* MB > ME */
-               if getmask(m, ^v) {
-                       i := m[0]
-                       m[0] = m[1] + 1
-                       m[1] = i - 1
-                       return true
-               }
-
-               return false
-       }
-
-       for i := 0; i < 32; i++ {
-               if v&(1<<uint(31-i)) != 0 {
-                       m[0] = uint32(i)
-                       for {
-                               m[1] = uint32(i)
-                               i++
-                               if i >= 32 || v&(1<<uint(31-i)) == 0 {
-                                       break
-                               }
-                       }
-
-                       for ; i < 32; i++ {
-                               if v&(1<<uint(31-i)) != 0 {
-                                       return false
-                               }
-                       }
-                       return true
-               }
-       }
-
-       return false
-}
-
-func (c *ctxt9) maskgen(p *obj.Prog, v uint32) (mb, me uint32) {
-       var m [2]uint32
-       if !getmask(&m, v) {
-               c.ctxt.Diag("cannot generate mask #%x\n%v", v, p)
-       }
-       return m[0], m[1]
+       return mb, (me - 1) & 63, valid
 }
 
 func loadu32(r int, d int64) uint32 {
@@ -3475,7 +3453,12 @@ func asmout(c *ctxt9, p *obj.Prog, o *Optab, out *[5]uint32) {
        case 63: /* rlwimi/rlwnm/rlwinm [$sh,b],s,[$mask or mb,me],a*/
                var mb, me uint32
                if len(p.RestArgs) == 1 { // Mask needs decomposed into mb and me.
-                       mb, me = c.maskgen(p, uint32(p.RestArgs[0].Addr.Offset))
+                       var valid bool
+                       // Note, optab rules ensure $mask is a 32b constant.
+                       mb, me, valid = decodeMask32(uint32(p.RestArgs[0].Addr.Offset))
+                       if !valid {
+                               c.ctxt.Diag("cannot generate mask #%x\n%v", uint64(p.RestArgs[0].Addr.Offset), p)
+                       }
                } else { // Otherwise, mask is already passed as mb and me in RestArgs.
                        mb, me = uint32(p.RestArgs[0].Addr.Offset), uint32(p.RestArgs[1].Addr.Offset)
                }