| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- #pragma once
- #if defined(__GNUC__) || defined(__clang__)
- static inline uint32_t clz32(unsigned long val)
- {
- return __builtin_clz(val);
- }
- static inline uint32_t ctz32(unsigned long val)
- {
- return __builtin_ctz(val);
- }
- #elif defined(_MSC_VER) && _MSC_VER >= 1400
- static inline uint32_t clz32(unsigned long val)
- {
- /* __lzcnt() / _lzcnt_u32() do not work correctly on older Intel CPUs,
- * so use BSR instead for better compatibility. */
- uint32_t zeros = 0;
- _BitScanReverse(&zeros, val);
- return 31 - zeros;
- }
- static inline uint32_t ctz32(unsigned long val)
- {
- return _tzcnt_u32(val);
- }
- #else
- static uint32_t popcnt(uint32_t x)
- {
- x -= ((x >> 1) & 0x55555555);
- x = (((x >> 2) & 0x33333333) + (x & 0x33333333));
- x = (((x >> 4) + x) & 0x0f0f0f0f);
- x += (x >> 8);
- x += (x >> 16);
- return x & 0x0000003f;
- }
- static uint32_t clz32(uint32_t x)
- {
- x |= (x >> 1);
- x |= (x >> 2);
- x |= (x >> 4);
- x |= (x >> 8);
- x |= (x >> 16);
- return 32 - popcnt(x);
- }
- static uint32_t ctz32(uint32_t x)
- {
- return popcnt((x & -x) - 1);
- }
- #endif
- static inline uint32_t min_u32(uint32_t a, uint32_t b)
- {
- return (a < b) ? a : b;
- }
- static inline uint16_t min_u16(uint16_t a, uint16_t b)
- {
- return (a < b) ? a : b;
- }
- static inline int32_t min_i32(int32_t a, int32_t b)
- {
- return (a < b) ? a : b;
- }
- static inline uint8_t max_u8(uint8_t a, uint8_t b)
- {
- return (a > b) ? a : b;
- }
|