arch-power: Add fixed-point logical count zeros instructions
authorSandipan Das <sandipan@linux.vnet.ibm.com>
Thu, 7 Jun 2018 09:39:04 +0000 (15:09 +0530)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 24 Jan 2021 03:26:04 +0000 (03:26 +0000)
This adds the following logical instructions:
  * Count Trailing Zeros Word (cnttzw[.])
  * Count Leading Zeros Doubleword (cntlzd[.])
  * Count Trailing Zeros Doubleword (cnttzd[.])

Change-Id: I4bcf090178d9241f230509ba55e8e58f5e7794ac
Signed-off-by: Sandipan Das <sandipan@linux.vnet.ibm.com>
src/arch/power/insts/integer.cc
src/arch/power/insts/integer.hh
src/arch/power/isa/decoder.isa

index b49da47e153b7e99f4de7f9b70e045a231833453..2f7e15909a66b5b44b2fb771f131373542c91df1 100644 (file)
@@ -295,7 +295,10 @@ IntLogicOp::generateDisassembly(
     } else if (!myMnemonic.compare("extsb") ||
                !myMnemonic.compare("extsh") ||
                !myMnemonic.compare("extsw") ||
-               !myMnemonic.compare("cntlzw")) {
+               !myMnemonic.compare("cntlzw") ||
+               !myMnemonic.compare("cntlzd") ||
+               !myMnemonic.compare("cnttzw") ||
+               !myMnemonic.compare("cnttzd")) {
         printSecondSrc = false;
     }
 
index 0cdd2b4570a161d8c0122e9c7e26c515b1f06441..4129a34820a70a445109586b18bc02e0315ba27a 100644 (file)
@@ -492,6 +492,8 @@ class IntLogicOp : public IntOp
     {
     }
 
+    /* Compute the number of consecutive zero bits starting from the
+       leftmost bit and moving right in a 32-bit integer */
     inline int
     findLeadingZeros(uint32_t rs) const
     {
@@ -507,6 +509,57 @@ class IntLogicOp : public IntOp
         }
     }
 
+    /* Compute the number of consecutive zero bits starting from the
+       leftmost bit and moving right in a 64-bit integer */
+    inline int
+    findLeadingZeros(uint64_t rs) const
+    {
+        if (rs) {
+    #if defined(__GNUC__) || (defined(__clang__) && \
+                              __has_builtin(__builtin_clzll))
+            return __builtin_clzll(rs);
+    #else
+            return 63 - findMsbSet(rs);
+    #endif
+        } else {
+            return 64;
+        }
+    }
+
+    /* Compute the number of consecutive zero bits starting from the
+       rightmost bit and moving left in a 32-bit integer */
+    inline int
+    findTrailingZeros(uint32_t rs) const
+    {
+        if (rs) {
+    #if defined(__GNUC__) || (defined(__clang__) && \
+                              __has_builtin(__builtin_ctz))
+            return __builtin_ctz(rs);
+    #else
+            return findLsbSet(rs);
+    #endif
+        } else {
+            return 32;
+        }
+    }
+
+    /* Compute the number of consecutive zero bits starting from the
+       rightmost bit and moving left in a 64-bit integer */
+    inline int
+    findTrailingZeros(uint64_t rs) const
+    {
+        if (rs) {
+    #if defined(__GNUC__) || (defined(__clang__) && \
+                              __has_builtin(__builtin_ctzll))
+            return __builtin_ctzll(rs);
+    #else
+            return findLsbSet(rs);
+    #endif
+        } else {
+            return 64;
+        }
+    }
+
     std::string generateDisassembly(
             Addr pc, const SymbolTable *symtab) const override;
 };
index 6575f4f54a1162c27306eff7bbf3b2c6cff5136c..c605b697d70aa86466b803c5651ae9c1b9e03b10 100644 (file)
@@ -513,6 +513,9 @@ decode PO default Unknown::unknown() {
             922: extsh({{ Ra = Rs_sh; }}, true);
             986: extsw({{ Ra = Rs_sw; }}, true);
             26: cntlzw({{ Ra = findLeadingZeros(Rs_uw); }}, true);
+            58: cntlzd({{ Ra = findLeadingZeros(Rs); }}, true);
+            538: cnttzw({{ Ra = findTrailingZeros(Rs_uw); }}, true);
+            570: cnttzd({{ Ra = findTrailingZeros(Rs); }}, true);
 
             508: cmpb({{
                 uint64_t mask = 0xff;