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 46 LELY_UTIL_BITS_INLINE uint_least16_t
bswap16(uint_least16_t x);
52 LELY_UTIL_BITS_INLINE uint_least32_t
bswap32(uint_least32_t x);
58 LELY_UTIL_BITS_INLINE uint_least64_t
bswap64(uint_least64_t x);
62 LELY_UTIL_BITS_INLINE
int cls8(uint_least8_t x);
68 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_clz) 69 LELY_UTIL_BITS_INLINE
int clz8(uint_least8_t x);
71 int clz8(uint_least8_t x);
78 LELY_UTIL_BITS_INLINE
int cls16(uint_least16_t x);
84 LELY_UTIL_BITS_INLINE
int clz16(uint_least16_t x);
90 LELY_UTIL_BITS_INLINE
int cls32(uint_least32_t x);
96 LELY_UTIL_BITS_INLINE
int clz32(uint_least32_t x);
102 LELY_UTIL_BITS_INLINE
int cls64(uint_least64_t x);
108 LELY_UTIL_BITS_INLINE
int clz64(uint_least64_t x);
114 LELY_UTIL_BITS_INLINE
int cts8(uint_least8_t x);
120 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ctz) 121 LELY_UTIL_BITS_INLINE
int ctz8(uint_least8_t x);
123 int ctz8(uint_least8_t x);
130 LELY_UTIL_BITS_INLINE
int cts16(uint_least16_t x);
136 LELY_UTIL_BITS_INLINE
int ctz16(uint_least16_t x);
142 LELY_UTIL_BITS_INLINE
int cts32(uint_least32_t x);
148 LELY_UTIL_BITS_INLINE
int ctz32(uint_least32_t x);
154 LELY_UTIL_BITS_INLINE
int cts64(uint_least64_t x);
160 LELY_UTIL_BITS_INLINE
int ctz64(uint_least64_t x);
166 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ffs) 167 LELY_UTIL_BITS_INLINE
int ffs8(uint_least8_t x);
169 int ffs8(uint_least8_t x);
176 LELY_UTIL_BITS_INLINE
int ffz8(uint_least8_t x);
182 LELY_UTIL_BITS_INLINE
int ffs16(uint_least16_t x);
188 LELY_UTIL_BITS_INLINE
int ffz16(uint_least16_t x);
194 LELY_UTIL_BITS_INLINE
int ffs32(uint_least32_t x);
200 LELY_UTIL_BITS_INLINE
int ffz32(uint_least32_t x);
206 LELY_UTIL_BITS_INLINE
int ffs64(uint_least64_t x);
212 LELY_UTIL_BITS_INLINE
int ffz64(uint_least64_t x);
215 #if defined(__GNUC__) || __has_builtin(__builtin_parity) 216 LELY_UTIL_BITS_INLINE
int parity8(uint_least8_t x);
222 LELY_UTIL_BITS_INLINE
int parity16(uint_least16_t x);
225 LELY_UTIL_BITS_INLINE
int parity32(uint_least32_t x);
228 LELY_UTIL_BITS_INLINE
int parity64(uint_least64_t x);
234 #if defined(__GNUC__) || __has_builtin(__builtin_popcount) 235 LELY_UTIL_BITS_INLINE
int popcount8(uint_least8_t x);
244 LELY_UTIL_BITS_INLINE
int popcount16(uint_least16_t x);
250 LELY_UTIL_BITS_INLINE
int popcount32(uint_least32_t x);
256 LELY_UTIL_BITS_INLINE
int popcount64(uint_least64_t x);
259 LELY_UTIL_BITS_INLINE uint_least8_t
rol8(uint_least8_t x,
unsigned int n);
262 LELY_UTIL_BITS_INLINE uint_least8_t
ror8(uint_least8_t x,
unsigned int n);
265 LELY_UTIL_BITS_INLINE uint_least16_t
rol16(uint_least16_t x,
unsigned int n);
268 LELY_UTIL_BITS_INLINE uint_least16_t
ror16(uint_least16_t x,
unsigned int n);
271 LELY_UTIL_BITS_INLINE uint_least32_t
rol32(uint_least32_t x,
unsigned int n);
274 LELY_UTIL_BITS_INLINE uint_least32_t
ror32(uint_least32_t x,
unsigned int n);
277 LELY_UTIL_BITS_INLINE uint_least64_t
rol64(uint_least64_t x,
unsigned int n);
280 LELY_UTIL_BITS_INLINE uint_least64_t
ror64(uint_least64_t x,
unsigned int n);
282 inline uint_least16_t
286 return _byteswap_ushort(x);
287 #elif GNUC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16) 288 return __builtin_bswap16(x);
290 return ((x & 0xff) << 8) | ((x >> 8) & 0xff);
294 inline uint_least32_t
298 return _byteswap_ulong(x);
299 #elif GNUC_PREREQ(4, 3) || __has_builtin(__builtin_bswap32) 300 return __builtin_bswap32(x);
302 return ((x & 0xff) << 24) | ((x & 0xff00u) << 8) | ((x >> 8) & 0xff00u)
303 | ((x >> 24) & 0xff);
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 return ((x & 0xff) << 56) | ((x & 0xff00u) << 40)
316 | ((x & 0xff0000ul) << 24) | ((x & 0xff000000ul) << 8)
317 | ((x >> 8) & 0xff000000ul) | ((x >> 24) & 0xff0000ul)
318 | ((x >> 40) & 0xff00u) | ((x >> 56) & 0xff);
328 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_clz) 335 return _BitScanReverse(&Index, x) ? 7 - Index : 8;
336 #elif defined(__GNUC__) || __has_builtin(__builtin_clz) 337 return x ? __builtin_clz(x) - 24 : 8;
340 #endif // _MSC_VER || __GNUC__ || __has_builtin(__builtin_clz) 351 x &= UINT16_C(0xffff);
354 return _BitScanReverse(&Index, x) ? 15 - Index : 16;
355 #elif defined(__GNUC__) || __has_builtin(__builtin_clz) 356 return x ? __builtin_clz(x) - 16 : 16;
358 return (x >> 8) ?
clz8(x >> 8) :
clz8((uint_least8_t)x) + 8;
371 x &= UINT32_C(0xffffffff);
374 return _BitScanReverse(&Index, x) ? 31 - Index : 32;
375 #elif (defined(__GNUC__) || __has_builtin(__builtin_clz)) && __WORDSIZE == 64 376 return x ? __builtin_clz(x) : 32;
377 #elif defined(__GNUC__) || __has_builtin(__builtin_clzl) 378 return x ? __builtin_clzl(x) : 32;
380 return (x >> 16) ?
clz16(x >> 16) :
clz16((uint_least16_t)x) + 16;
393 x &= UINT64_C(0xffffffffffffffff);
394 #if defined(_MSC_VER) && _WIN64 396 return _BitScanReverse64(&Index, x) ? 63 - Index : 64;
397 #elif (defined(__GNUC__) || __has_builtin(__builtin_clzl)) && LONG_BIT == 64 398 return x ? __builtin_clzl(x) : 64;
399 #elif defined(__GNUC__) || __has_builtin(__builtin_clzll) 400 return x ? __builtin_clzll(x) : 64;
402 return (x >> 32) ?
clz32(x >> 32) :
clz32((uint_least32_t)x) + 32;
412 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ctz) 419 return _BitScanForward(&Index, x) ? Index : 8;
420 #elif defined(__GNUC__) || __has_builtin(__builtin_ctz) 421 return x ? __builtin_ctz(x) : 8;
424 #endif // _MSC_VER || __GNUC__ || __has_builtin(__builtin_ctz) 435 x &= UINT16_C(0xffff);
438 return _BitScanForward(&Index, x) ? Index : 16;
439 #elif defined(__GNUC__) || __has_builtin(__builtin_ctz) 440 return x ? __builtin_ctz(x) : 16;
442 return (x & 0xff) ?
ctz8((uint_least8_t)x) :
ctz8(x >> 8) + 8;
455 x &= UINT32_C(0xffffffff);
458 return _BitScanForward(&Index, x) ? Index : 32;
459 #elif (defined(__GNUC__) || __has_builtin(__builtin_ctz)) && __WORDSIZE == 64 460 return x ? __builtin_ctz(x) : 32;
461 #elif defined(__GNUC__) || __has_builtin(__builtin_ctzl) 462 return x ? __builtin_ctzl(x) : 32;
465 return (x & UINT16_C(0xffff))
466 ?
ctz16((uint_least16_t)x) :
ctz16(x >> 16) + 16;
480 x &= UINT64_C(0xffffffffffffffff);
481 #if (defined(__GNUC__) || __has_builtin(__builtin_ctzl)) && LONG_BIT == 64 482 return x ? __builtin_ctzl(x) : 64;
483 #elif defined(__GNUC__) || __has_builtin(__builtin_ctzll) 484 return x ? __builtin_ctzll(x) : 64;
487 return (x & UINT32_C(0xffffffff))
488 ?
ctz32((uint_least32_t)x) :
ctz32(x >> 32) + 32;
493 #if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ffs) 500 return _BitScanForward(&Index, x) ? Index + 1 : 0;
501 #elif defined(__GNUC__) || __has_builtin(__builtin_ffs) 502 return __builtin_ffs(x);
505 #endif // _MSC_VER || __GNUC__ || __has_builtin(__builtin_ffs) 516 x &= UINT16_C(0xffff);
519 return _BitScanForward(&Index, x) ? Index + 1 : 0;
520 #elif defined(__GNUC__) || __has_builtin(__builtin_ffs) 521 return __builtin_ffs(x);
524 return x ? ((x & UINT8_C(0xff))
525 ?
ffs8((uint_least8_t)x) :
ffs8(x >> 8) + 8) : 0;
539 x &= UINT32_C(0xffffffff);
542 return _BitScanForward(&Index, x) ? Index + 1 : 0;
543 #elif (defined(__GNUC__) || __has_builtin(__builtin_ffs)) && __WORDSIZE == 64 544 return __builtin_ffs(x);
545 #elif defined(__GNUC__) || __has_builtin(__builtin_ffsl) 546 return __builtin_ffsl(x);
549 return x ? ((x & UINT16_C(0xffff))
550 ?
ffs16((uint_least16_t)x) :
ffs16(x >> 16) + 16) : 0;
564 x &= UINT64_C(0xffffffffffffffff);
565 #if defined(_MSC_VER) && _WIN64 567 return _BitScanForward64(&Index, x) ? Index + 1 : 0;
568 #elif (defined(__GNUC__) || __has_builtin(__builtin_ffsl)) && LONG_BIT == 64 569 return __builtin_ffsl(x);
570 #elif defined(__GNUC__) || __has_builtin(__builtin_ffsll) 571 return __builtin_ffsll(x);
574 return x ? ((x & UINT32_C(0xffffffff))
575 ?
ffs32((uint_least32_t)x) :
ffs32(x >> 32) + 32) : 0;
586 #if defined(__GNUC__) || __has_builtin(__builtin_parity) 591 return __builtin_parity(x);
593 #endif // __GNUC__ || __has_builtin(__builtin_parity) 598 x &= UINT16_C(0xffff);
599 #if defined(__GNUC__) || __has_builtin(__builtin_parity) 600 return __builtin_parity(x);
609 x &= UINT32_C(0xffffffff);
610 #if (defined(__GNUC__) || __has_builtin(__builtin_parity)) && __WORDSIZE == 64 611 return __builtin_parity(x);
612 #elif defined(__GNUC__) || __has_builtin(__builtin_parityl) 613 return __builtin_parityl(x);
622 x &= UINT64_C(0xffffffffffffffff);
623 #if (defined(__GNUC__) || __has_builtin(__builtin_parityl)) && LONG_BIT == 64 624 return __builtin_parityl(x);
625 #elif defined(__GNUC__) || __has_builtin(__builtin_parityll) 626 return __builtin_parityll(x);
632 #if defined(__GNUC__) || __has_builtin(__builtin_popcount) 637 return __builtin_popcount(x);
639 #endif // __GNUC__ || __has_builtin(__builtin_popcount) 644 x &= UINT16_C(0xffff);
645 #if defined(__GNUC__) || __has_builtin(__builtin_popcount) 646 return __builtin_popcount(x);
655 x &= UINT32_C(0xffffffff);
656 #if (defined(__GNUC__) || __has_builtin(__builtin_popcount)) && __WORDSIZE == 64 657 return __builtin_popcount(x);
658 #elif defined(__GNUC__) || __has_builtin(__builtin_popcountl) 659 return __builtin_popcountl(x);
668 x &= UINT64_C(0xffffffffffffffff);
669 #if (defined(__GNUC__) || __has_builtin(__builtin_popcountl)) && LONG_BIT == 64 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.