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
43LELY_UTIL_BITS_INLINE uint_least16_t
bswap16(uint_least16_t x);
46LELY_UTIL_BITS_INLINE uint_least32_t
bswap32(uint_least32_t x);
49LELY_UTIL_BITS_INLINE uint_least64_t
bswap64(uint_least64_t x);
53LELY_UTIL_BITS_INLINE
int cls8(uint_least8_t x);
59#if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_clz)
60LELY_UTIL_BITS_INLINE
int clz8(uint_least8_t x);
62int clz8(uint_least8_t x);
69LELY_UTIL_BITS_INLINE
int cls16(uint_least16_t x);
75LELY_UTIL_BITS_INLINE
int clz16(uint_least16_t x);
81LELY_UTIL_BITS_INLINE
int cls32(uint_least32_t x);
87LELY_UTIL_BITS_INLINE
int clz32(uint_least32_t x);
93LELY_UTIL_BITS_INLINE
int cls64(uint_least64_t x);
99LELY_UTIL_BITS_INLINE
int clz64(uint_least64_t x);
105LELY_UTIL_BITS_INLINE
int cts8(uint_least8_t x);
111#if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ctz)
112LELY_UTIL_BITS_INLINE
int ctz8(uint_least8_t x);
114int ctz8(uint_least8_t x);
121LELY_UTIL_BITS_INLINE
int cts16(uint_least16_t x);
127LELY_UTIL_BITS_INLINE
int ctz16(uint_least16_t x);
133LELY_UTIL_BITS_INLINE
int cts32(uint_least32_t x);
139LELY_UTIL_BITS_INLINE
int ctz32(uint_least32_t x);
145LELY_UTIL_BITS_INLINE
int cts64(uint_least64_t x);
151LELY_UTIL_BITS_INLINE
int ctz64(uint_least64_t x);
157#if defined(_MSC_VER) || defined(__GNUC__) || __has_builtin(__builtin_ffs)
158LELY_UTIL_BITS_INLINE
int ffs8(uint_least8_t x);
160int ffs8(uint_least8_t x);
167LELY_UTIL_BITS_INLINE
int ffz8(uint_least8_t x);
173LELY_UTIL_BITS_INLINE
int ffs16(uint_least16_t x);
179LELY_UTIL_BITS_INLINE
int ffz16(uint_least16_t x);
185LELY_UTIL_BITS_INLINE
int ffs32(uint_least32_t x);
191LELY_UTIL_BITS_INLINE
int ffz32(uint_least32_t x);
197LELY_UTIL_BITS_INLINE
int ffs64(uint_least64_t x);
203LELY_UTIL_BITS_INLINE
int ffz64(uint_least64_t x);
206#if defined(__GNUC__) || __has_builtin(__builtin_parity)
207LELY_UTIL_BITS_INLINE
int parity8(uint_least8_t x);
213LELY_UTIL_BITS_INLINE
int parity16(uint_least16_t x);
216LELY_UTIL_BITS_INLINE
int parity32(uint_least32_t x);
219LELY_UTIL_BITS_INLINE
int parity64(uint_least64_t x);
225#if defined(__GNUC__) || __has_builtin(__builtin_popcount)
226LELY_UTIL_BITS_INLINE
int popcount8(uint_least8_t x);
235LELY_UTIL_BITS_INLINE
int popcount16(uint_least16_t x);
241LELY_UTIL_BITS_INLINE
int popcount32(uint_least32_t x);
247LELY_UTIL_BITS_INLINE
int popcount64(uint_least64_t x);
250LELY_UTIL_BITS_INLINE uint_least8_t
rol8(uint_least8_t x,
unsigned int n);
253LELY_UTIL_BITS_INLINE uint_least8_t
ror8(uint_least8_t x,
unsigned int n);
256LELY_UTIL_BITS_INLINE uint_least16_t
rol16(uint_least16_t x,
unsigned int n);
259LELY_UTIL_BITS_INLINE uint_least16_t
ror16(uint_least16_t x,
unsigned int n);
262LELY_UTIL_BITS_INLINE uint_least32_t
rol32(uint_least32_t x,
unsigned int n);
265LELY_UTIL_BITS_INLINE uint_least32_t
ror32(uint_least32_t x,
unsigned int n);
268LELY_UTIL_BITS_INLINE uint_least64_t
rol64(uint_least64_t x,
unsigned int n);
271LELY_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); \
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)
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)
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;
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;
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);
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);
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);
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);
679rol8(uint_least8_t x,
unsigned int n)
686 return n ? (x << n) | (x >> (8 - n)) : x;
691ror8(uint_least8_t x,
unsigned int n)
698 return n ? (x >> n) | (x << (8 - n)) : x;
703rol16(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;
715ror16(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;
727rol32(uint_least32_t x,
unsigned int n)
729 x &= UINT32_C(0xffffffff);
734 return n ? (x << n) | (x >> (32 - n)) : x;
739ror32(uint_least32_t x,
unsigned int n)
741 x &= UINT32_C(0xffffffff);
746 return n ? (x >> n) | (x << (32 - n)) : x;
751rol64(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;
763ror64(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;
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.
uint_least16_t ror16(uint_least16_t x, unsigned int n)
Rotates the 16-bit unsigned integer x right by n bits.
uint_least64_t bswap64(uint_least64_t x)
Reverses the byte order of the 64-bit unsigned integer x.
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 ffz64(uint_least64_t x)
Returns the index (starting from one) of the first zero bit in the unsigned 64-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 ffs8(uint_least8_t x)
Returns the index (starting from one) of the first set bit in the unsigned 8-bit integer x,...
uint_least64_t ror64(uint_least64_t x, unsigned int n)
Rotates the 64-bit unsigned integer x right by n bits.
int ctz32(uint_least32_t x)
Counts the number of trailing zero bits in the unsigned 32-bit integer x.
int cls16(uint_least16_t x)
Counts the number of leading set bits in the unsigned 16-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_least8_t ror8(uint_least8_t x, unsigned int n)
Rotates the 8-bit unsigned integer x right by n bits.
int cts32(uint_least32_t x)
Counts the number of trailing set bits in the unsigned 32-bit integer x.
int clz8(uint_least8_t x)
Counts the number of leading zero bits in 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.
int popcount32(uint_least32_t x)
Returns the population count (the number of set bits) in the unsigned 32-bit integer x.
int cts16(uint_least16_t x)
Counts the number of trailing set bits in 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.
uint_least16_t bswap16(uint_least16_t x)
Reverses the byte order of the 16-bit unsigned integer x.
int parity8(uint_least8_t x)
Returns the parity of the unsigned 8-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.
uint_least8_t rol8(uint_least8_t x, unsigned int n)
Rotates the 8-bit unsigned integer x left by n bits.
int clz64(uint_least64_t x)
Counts the number of leading zero bits in 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,...
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 clz32(uint_least32_t x)
Counts the number of leading zero bits in the unsigned 32-bit integer x.
int parity32(uint_least32_t x)
Returns the parity of the unsigned 32-bit integer x.
int clz16(uint_least16_t x)
Counts the number of leading zero bits in the unsigned 16-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,...
int ffz16(uint_least16_t x)
Returns the index (starting from one) of the first zero bit in the unsigned 16-bit integer x,...
int cls32(uint_least32_t x)
Counts the number of leading 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.
uint_least16_t rol16(uint_least16_t x, unsigned int n)
Rotates the 16-bit unsigned integer x left by n bits.
int parity64(uint_least64_t x)
Returns the parity of the unsigned 64-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 ctz16(uint_least16_t x)
Counts the number of trailing zero bits in the unsigned 16-bit integer x.
int ctz8(uint_least8_t x)
Counts the number of trailing zero bits in the unsigned 8-bit integer x.
int cls8(uint_least8_t x)
Counts the number of leading set bits 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.
int popcount16(uint_least16_t x)
Returns the population count (the number of set bits) in the unsigned 16-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.
This header file is part of the Lely libraries; it contains the compiler feature definitions.
This header file is part of the C11 and POSIX compatibility library; it includes <stdint....
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....