Size findLastBit(Size a) { #ifdef __GNUC__ #ifdef __X64__ return sizeof(a)*8 - 1 - __builtin_clzl(a); #else return sizeof(a)*8 - 1 - __builtin_clz(a); #endif #elif defined(_MSC_VER) unsigned long pos; #ifdef __X64__ _BitScanReverse64(&pos, a); #else _BitScanReverse(&pos, a); #endif return sizeof(a)*8 - 1 - pos; #else //Very naive implementation. Size c = sizeof(a)*8 - 1; const Size mask = 1 << c; while(!(a & mask)) { a <<= 1; c--; } return c; #endif }
// log2 - returns -1 if x==0, otherwise log2(x) inline int log2(size_t x) { if (x == 0) return -1; #if defined(__GNUC__) # ifdef REALM_PTR_64 return 63 - __builtin_clzll(x); // returns int # else return 31 - __builtin_clz(x); // returns int # endif #elif defined(_WIN32) unsigned long index = 0; # ifdef REALM_PTR_64 unsigned char c = _BitScanReverse64(&index, x); // outputs unsigned long # else unsigned char c = _BitScanReverse(&index, x); // outputs unsigned long # endif return static_cast<int>(index); #else // not __GNUC__ and not _WIN32 int r = 0; while (x >>= 1) { r++; } return r; #endif }
bool uint2048::highest_bit(uint16_t* index) const{ auto res = 0ul; auto part = 0ull; /* loop down from the most significant ull and find the first one that is non-zero. use the intrinsic function _BitScanReverse64 to find the index of that ull's most significant bit. set the index pointer's value to: 64 * num of ulls below + the index resulting from _BitScanReverse64 return true if all ulls are found to be zero, set the index to 0 and return false. */ for (auto i = 0u; i < 32u; ++i){ part = parts_[31u - i]; if (part > 0u){ // intrinsic function // bsr instruction // find index of most significant bit _BitScanReverse64(&res, part); // could use FMA here? *index = ((31u - i) * 64u) + static_cast<uint16_t>(res); return true; } } *index = 0u; return false; }
static inline int clzll(unsigned long long input_num) { unsigned long index; #ifdef _WIN64 _BitScanReverse64(&index, input_num); #else // if we must support 32-bit Windows if (input_num > 0xFFFFFFF) { _BitScanReverse(&index, (uint32_t)(input_num >> 32)); } else {
int flsll(long long value) { unsigned long index = 0; unsigned char isNonZero; isNonZero = _BitScanReverse64(&index, value); return isNonZero ? index + 1 : 0; }
static unsigned __inline ctz (unsigned long x) { unsigned r; #if defined (WORDSIZE) && (WORDSIZE == 64) _BitScanReverse64 (&r, x); #else _BitScanReverse32 (&r, x); #endif return (r); }
size_t alignToIndex(size_t align) { ASSERT(align > 0, "Can not align to 0 alignment"); unsigned long index; unsigned char isNonzero; isNonzero = _BitScanReverse64(&index, static_cast<unsigned long long>(align)); if (isNonzero) return index; else return 0; }
inline bitcount_t flog2(uint64_t v) { #if defined(_M_X64) || defined(_M_ARM) || defined(_M_ARM64) unsigned long i; _BitScanReverse64(&i, v); return i; #else // 32-bit x86 uint32_t high = v >> 32; uint32_t low = uint32_t(v); return high ? 32+flog2(high) : flog2(low); #endif }
static int __inline rd_ctz64(u64 x) { #ifdef _M_X64 int r = 0; if (_BitScanReverse64(&r, x)) return r; else return 64; #else int r; if ((r = rd_ctz(x & 0xffffffff)) < 32) return r; return 32 + rd_ctz(x >> 32); #endif }
__INTRIN_INLINE bool bsr64(unsigned long* const index, const uint64_t mask) { #if defined(__GNUC__) || defined(__clang__) if (mask) { *index = (unsigned long)(63 - __builtin_clzll(mask)); return true; } else { return false; } #elif defined(_MSC_VER) return _BitScanReverse64(index, mask) != 0; #else # error Unsupported platform #endif }
// 按 bit 数前面 0 的个数 int Clz(size_t x) { #ifdef _MSC_VER unsigned long r = 0; # ifdef XXLIB_64BIT _BitScanReverse64(&r, x); return 63 - r; # else _BitScanReverse(&r, x); return 31 - r; # endif #else # ifdef XXLIB_64BIT return __builtin_clzl(x); # else return __builtin_clz(x); # endif #endif }
unsigned char test_BitScanReverse64(unsigned LONG *Index, unsigned __int64 Mask) { return _BitScanReverse64(Index, Mask); }
BOOST_FORCEINLINE unsigned find_msb(Unsigned mask, const mpl::int_<2>&) { unsigned long result; _BitScanReverse64(&result, mask); return result; }