X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Futil%2Fbitscan.h;h=611e812059696c10c2d82bb171c57343cff1dd71;hb=1966d9ff412359c4189601231ca9182071bef285;hp=4999b744d1d24141ad8e552340bef4c827f882fe;hpb=c3b66566760dd44eaeed9e4df13687dc3ee69bd9;p=mesa.git diff --git a/src/util/bitscan.h b/src/util/bitscan.h index 4999b744d1d..611e8120596 100644 --- a/src/util/bitscan.h +++ b/src/util/bitscan.h @@ -29,7 +29,9 @@ #ifndef BITSCAN_H #define BITSCAN_H +#include #include +#include #if defined(_MSC_VER) #include @@ -50,7 +52,7 @@ extern "C" { #define ffs __builtin_ffs #elif defined(_MSC_VER) && (_M_IX86 || _M_ARM || _M_AMD64 || _M_IA64) static inline -int ffs(unsigned i) +int ffs(int i) { unsigned long index; if (_BitScanForward(&index, i)) @@ -60,14 +62,14 @@ int ffs(unsigned i) } #else extern -int ffs(unsigned i); +int ffs(int i); #endif #ifdef HAVE___BUILTIN_FFSLL #define ffsll __builtin_ffsll #elif defined(_MSC_VER) && (_M_AMD64 || _M_ARM || _M_IA64) static inline int -ffsll(uint64_t i) +ffsll(long long int i) { unsigned long index; if (_BitScanForward64(&index, i)) @@ -77,7 +79,7 @@ ffsll(uint64_t i) } #else extern int -ffsll(uint64_t val); +ffsll(long long int val); #endif @@ -134,7 +136,7 @@ u_bit_scan_consecutive_range(unsigned *mask, int *start, int *count) static inline void u_bit_scan_consecutive_range64(uint64_t *mask, int *start, int *count) { - if (*mask == ~0llu) { + if (*mask == ~0ull) { *start = 0; *count = 64; *mask = 0; @@ -146,6 +148,94 @@ 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); +#elif defined(_MSC_VER) && (_M_IX86 || _M_ARM || _M_AMD64 || _M_IA64) + unsigned long index; + if (_BitScanReverse(&index, u)) + return index + 1; + else + return 0; +#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); +#elif defined(_MSC_VER) && (_M_AMD64 || _M_ARM || _M_IA64) + unsigned long index; + if (_BitScanReverse64(&index, u)) + return index + 1; + else + return 0; +#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; +} + +static inline uint64_t +u_bit_consecutive64(unsigned start, unsigned count) +{ + assert(start + count <= 64); + if (count == 64) + return ~(uint64_t)0; + return (((uint64_t)1 << count) - 1) << start; +} + + #ifdef __cplusplus } #endif