22 #ifndef LELY_UTIL_BITS_H_ 23 #define LELY_UTIL_BITS_H_ 34 #ifndef LELY_UTIL_BITS_INLINE 35 #define LELY_UTIL_BITS_INLINE static inline 43 LELY_UTIL_BITS_INLINE uint_least16_t
bswap16(uint_least16_t x);
46 LELY_UTIL_BITS_INLINE uint_least32_t
bswap32(uint_least32_t x);
49 LELY_UTIL_BITS_INLINE uint_least64_t
bswap64(uint_least64_t x);
53 LELY_UTIL_BITS_INLINE
int cls8(uint_least8_t x);
59 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_clz) 60 LELY_UTIL_BITS_INLINE
int clz8(uint_least8_t x);
62 int clz8(uint_least8_t x);
69 LELY_UTIL_BITS_INLINE
int cls16(uint_least16_t x);
75 LELY_UTIL_BITS_INLINE
int clz16(uint_least16_t x);
81 LELY_UTIL_BITS_INLINE
int cls32(uint_least32_t x);
87 LELY_UTIL_BITS_INLINE
int clz32(uint_least32_t x);
93 LELY_UTIL_BITS_INLINE
int cls64(uint_least64_t x);
99 LELY_UTIL_BITS_INLINE
int clz64(uint_least64_t x);
105 LELY_UTIL_BITS_INLINE
int cts8(uint_least8_t x);
111 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ctz) 112 LELY_UTIL_BITS_INLINE
int ctz8(uint_least8_t x);
114 int ctz8(uint_least8_t x);
121 LELY_UTIL_BITS_INLINE
int cts16(uint_least16_t x);
127 LELY_UTIL_BITS_INLINE
int ctz16(uint_least16_t x);
133 LELY_UTIL_BITS_INLINE
int cts32(uint_least32_t x);
139 LELY_UTIL_BITS_INLINE
int ctz32(uint_least32_t x);
145 LELY_UTIL_BITS_INLINE
int cts64(uint_least64_t x);
151 LELY_UTIL_BITS_INLINE
int ctz64(uint_least64_t x);
157 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ffs) 158 LELY_UTIL_BITS_INLINE
int ffs8(uint_least8_t x);
160 int ffs8(uint_least8_t x);
167 LELY_UTIL_BITS_INLINE
int ffz8(uint_least8_t x);
173 LELY_UTIL_BITS_INLINE
int ffs16(uint_least16_t x);
179 LELY_UTIL_BITS_INLINE
int ffz16(uint_least16_t x);
185 LELY_UTIL_BITS_INLINE
int ffs32(uint_least32_t x);
191 LELY_UTIL_BITS_INLINE
int ffz32(uint_least32_t x);
197 LELY_UTIL_BITS_INLINE
int ffs64(uint_least64_t x);
203 LELY_UTIL_BITS_INLINE
int ffz64(uint_least64_t x);
206 #if defined(__GNUC__) || __has_builtin(__builtin_parity) 207 LELY_UTIL_BITS_INLINE
int parity8(uint_least8_t x);
213 LELY_UTIL_BITS_INLINE
int parity16(uint_least16_t x);
216 LELY_UTIL_BITS_INLINE
int parity32(uint_least32_t x);
219 LELY_UTIL_BITS_INLINE
int parity64(uint_least64_t x);
225 #if defined(__GNUC__) || __has_builtin(__builtin_popcount) 226 LELY_UTIL_BITS_INLINE
int popcount8(uint_least8_t x);
235 LELY_UTIL_BITS_INLINE
int popcount16(uint_least16_t x);
241 LELY_UTIL_BITS_INLINE
int popcount32(uint_least32_t x);
247 LELY_UTIL_BITS_INLINE
int popcount64(uint_least64_t x);
250 LELY_UTIL_BITS_INLINE uint_least8_t
rol8(uint_least8_t x,
unsigned int n);
253 LELY_UTIL_BITS_INLINE uint_least8_t
ror8(uint_least8_t x,
unsigned int n);
256 LELY_UTIL_BITS_INLINE uint_least16_t
rol16(uint_least16_t x,
unsigned int n);
259 LELY_UTIL_BITS_INLINE uint_least16_t
ror16(uint_least16_t x,
unsigned int n);
262 LELY_UTIL_BITS_INLINE uint_least32_t
rol32(uint_least32_t x,
unsigned int n);
265 LELY_UTIL_BITS_INLINE uint_least32_t
ror32(uint_least32_t x,
unsigned int n);
268 LELY_UTIL_BITS_INLINE uint_least64_t
rol64(uint_least64_t x,
unsigned int n);
271 LELY_UTIL_BITS_INLINE uint_least64_t
ror64(uint_least64_t x,
unsigned int n);
273 #define LELY_UTIL_DEFINE_BSWAP_IMPL(type) \ 275 for (unsigned int i = 0; i < sizeof(x) / 2; i++) \ 276 r |= (x & ((type)UCHAR_MAX << (i * CHAR_BIT))) \ 277 << ((sizeof(x) - 2 * i - 1) * CHAR_BIT); \ 278 for (unsigned int i = sizeof(x) / 2; i < sizeof(x); i++) \ 279 r |= (x & ((type)UCHAR_MAX << (i * CHAR_BIT))) \ 280 >> ((2 * i + 1 - sizeof(x)) * CHAR_BIT); \ 283 inline uint_least16_t
287 return _byteswap_ushort(x);
288 #elif GNUC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16) 289 return __builtin_bswap16(x);
291 LELY_UTIL_DEFINE_BSWAP_IMPL(uint_least16_t)
295 inline uint_least32_t
299 return _byteswap_ulong(x);
300 #elif GNUC_PREREQ(4, 3) || __has_builtin(__builtin_bswap32) 301 return __builtin_bswap32(x);
303 LELY_UTIL_DEFINE_BSWAP_IMPL(uint_least32_t)
307 inline uint_least64_t
311 return _byteswap_uint64(x);
312 #elif GNUC_PREREQ(4, 3) || __has_builtin(__builtin_bswap64) 313 return __builtin_bswap64(x);
315 LELY_UTIL_DEFINE_BSWAP_IMPL(uint_least64_t)
319 #undef LELY_UTIL_DEFINE_BSWAP_IMPL 327 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_clz) 334 return _BitScanReverse(&Index, x) ? 7 - Index : 8;
335 #elif defined(__GNUC__) || __has_builtin(__builtin_clz) 336 return x ? __builtin_clz(x) - 24 : 8;
339 #endif // _MSC_VER || __GNUC__ || __has_builtin(__builtin_clz) 350 x &= UINT16_C(0xffff);
353 return _BitScanReverse(&Index, x) ? 15 - Index : 16;
354 #elif defined(__GNUC__) || __has_builtin(__builtin_clz) 355 return x ? __builtin_clz(x) - 16 : 16;
357 return (x >> 8) ?
clz8(x >> 8) :
clz8((uint_least8_t)x) + 8;
370 x &= UINT32_C(0xffffffff);
373 return _BitScanReverse(&Index, x) ? 31 - Index : 32;
374 #elif (defined(__GNUC__) || __has_builtin(__builtin_clz)) && __WORDSIZE == 64 375 return x ? __builtin_clz(x) : 32;
376 #elif defined(__GNUC__) || __has_builtin(__builtin_clzl) 377 return x ? __builtin_clzl(x) : 32;
379 return (x >> 16) ?
clz16(x >> 16) :
clz16((uint_least16_t)x) + 16;
392 x &= UINT64_C(0xffffffffffffffff);
393 #if defined(_MSC_VER) && _WIN64 395 return _BitScanReverse64(&Index, x) ? 63 - Index : 64;
396 #elif (defined(__GNUC__) || __has_builtin(__builtin_clzl)) && __WORDSIZE == 64 397 return x ? __builtin_clzl(x) : 64;
398 #elif defined(__GNUC__) || __has_builtin(__builtin_clzll) 399 return x ? __builtin_clzll(x) : 64;
401 return (x >> 32) ?
clz32(x >> 32) :
clz32((uint_least32_t)x) + 32;
411 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ctz) 418 return _BitScanForward(&Index, x) ? Index : 8;
419 #elif defined(__GNUC__) || __has_builtin(__builtin_ctz) 420 return x ? __builtin_ctz(x) : 8;
423 #endif // _MSC_VER || __GNUC__ || __has_builtin(__builtin_ctz) 434 x &= UINT16_C(0xffff);
437 return _BitScanForward(&Index, x) ? Index : 16;
438 #elif defined(__GNUC__) || __has_builtin(__builtin_ctz) 439 return x ? __builtin_ctz(x) : 16;
441 return (x & 0xff) ?
ctz8((uint_least8_t)x) :
ctz8(x >> 8) + 8;
454 x &= UINT32_C(0xffffffff);
457 return _BitScanForward(&Index, x) ? Index : 32;
458 #elif (defined(__GNUC__) || __has_builtin(__builtin_ctz)) && __WORDSIZE == 64 459 return x ? __builtin_ctz(x) : 32;
460 #elif defined(__GNUC__) || __has_builtin(__builtin_ctzl) 461 return x ? __builtin_ctzl(x) : 32;
464 return (x & UINT16_C(0xffff))
465 ?
ctz16((uint_least16_t)x) :
ctz16(x >> 16) + 16;
479 x &= UINT64_C(0xffffffffffffffff);
480 #if (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) && __WORDSIZE == 64 481 return x ? __builtin_ctzl(x) : 64;
482 #elif defined(__GNUC__) || __has_builtin(__builtin_ctzll) 483 return x ? __builtin_ctzll(x) : 64;
486 return (x & UINT32_C(0xffffffff))
487 ?
ctz32((uint_least32_t)x) :
ctz32(x >> 32) + 32;
492 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ffs) 499 return _BitScanForward(&Index, x) ? Index + 1 : 0;
500 #elif defined(__GNUC__) || __has_builtin(__builtin_ffs) 501 return __builtin_ffs(x);
504 #endif // _MSC_VER || __GNUC__ || __has_builtin(__builtin_ffs) 515 x &= UINT16_C(0xffff);
518 return _BitScanForward(&Index, x) ? Index + 1 : 0;
519 #elif defined(__GNUC__) || __has_builtin(__builtin_ffs) 520 return __builtin_ffs(x);
523 return x ? ((x & UINT8_C(0xff))
524 ?
ffs8((uint_least8_t)x) :
ffs8(x >> 8) + 8) : 0;
538 x &= UINT32_C(0xffffffff);
541 return _BitScanForward(&Index, x) ? Index + 1 : 0;
542 #elif (defined(__GNUC__) || __has_builtin(__builtin_ffs)) && __WORDSIZE == 64 543 return __builtin_ffs(x);
544 #elif defined(__GNUC__) || __has_builtin(__builtin_ffsl) 545 return __builtin_ffsl(x);
548 return x ? ((x & UINT16_C(0xffff))
549 ?
ffs16((uint_least16_t)x) :
ffs16(x >> 16) + 16) : 0;
563 x &= UINT64_C(0xffffffffffffffff);
564 #if defined(_MSC_VER) && _WIN64 566 return _BitScanForward64(&Index, x) ? Index + 1 : 0;
567 #elif (defined(__GNUC__) || __has_builtin(__builtin_ffsl)) && __WORDSIZE == 64 568 return __builtin_ffsl(x);
569 #elif defined(__GNUC__) || __has_builtin(__builtin_ffsll) 570 return __builtin_ffsll(x);
573 return x ? ((x & UINT32_C(0xffffffff))
574 ?
ffs32((uint_least32_t)x) :
ffs32(x >> 32) + 32) : 0;
585 #if defined(__GNUC__) || __has_builtin(__builtin_parity) 590 return __builtin_parity(x);
592 #endif // __GNUC__ || __has_builtin(__builtin_parity) 597 x &= UINT16_C(0xffff);
598 #if defined(__GNUC__) || __has_builtin(__builtin_parity) 599 return __builtin_parity(x);
608 x &= UINT32_C(0xffffffff);
609 #if (defined(__GNUC__) || __has_builtin(__builtin_parity)) && __WORDSIZE == 64 610 return __builtin_parity(x);
611 #elif defined(__GNUC__) || __has_builtin(__builtin_parityl) 612 return __builtin_parityl(x);
621 x &= UINT64_C(0xffffffffffffffff);
622 #if (defined(__GNUC__) || __has_builtin(__builtin_parityl)) && __WORDSIZE == 64 623 return __builtin_parityl(x);
624 #elif defined(__GNUC__) || __has_builtin(__builtin_parityll) 625 return __builtin_parityll(x);
631 #if defined(__GNUC__) || __has_builtin(__builtin_popcount) 636 return __builtin_popcount(x);
638 #endif // __GNUC__ || __has_builtin(__builtin_popcount) 643 x &= UINT16_C(0xffff);
644 #if defined(__GNUC__) || __has_builtin(__builtin_popcount) 645 return __builtin_popcount(x);
654 x &= UINT32_C(0xffffffff);
655 #if (defined(__GNUC__) || __has_builtin(__builtin_popcount)) && __WORDSIZE == 64 656 return __builtin_popcount(x);
657 #elif defined(__GNUC__) || __has_builtin(__builtin_popcountl) 658 return __builtin_popcountl(x);
667 x &= UINT64_C(0xffffffffffffffff);
668 #if (defined(__GNUC__) || __has_builtin(__builtin_popcountl)) \ 670 return __builtin_popcountl(x);
671 #elif defined(__GNUC__) || __has_builtin(__builtin_popcountll) 672 return __builtin_popcountll(x);
679 rol8(uint_least8_t x,
unsigned int n)
686 return n ? (x << n) | (x >> (8 - n)) : x;
691 ror8(uint_least8_t x,
unsigned int n)
698 return n ? (x >> n) | (x << (8 - n)) : x;
702 inline uint_least16_t
703 rol16(uint_least16_t x,
unsigned int n)
705 x &= UINT16_C(0xffff);
708 return _rotl16(x, n);
710 return n ? (x << n) | (x >> (16 - n)) : x;
714 inline uint_least16_t
715 ror16(uint_least16_t x,
unsigned int n)
717 x &= UINT16_C(0xffff);
720 return _rotr16(x, n);
722 return n ? (x >> n) | (x << (16 - n)) : x;
726 inline uint_least32_t
727 rol32(uint_least32_t x,
unsigned int n)
729 x &= UINT32_C(0xffffffff);
734 return n ? (x << n) | (x >> (32 - n)) : x;
738 inline uint_least32_t
739 ror32(uint_least32_t x,
unsigned int n)
741 x &= UINT32_C(0xffffffff);
746 return n ? (x >> n) | (x << (32 - n)) : x;
750 inline uint_least64_t
751 rol64(uint_least64_t x,
unsigned int n)
753 x &= UINT64_C(0xffffffffffffffff);
756 return _rotl64(x, n);
758 return n ? (x << n) | (x >> (64 - n)) : x;
762 inline uint_least64_t
763 ror64(uint_least64_t x,
unsigned int n)
765 x &= UINT64_C(0xffffffffffffffff);
768 return _rotr64(x, n);
770 return n ? (x >> n) | (x << (64 - n)) : x;
778 #endif // !LELY_UTIL_BITS_H_ int cts32(uint_least32_t x)
Counts the number of trailing set bits in the unsigned 32-bit integer x.
int popcount64(uint_least64_t x)
Returns the population count (the number of set bits) in the unsigned 64-bit integer x...
int clz8(uint_least8_t x)
Counts the number of leading zero bits in the unsigned 8-bit integer x.
int ffz32(uint_least32_t x)
Returns the index (starting from one) of the first zero bit in the unsigned 32-bit integer x...
uint_least64_t bswap64(uint_least64_t x)
Reverses the byte order of the 64-bit unsigned integer x.
int ffs8(uint_least8_t x)
Returns the index (starting from one) of the first set bit in the unsigned 8-bit integer x...
int cls16(uint_least16_t x)
Counts the number of leading set bits in the unsigned 16-bit integer x.
int popcount32(uint_least32_t x)
Returns the population count (the number of set bits) in the unsigned 32-bit integer x...
int popcount8(uint_least8_t x)
Returns the population count (the number of set bits) in the unsigned 8-bit integer x...
int cts16(uint_least16_t x)
Counts the number of trailing set bits in the unsigned 16-bit integer x.
int cts64(uint_least64_t x)
Counts the number of trailing set bits in the unsigned 64-bit integer x.
uint_least32_t ror32(uint_least32_t x, unsigned int n)
Rotates the 32-bit unsigned integer x right by n bits.
int clz64(uint_least64_t x)
Counts the number of leading zero bits in the unsigned 64-bit integer x.
int ffs64(uint_least64_t x)
Returns the index (starting from one) of the first set bit in the unsigned 64-bit integer x...
uint_least16_t ror16(uint_least16_t x, unsigned int n)
Rotates the 16-bit unsigned integer x right by n bits.
int ffs32(uint_least32_t x)
Returns the index (starting from one) of the first set bit in the unsigned 32-bit integer x...
int cts8(uint_least8_t x)
Counts the number of trailing set bits in the unsigned 8-bit integer x.
int parity16(uint_least16_t x)
Returns the parity of the unsigned 16-bit integer x.
int cls64(uint_least64_t x)
Counts the number of leading set bits in the unsigned 64-bit integer x.
int cls32(uint_least32_t x)
Counts the number of leading set bits in the unsigned 32-bit integer x.
uint_least64_t rol64(uint_least64_t x, unsigned int n)
Rotates the 64-bit unsigned integer x left by n bits.
int ffs16(uint_least16_t x)
Returns the index (starting from one) of the first set bit in the unsigned 16-bit integer x...
int cls8(uint_least8_t x)
Counts the number of leading set bits in the unsigned 8-bit integer x.
int parity32(uint_least32_t x)
Returns the parity of the unsigned 32-bit integer x.
int ctz8(uint_least8_t x)
Counts the number of trailing zero bits in the unsigned 8-bit integer x.
int ffz64(uint_least64_t x)
Returns the index (starting from one) of the first zero bit in the unsigned 64-bit integer x...
uint_least16_t rol16(uint_least16_t x, unsigned int n)
Rotates the 16-bit unsigned integer x left by n bits.
uint_least64_t ror64(uint_least64_t x, unsigned int n)
Rotates the 64-bit unsigned integer x right by n bits.
This header file is part of the C11 and POSIX compatibility library; it includes <stdint.h> and defines any missing functionality.
int ctz32(uint_least32_t x)
Counts the number of trailing zero bits in the unsigned 32-bit integer x.
int clz32(uint_least32_t x)
Counts the number of leading zero bits in the unsigned 32-bit integer x.
int popcount16(uint_least16_t x)
Returns the population count (the number of set bits) in the unsigned 16-bit integer x...
uint_least32_t rol32(uint_least32_t x, unsigned int n)
Rotates the 32-bit unsigned integer x left by n bits.
int parity64(uint_least64_t x)
Returns the parity of the unsigned 64-bit integer x.
int ffz8(uint_least8_t x)
Returns the index (starting from one) of the first zero bit in the unsigned 8-bit integer x...
uint_least32_t bswap32(uint_least32_t x)
Reverses the byte order of the 32-bit unsigned integer x.
uint_least16_t bswap16(uint_least16_t x)
Reverses the byte order of the 16-bit unsigned integer x.
int clz16(uint_least16_t x)
Counts the number of leading zero bits in the unsigned 16-bit integer x.
int ffz16(uint_least16_t x)
Returns the index (starting from one) of the first zero bit in the unsigned 16-bit integer x...
uint_least8_t ror8(uint_least8_t x, unsigned int n)
Rotates the 8-bit unsigned integer x right by n bits.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib.h> and defines any missing functionality.
int ctz16(uint_least16_t x)
Counts the number of trailing zero bits in the unsigned 16-bit integer x.
This header file is part of the Lely libraries; it contains the compiler feature definitions.
uint_least8_t rol8(uint_least8_t x, unsigned int n)
Rotates the 8-bit unsigned integer x left by n bits.
int parity8(uint_least8_t x)
Returns the parity of the unsigned 8-bit integer x.
int ctz64(uint_least64_t x)
Counts the number of trailing zero bits in the unsigned 64-bit integer x.