X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fbase%2Fbitfield.hh;h=5a98b13c75e219383499e5ce4de467a1fe7389ad;hb=97887eb6dc9e548c9b5719727fd4783ef157917c;hp=28093a5d44e45e8732f885eefcfdd56b0b98b666;hpb=709d859530325f28b904001f5a55dbdec2bad199;p=gem5.git diff --git a/src/base/bitfield.hh b/src/base/bitfield.hh index 28093a5d4..5a98b13c7 100644 --- a/src/base/bitfield.hh +++ b/src/base/bitfield.hh @@ -92,7 +92,7 @@ mask(int first, int last) */ template inline -int64_t +uint64_t sext(uint64_t val) { int sign_bit = bits(val, N-1, N-1); @@ -161,4 +161,54 @@ findMsbSet(uint64_t val) { return msb; } +/** + * Returns the bit position of the LSB that is set in the input + */ +inline int +findLsbSet(uint64_t val) { + int lsb = 0; + if (!val) + return sizeof(val) * 8; + if (!bits(val, 31,0)) { lsb += 32; val >>= 32; } + 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; +} + +/** + * Checks if a number is a power of two, or zero. + */ +template +inline bool +isPow2(T v) { + return (v & (v - 1)) == (T)0; +} + +/** + * Returns the number of set ones in the provided value. + * PD algorithm from + * http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel + */ +inline int +popCount(uint64_t val) { +#ifndef __has_builtin + #define __has_builtin(foo) 0 +#endif +#if defined(__GNUC__) || (defined(__clang__) && __has_builtin(__builtin_popcountl)) + return __builtin_popcountl(val); +#else + const uint64_t m1 = 0x5555555555555555; // ..010101b + const uint64_t m2 = 0x3333333333333333; // ..110011b + const uint64_t m4 = 0x0f0f0f0f0f0f0f0f; // ..001111b + const uint64_t sum = 0x0101010101010101; + + val -= (val >> 1) & m1; // 2 bits count -> 2 bits + val = (val & m2) + ((val >> 2) & m2); // 4 bits count -> 4 bits + val = (val + (val >> 4)) & m4; // 8 bits count -> 8 bits + return (val * sum) >> 56; // horizontal sum +#endif // defined(__GNUC__) || (defined(__clang__) && __has_builtin(__builtin_popcountl)) +} #endif // __BASE_BITFIELD_HH__