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 defined(_MSC_VER) && !defined(_DEBUG)
110 return _byteswap_ushort(UV);
116 }
else if constexpr (
sizeof(
T) == 4) {
118#if __has_builtin(__builtin_bswap32)
119 return __builtin_bswap32(UV);
120#elif defined(_MSC_VER) && !defined(_DEBUG)
121 return _byteswap_ulong(UV);
127 return (Byte0 << 24) | (Byte1 << 8) | (Byte2 >> 8) | (Byte3 >> 24);
129 }
else if constexpr (
sizeof(
T) == 8) {
131#if __has_builtin(__builtin_bswap64)
132 return __builtin_bswap64(UV);
133#elif defined(_MSC_VER) && !defined(_DEBUG)
134 return _byteswap_uint64(UV);
138 return (
Hi << 32) |
Lo;
141 static_assert(!
sizeof(
T *),
"Don't know how to handle the given type.");
146template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
155 static_assert(std::is_unsigned_v<T>,
"T must be an unsigned integer type");
156 static_assert(
sizeof(
T) <= 8,
"T must be 8 bytes or less");
158 if constexpr (
sizeof(
T) <= 4) {
160 return (
int)__builtin_popcount(
Value);
163 V = V - ((V >> 1) & 0x55555555);
164 V = (V & 0x33333333) + ((V >> 2) & 0x33333333);
165 return int(((V + (V >> 4) & 0xF0F0F0F) * 0x1010101) >> 24);
169 return (
int)__builtin_popcountll(
Value);
172 V = V - ((V >> 1) & 0x5555555555555555ULL);
173 V = (V & 0x3333333333333333ULL) + ((V >> 2) & 0x3333333333333333ULL);
174 V = (V + (V >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
175 return int((
uint64_t)(V * 0x0101010101010101ULL) >> 56);
187 static_assert(std::is_unsigned_v<T>,
188 "Only unsigned integral types are allowed.");
190 return std::numeric_limits<T>::digits;
193 if constexpr (
sizeof(
T) <= 4) {
194#if __has_builtin(__builtin_ctz) || defined(__GNUC__)
195 return __builtin_ctz(Val);
196#elif defined(_MSC_VER)
198 _BitScanForward(&Index, Val);
201 }
else if constexpr (
sizeof(
T) == 8) {
202#if __has_builtin(__builtin_ctzll) || defined(__GNUC__)
203 return __builtin_ctzll(Val);
204#elif defined(_MSC_VER) && defined(_M_X64)
206 _BitScanForward64(&Index, Val);
213 return llvm::popcount(
static_cast<std::make_unsigned_t<T>
>((Val & -Val) - 1));
223 static_assert(std::is_unsigned_v<T>,
224 "Only unsigned integral types are allowed.");
226 return std::numeric_limits<T>::digits;
229 if constexpr (
sizeof(
T) == 4) {
230#if __has_builtin(__builtin_clz) || defined(__GNUC__)
231 return __builtin_clz(Val);
232#elif defined(_MSC_VER)
234 _BitScanReverse(&Index, Val);
237 }
else if constexpr (
sizeof(
T) == 8) {
238#if __has_builtin(__builtin_clzll) || defined(__GNUC__)
239 return __builtin_clzll(Val);
240#elif defined(_MSC_VER) && defined(_M_X64)
242 _BitScanReverse64(&Index, Val);
248 unsigned ZeroBits = 0;
249 for (
T Shift = std::numeric_limits<T>::digits >> 1; Shift; Shift >>= 1) {
250 T Tmp = Val >> Shift;
267 static_assert(std::is_unsigned_v<T>,
268 "Only unsigned integral types are allowed.");
280 static_assert(std::is_unsigned_v<T>,
281 "Only unsigned integral types are allowed.");
290 static_assert(std::is_unsigned_v<T>,
291 "Only unsigned integral types are allowed.");
300 static_assert(std::is_unsigned_v<T>,
301 "Only unsigned integral types are allowed.");
315 static_assert(std::is_unsigned_v<T>,
316 "Only unsigned integral types are allowed.");
323template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
324[[nodiscard]]
constexpr T rotr(
T V,
int R);
326template <
typename T,
typename = std::enable_if_t<std::is_
unsigned_v<T>>>
327[[nodiscard]]
constexpr T rotl(
T V,
int R) {
328 unsigned N = std::numeric_limits<T>::digits;
337 return (V << R) | (V >> (
N - R));
340template <
typename T,
typename> [[nodiscard]]
constexpr T rotr(
T V,
int R) {
341 unsigned N = std::numeric_limits<T>::digits;
350 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)
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
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)
int popcount(T Value) noexcept
Count the number of set bits in a value.