diff --git a/include/ucore/math.h b/include/ucore/math.h index b895c25..858af09 100644 --- a/include/ucore/math.h +++ b/include/ucore/math.h @@ -19,9 +19,36 @@ uc_phi_32(uint32_t N); uint64_t uc_phi_64(uint64_t N); +#if defined(__has_builtin) +# if __has_builtin(__builtin_clzll) +# define HAVE_BUILTIN_CLZ 1 +# endif +#endif + +#if HAVE_BUILTIN_CLZ + static inline uint32_t uc_nextpow2(uint32_t x) { + if (x <= 1) return 1; + return 1u << (32 - __builtin_clz(x - 1)); + return x; +} + +static inline uint64_t +uc_nextpow2_64(uint64_t x) +{ + if (x <= 1) return 1; + return 1u << (64 - __builtin_clzll(x - 1)); + return x; +} +#else +static inline uint32_t +uc_nextpow2(uint32_t x) +{ + if (x == 0) { + return 1; + } x--; x |= x >> 1; x |= x >> 2; @@ -29,10 +56,30 @@ uc_nextpow2(uint32_t x) x |= x >> 8; x |= x >> 16; x++; - + return x; } +static inline uint64_t +uc_nextpow2(uint64_t x) +{ + if (x == 0) { + return 1; + } + x--; + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + x++; + + return x; +} +#endif + +#undef HAVE_BUILTIN_CLZ #ifdef __cplusplus } #endif