#ifndef S2_UTIL_BITS_BITS_H_
#define S2_UTIL_BITS_BITS_H_
#if defined(__i386__) || defined(__x86_64__)
#include <x86intrin.h>
#endif
#include "base/logging.h"
class Bits { … };
#if defined(__GNUC__)
inline int Bits::Log2Floor(uint32_t n) { … }
inline int Bits::Log2FloorNonZero(uint32_t n) { … }
inline int Bits::FindLSBSetNonZero(uint32_t n) { … }
inline int Bits::Log2Floor64(uint64_t n) { … }
inline int Bits::Log2FloorNonZero64(uint64_t n) { … }
inline int Bits::FindLSBSetNonZero64(uint64_t n) { … }
#elif defined(_MSC_VER)
inline int Bits::FindLSBSetNonZero(uint32_t n) {
return Bits::FindLSBSetNonZero_Portable(n);
}
inline int Bits::FindLSBSetNonZero64(uint64_t n) {
return Bits::FindLSBSetNonZero64_Portable(n);
}
inline int Bits::Log2FloorNonZero(uint32_t n) {
#ifdef _M_IX86
_asm {
bsr ebx, n
mov n, ebx
}
return n;
#else
return Bits::Log2FloorNonZero_Portable(n);
#endif
}
inline int Bits::Log2Floor(uint32_t n) {
#ifdef _M_IX86
_asm {
xor ebx, ebx
mov eax, n
and eax, eax
jz return_ebx
bsr ebx, eax
return_ebx:
mov n, ebx
}
return n;
#else
return Bits::Log2Floor_Portable(n);
#endif
}
inline int Bits::Log2Floor64(uint64_t n) {
return Bits::Log2Floor64_Portable(n);
}
inline int Bits::Log2FloorNonZero64(uint64_t n) {
return Bits::Log2FloorNonZero64_Portable(n);
}
#else
inline int Bits::Log2Floor(uint32_t n) {
return Bits::Log2Floor_Portable(n);
}
inline int Bits::Log2FloorNonZero(uint32_t n) {
return Bits::Log2FloorNonZero_Portable(n);
}
inline int Bits::FindLSBSetNonZero(uint32_t n) {
return Bits::FindLSBSetNonZero_Portable(n);
}
inline int Bits::Log2Floor64(uint64_t n) {
return Bits::Log2Floor64_Portable(n);
}
inline int Bits::Log2FloorNonZero64(uint64_t n) {
return Bits::Log2FloorNonZero64_Portable(n);
}
inline int Bits::FindLSBSetNonZero64(uint64_t n) {
return Bits::FindLSBSetNonZero64_Portable(n);
}
#endif
inline int Bits::Log2Floor_Portable(uint32_t n) { … }
inline int Bits::Log2FloorNonZero_Portable(uint32_t n) { … }
inline int Bits::Log2Floor64_Portable(uint64_t n) { … }
inline int Bits::Log2FloorNonZero64_Portable(uint64_t n) { … }
inline int Bits::FindLSBSetNonZero_Portable(uint32_t n) { … }
inline int Bits::FindLSBSetNonZero64_Portable(uint64_t n) { … }
#endif