diff options
author | Mathias Fröhlich <[email protected]> | 2016-08-02 08:46:04 +0200 |
---|---|---|
committer | Mathias Fröhlich <[email protected]> | 2016-08-09 21:20:46 +0200 |
commit | 027cbf00f248bda325521db8f56a3718898da46b (patch) | |
tree | 5e5cce2c268223053e4504f921c5143277f51b3c /src/util | |
parent | e4cb3af524cb02ec7cd23a64da033cfb7193a3cb (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')
-rw-r--r-- | src/util/bitscan.h | 68 |
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 |