22#if !__has_builtin(__builtin_bit_cast)
26#if defined(_MSC_VER) && !defined(_DEBUG)
30#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
31 defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || \
32 defined(__OpenBSD__) || defined(__DragonFly__)
35#include <sys/machine.h>
39#define BIG_ENDIAN 4321
40#define LITTLE_ENDIAN 1234
41#if defined(_BIG_ENDIAN)
42#define BYTE_ORDER BIG_ENDIAN
44#define BYTE_ORDER LITTLE_ENDIAN
47#define BIG_ENDIAN 4321
48#define LITTLE_ENDIAN 1234
49#define BYTE_ORDER BIG_ENDIAN
51#if !defined(BYTE_ORDER) && !defined(_WIN32)
52#include <machine/endian.h>
61unsigned char _BitScanForward(
unsigned long *_Index,
unsigned long _Mask);
62unsigned char _BitScanForward64(
unsigned long *_Index,
unsigned __int64 _Mask);
63unsigned char _BitScanReverse(
unsigned long *_Index,
unsigned long _Mask);
64unsigned char _BitScanReverse64(
unsigned long *_Index,
unsigned __int64 _Mask);
73#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
84 typename To,
typename From,
85 typename = std::enable_if_t<
sizeof(To) ==
sizeof(
From)>,
86 typename = std::enable_if_t<std::is_trivially_constructible<To>::value>,
87 typename = std::enable_if_t<std::is_trivially_copyable<To>::value>,
88 typename = std::enable_if_t<std::is_trivially_copyable<From>::value>>
90#if __has_builtin(__builtin_bit_cast)
91 return __builtin_bit_cast(To, from);
94 std::memcpy(&to, &from,
sizeof(To));
100template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
102 if constexpr (
sizeof(
T) == 1) {
104 }
else if constexpr (
sizeof(
T) == 2) {
106#if defined(_MSC_VER) && !defined(_DEBUG)
109 return _byteswap_ushort(UV);
115 }
else if constexpr (
sizeof(
T) == 4) {
117#if __has_builtin(__builtin_bswap32)
118 return __builtin_bswap32(UV);
119#elif defined(_MSC_VER) && !defined(_DEBUG)
120 return _byteswap_ulong(UV);
126 return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
128 }
else if constexpr (
sizeof(
T) == 8) {
130#if __has_builtin(__builtin_bswap64)
131 return __builtin_bswap64(UV);
132#elif defined(_MSC_VER) && !defined(_DEBUG)
133 return _byteswap_uint64(UV);
136 uint32_t Lo = llvm::byteswap<uint32_t>(UV >> 32);
137 return (
Hi << 32) |
Lo;
140 static_assert(!
sizeof(
T *),
"Don't know how to handle the given type.");
145template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
154 return std::numeric_limits<T>::digits;
159 unsigned ZeroBits = 0;
160 T Shift = std::numeric_limits<T>::digits >> 1;
161 T Mask = std::numeric_limits<T>::max() >> Shift;
163 if ((Val & Mask) == 0) {
174#if defined(__GNUC__) || defined(_MSC_VER)
175template <
typename T>
struct TrailingZerosCounter<
T, 4> {
176 static unsigned count(
T Val) {
180#if __has_builtin(__builtin_ctz) || defined(__GNUC__)
181 return __builtin_ctz(Val);
182#elif defined(_MSC_VER)
184 _BitScanForward(&
Index, Val);
190#if !defined(_MSC_VER) || defined(_M_X64)
191template <
typename T>
struct TrailingZerosCounter<
T, 8> {
192 static unsigned count(
T Val) {
196#if __has_builtin(__builtin_ctzll) || defined(__GNUC__)
197 return __builtin_ctzll(Val);
198#elif defined(_MSC_VER)
200 _BitScanForward64(&
Index, Val);
216 static_assert(std::is_unsigned_v<T>,
217 "Only unsigned integral types are allowed.");
225 return std::numeric_limits<T>::digits;
228 unsigned ZeroBits = 0;
229 for (
T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
230 T Tmp = Val >> Shift;
240#if defined(__GNUC__) || defined(_MSC_VER)
241template <
typename T>
struct LeadingZerosCounter<
T, 4> {
242 static unsigned count(
T Val) {
246#if __has_builtin(__builtin_clz) || defined(__GNUC__)
247 return __builtin_clz(Val);
248#elif defined(_MSC_VER)
250 _BitScanReverse(&
Index, Val);
256#if !defined(_MSC_VER) || defined(_M_X64)
257template <
typename T>
struct LeadingZerosCounter<
T, 8> {
258 static unsigned count(
T Val) {
262#if __has_builtin(__builtin_clzll) || defined(__GNUC__)
263 return __builtin_clzll(Val);
264#elif defined(_MSC_VER)
266 _BitScanReverse64(&
Index, Val);
282 static_assert(std::is_unsigned_v<T>,
283 "Only unsigned integral types are allowed.");
295 static_assert(std::is_unsigned_v<T>,
296 "Only unsigned integral types are allowed.");
297 return llvm::countl_zero<T>(~
Value);
308 static_assert(std::is_unsigned_v<T>,
309 "Only unsigned integral types are allowed.");
310 return llvm::countr_zero<T>(~
Value);
318 static_assert(std::is_unsigned_v<T>,
319 "Only unsigned integral types are allowed.");
328 static_assert(std::is_unsigned_v<T>,
329 "Only unsigned integral types are allowed.");
343 static_assert(std::is_unsigned_v<T>,
344 "Only unsigned integral types are allowed.");
347 return T(1) << llvm::bit_width<T>(
Value - 1u);
354 static_assert(SizeOfT <= 4,
"Not implemented!");
356 return (
int)__builtin_popcount(
Value);
359 v = v - ((v >> 1) & 0x55555555);
360 v = (v & 0x33333333) + ((v >> 2) & 0x33333333);
361 return int(((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24);
369 return (
int)__builtin_popcountll(
Value);
372 v = v - ((v >> 1) & 0x5555555555555555ULL);
373 v = (v & 0x3333333333333333ULL) + ((v >> 2) & 0x3333333333333333ULL);
374 v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
375 return int((
uint64_t)(v * 0x0101010101010101ULL) >> 56);
384template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
390template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
391[[nodiscard]]
constexpr T rotr(
T V,
int R);
393template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
394[[nodiscard]]
constexpr T rotl(
T V,
int R) {
395 unsigned N = std::numeric_limits<T>::digits;
404 return (V << R) | (V >> (
N - R));
407template <
typename T,
typename> [[nodiscard]]
constexpr T rotr(
T V,
int R) {
408 unsigned N = std::numeric_limits<T>::digits;
417 return (V >> R) | (V << (
N - R));
BlockVerifier::State From
LLVM Value Representation.
This is an optimization pass for GlobalISel generic memory operations.
constexpr T rotr(T V, int R)
int popcount(T Value) noexcept
Count the number of set bits in a value.
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
constexpr T byteswap(T V) noexcept
Reverses the bytes in the given integer value V.
int bit_width(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
T bit_ceil(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
constexpr bool has_single_bit(T Value) noexcept
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
int countl_one(T Value)
Count the number of ones from the most significant bit to the first zero bit.
To bit_cast(const From &from) noexcept
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr T rotl(T V, int R)
static unsigned count(T Val)
static int count(T Value)
static int count(T Value)
static unsigned count(T Val)