summaryrefslogtreecommitdiffstats
path: root/src/util/bitscan.h
diff options
context:
space:
mode:
authorMathias Fröhlich <[email protected]>2016-08-02 08:46:04 +0200
committerMathias Fröhlich <[email protected]>2016-08-09 21:20:46 +0200
commit027cbf00f248bda325521db8f56a3718898da46b (patch)
tree5e5cce2c268223053e4504f921c5143277f51b3c /src/util/bitscan.h
parente4cb3af524cb02ec7cd23a64da033cfb7193a3cb (diff)
util: Move _mesa_fsl/util_last_bit into util/bitscan.h
As requested with the initial creation of util/bitscan.h now move other bitscan related functions into util. v2: Split into two patches. Signed-off-by: Mathias Fröhlich <[email protected]> Tested-by: Brian Paul <[email protected]> Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/util/bitscan.h')
-rw-r--r--src/util/bitscan.h68
1 files changed, 68 insertions, 0 deletions
diff --git a/src/util/bitscan.h b/src/util/bitscan.h
index 4999b744d1d..0743fe7d321 100644
--- a/src/util/bitscan.h
+++ b/src/util/bitscan.h
@@ -29,6 +29,7 @@
#ifndef BITSCAN_H
#define BITSCAN_H
+#include <assert.h>
#include <stdint.h>
#if defined(_MSC_VER)
@@ -146,6 +147,73 @@ u_bit_scan_consecutive_range64(uint64_t *mask, int *start, int *count)
}
+/**
+ * Find last bit set in a word. The least significant bit is 1.
+ * Return 0 if no bits are set.
+ * Essentially ffs() in the reverse direction.
+ */
+static inline unsigned
+util_last_bit(unsigned u)
+{
+#if defined(HAVE___BUILTIN_CLZ)
+ return u == 0 ? 0 : 32 - __builtin_clz(u);
+#else
+ unsigned r = 0;
+ while (u) {
+ r++;
+ u >>= 1;
+ }
+ return r;
+#endif
+}
+
+/**
+ * Find last bit set in a word. The least significant bit is 1.
+ * Return 0 if no bits are set.
+ * Essentially ffsll() in the reverse direction.
+ */
+static inline unsigned
+util_last_bit64(uint64_t u)
+{
+#if defined(HAVE___BUILTIN_CLZLL)
+ return u == 0 ? 0 : 64 - __builtin_clzll(u);
+#else
+ unsigned r = 0;
+ while (u) {
+ r++;
+ u >>= 1;
+ }
+ return r;
+#endif
+}
+
+/**
+ * Find last bit in a word that does not match the sign bit. The least
+ * significant bit is 1.
+ * Return 0 if no bits are set.
+ */
+static inline unsigned
+util_last_bit_signed(int i)
+{
+ if (i >= 0)
+ return util_last_bit(i);
+ else
+ return util_last_bit(~(unsigned)i);
+}
+
+/* Returns a bitfield in which the first count bits starting at start are
+ * set.
+ */
+static inline unsigned
+u_bit_consecutive(unsigned start, unsigned count)
+{
+ assert(start + count <= 32);
+ if (count == 32)
+ return ~0;
+ return ((1u << count) - 1) << start;
+}
+
+
#ifdef __cplusplus
}
#endif