Gabriel B. has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/67670?usp=email )

Change subject: base: Generalize findLsbSet to std::bitset<N>
......................................................................

base: Generalize findLsbSet to std::bitset<N>

Change-Id: I2ec59ab9cda2243666def09e3414d8ef75197d49
---
M src/base/bitfield.hh
1 file changed, 63 insertions(+), 26 deletions(-)



diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh
index 288c5ca..645a77b 100644
--- a/src/base/bitfield.hh
+++ b/src/base/bitfield.hh
@@ -41,9 +41,11 @@
 #ifndef __BASE_BITFIELD_HH__
 #define __BASE_BITFIELD_HH__

+#include <bitset>
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
+#include <limits>
 #include <type_traits>

 namespace gem5
@@ -289,38 +291,64 @@

 /**
  * Returns the bit position of the LSB that is set in the input
+ * That function will either use a builting that exploit a "count trailing
+ * zeros" instruction or use a bit-fidling algorithm explained bellow.
  *
  * @ingroup api_bitfield
  */
 constexpr int
-findLsbSet(uint64_t val)
+findLsbSet(uint64_t val) {
+    if (val == 0) return 64;
+#ifndef __has_builtin
+#define __has_builtin(foo) 0
+#endif
+#if defined(__GNUC__) || \
+    (defined(__clang__) && __has_builtin(__builtin_ctz))
+    if constexpr (sizeof(unsigned long long) == sizeof(val)) {
+        return __builtin_ctzll(val);
+    }
+#endif
+ // Create a mask with trailing zeros flipped to 1, lsbset flipped to 0 and
+    // the rest unchanged. This effectively is equivalent to doing -1.
+    // e.g.: 0101000 - 1 = 0100111
+    auto mask = val - 1;
+    // This will create a mask of ones from lsb set to last bit
+    // e.g.: 0101000 ^ 0100111 = 00001111
+    auto masked = val ^ mask;
+ // Shift that mask to that there is a 1 where there was 0 after the lsb set
+    // before
+    // e.g.: 00001111 >> 1 = 00000111 (val is 0101000 in the example)
+    auto ones = masked >> 1;
+ // Number of bit set is the lsb set. This operation should be optimized by
+    // the compiler without unsing intrinsics.
+    return std::bitset<64>(ones).count();
+}
+
+template<size_t N>
+constexpr int
+findLsbSet(std::bitset<N> bs)
 {
-    int lsb = 0;
-    if (!val)
-        return sizeof(val) * 8;
-    if (!bits(val, 31, 0)) {
-        lsb += 32;
-        val >>= 32;
+    if constexpr (N <= 64) {
+        return findLsbSet(bs.to_ullong());
+    } else {
+        if (bs.none()) return N;
+        // Mask of ones
+ constexpr std::bitset<N> mask(std::numeric_limits<uint64_t>::max());
+        // Is the lsb set in the rightmost 64 bits ?
+        auto nextQword{bs & mask};
+        int i{0};
+        while (nextQword.none()) {
+            // If yes, shift by 64 bits and repeat
+            i += 64;
+            bs >>= 64;
+            nextQword = bs & mask;
+        }
+ // If yes, account for the the i 64-bit shifts and add the remaining + // using the 4 bit implementation. Store in intermediate variable to
+        // ensure valid conversion from ullong to uint64_t.
+        uint64_t remaining{nextQword.to_ullong()};
+        return i + findLsbSet(remaining);
     }
-    if (!bits(val, 15, 0)) {
-        lsb += 16;
-        val >>= 16;
-    }
-    if (!bits(val, 7, 0)) {
-        lsb += 8;
-        val >>= 8;
-    }
-    if (!bits(val, 3, 0)) {
-        lsb += 4;
-        val >>= 4;
-    }
-    if (!bits(val, 1, 0)) {
-        lsb += 2;
-        val >>= 2;
-    }
-    if (!bits(val, 0, 0))
-        lsb += 1;
-    return lsb;
 }

 /**

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/67670?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I2ec59ab9cda2243666def09e3414d8ef75197d49
Gerrit-Change-Number: 67670
Gerrit-PatchSet: 1
Gerrit-Owner: Gabriel B. <gabriel.bus...@arteris.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org

Reply via email to