23#if !__has_builtin(__builtin_bit_cast)
27#if defined(_MSC_VER) && !defined(_DEBUG)
31#if defined(__linux__) || defined(__GNU__) || defined(__HAIKU__) || \
32 defined(__Fuchsia__) || defined(__EMSCRIPTEN__) || defined(__NetBSD__) || \
33 defined(__OpenBSD__) || defined(__DragonFly__) || defined(__managarm__)
36#include <sys/machine.h>
40#define BIG_ENDIAN 4321
41#define LITTLE_ENDIAN 1234
42#if defined(_BIG_ENDIAN)
43#define BYTE_ORDER BIG_ENDIAN
45#define BYTE_ORDER LITTLE_ENDIAN
48#define BIG_ENDIAN 4321
49#define LITTLE_ENDIAN 1234
50#define BYTE_ORDER BIG_ENDIAN
52#if !defined(BYTE_ORDER) && !defined(_WIN32)
53#include <machine/endian.h>
62unsigned char _BitScanForward(
unsigned long *_Index,
unsigned long _Mask);
63unsigned char _BitScanForward64(
unsigned long *_Index,
unsigned __int64 _Mask);
64unsigned char _BitScanReverse(
unsigned long *_Index,
unsigned long _Mask);
65unsigned char _BitScanReverse64(
unsigned long *_Index,
unsigned __int64 _Mask);
74#if defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN
85 typename To,
typename From,
86 typename = std::enable_if_t<
sizeof(To) ==
sizeof(From)>,
87 typename = std::enable_if_t<std::is_trivially_constructible<To>::value>,
88 typename = std::enable_if_t<std::is_trivially_copyable<To>::value>,
89 typename = std::enable_if_t<std::is_trivially_copyable<From>::value>>
90[[nodiscard]]
inline To
bit_cast(
const From &from)
noexcept {
91#if __has_builtin(__builtin_bit_cast)
92 return __builtin_bit_cast(To, from);
95 std::memcpy(&to, &from,
sizeof(To));
101template <
typename T,
typename = std::enable_if_t<std::is_
integral_v<T>>>
103 if constexpr (
sizeof(
T) == 1) {
105 }
else if constexpr (
sizeof(
T) == 2) {
107#if __has_builtin(__builtin_bswap16)
108 return __builtin_bswap16(UV);
109#elif defined(_MSC_VER) && !defined(_DEBUG)
112 return _byteswap_ushort(UV);
118 }
else if constexpr (
sizeof(
T) == 4) {
120#if __has_builtin(__builtin_bswap32)
121 return __builtin_bswap32(UV);
122#elif defined(_MSC_VER) && !defined(_DEBUG)
123 return _byteswap_ulong(UV);
129 return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
131 }
else if constexpr (
sizeof(
T) == 8) {
133#if __has_builtin(__builtin_bswap64)
134 return __builtin_bswap64(UV);
135#elif defined(_MSC_VER) && !defined(_DEBUG)
136 return _byteswap_uint64(UV);
140 return (
Hi << 32) |
Lo;
143 static_assert(!
sizeof(
T *),
"Don't know how to handle the given type.");
148template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
157 static_assert(std::is_unsigned_v<T>,
"T must be an unsigned integer type");
158 static_assert(
sizeof(
T) <= 8,
"T must be 8 bytes or less");
160 if constexpr (
sizeof(
T) <= 4) {
162 return (
int)__builtin_popcount(
Value);
165 V = V - ((V >> 1) & 0x55555555);
166 V = (V & 0x33333333) + ((V >> 2) & 0x33333333);
167 return int(((V + (V >> 4) & 0xF0F0F0F) * 0x1010101) >> 24);
171 return (
int)__builtin_popcountll(
Value);
174 V = V - ((V >> 1) & 0x5555555555555555ULL);
175 V = (V & 0x3333333333333333ULL) + ((V >> 2) & 0x3333333333333333ULL);
176 V = (V + (V >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
177 return int((
uint64_t)(V * 0x0101010101010101ULL) >> 56);
191 static_assert(std::is_unsigned_v<T>,
192 "Only unsigned integral types are allowed.");
195 return llvm::popcount(
static_cast<std::make_unsigned_t<T>
>((Val & -Val) - 1));
205 static_assert(std::is_unsigned_v<T>,
206 "Only unsigned integral types are allowed.");
208 return std::numeric_limits<T>::digits;
211 if constexpr (
sizeof(
T) <= 4) {
212#if __has_builtin(__builtin_ctz) || defined(__GNUC__)
213 return __builtin_ctz(Val);
214#elif defined(_MSC_VER)
216 _BitScanForward(&Index, Val);
219 }
else if constexpr (
sizeof(
T) == 8) {
220#if __has_builtin(__builtin_ctzll) || defined(__GNUC__)
221 return __builtin_ctzll(Val);
222#elif defined(_MSC_VER) && defined(_M_X64)
224 _BitScanForward64(&Index, Val);
241 static_assert(std::is_unsigned_v<T>,
242 "Only unsigned integral types are allowed.");
244 return std::numeric_limits<T>::digits;
246 unsigned ZeroBits = 0;
247 for (
T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
248 T Tmp = Val >> Shift;
264 static_assert(std::is_unsigned_v<T>,
265 "Only unsigned integral types are allowed.");
267 constexpr int BitWidth = std::numeric_limits<T>::digits;
273 if constexpr (
sizeof(
T) <= 4) {
274#if __has_builtin(__builtin_clz) || defined(__GNUC__)
275 constexpr int Padding = std::numeric_limits<uint32_t>::digits -
BitWidth;
276 return __builtin_clz(Val) - Padding;
277#elif defined(_MSC_VER)
279 _BitScanReverse(&Index, Val);
280 return static_cast<int>((
BitWidth - 1) - Index);
282 }
else if constexpr (
sizeof(
T) == 8) {
283#if __has_builtin(__builtin_clzll) || defined(__GNUC__)
284 return __builtin_clzll(Val);
285#elif defined(_MSC_VER) && defined(_M_X64)
287 _BitScanReverse64(&Index, Val);
303 static_assert(std::is_unsigned_v<T>,
304 "Only unsigned integral types are allowed.");
316 static_assert(std::is_unsigned_v<T>,
317 "Only unsigned integral types are allowed.");
326 static_assert(std::is_unsigned_v<T>,
327 "Only unsigned integral types are allowed.");
338 static_assert(std::is_unsigned_v<T>,
339 "Only unsigned integral types are allowed.");
348 static_assert(std::is_unsigned_v<T>,
349 "Only unsigned integral types are allowed.");
363 static_assert(std::is_unsigned_v<T>,
364 "Only unsigned integral types are allowed.");
378 static_assert(std::is_unsigned_v<T>,
379 "Only unsigned integral types are allowed.");
385template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
386[[nodiscard]]
constexpr T rotl(
T V,
int R) {
387 constexpr unsigned N = std::numeric_limits<T>::digits;
389 static_assert(
has_single_bit(
N),
"& (N - 1) is only valid for powers of two");
395 return (V << R) | (V >> (
N - R));
398template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
399[[nodiscard]]
constexpr T rotr(
T V,
int R) {
400 constexpr unsigned N = std::numeric_limits<T>::digits;
402 static_assert(
has_single_bit(
N),
"& (N - 1) is only valid for powers of two");
408 return (V >> R) | (V << (
N - R));
LLVM Value Representation.
This is an optimization pass for GlobalISel generic memory operations.
constexpr T rotr(T V, int R)
constexpr T bit_ceil_constexpr(T Value)
Returns the smallest integral power of two no smaller than Value if Value is nonzero.
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.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
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
constexpr int countl_zero_constexpr(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
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
constexpr unsigned BitWidth
constexpr int countr_zero_constexpr(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
constexpr int bit_width_constexpr(T Value)
Returns the number of bits needed to represent Value if Value is nonzero.
constexpr T rotl(T V, int R)