diff --git a/lib/util.c b/lib/util.c index f3e47b1312b..01fe7dcd4e5 100644 --- a/lib/util.c +++ b/lib/util.c @@ -949,7 +949,7 @@ english_list_delimiter(size_t index, size_t total) } /* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */ -#if __GNUC__ >= 4 +#if __GNUC__ >= 4 || _MSC_VER /* Defined inline in util.h. */ #else /* Returns the number of trailing 0-bits in 'n'. Undefined if 'n' == 0. */ diff --git a/lib/util.h b/lib/util.h index 7da7aa8f0e4..ecc8e5f723d 100644 --- a/lib/util.h +++ b/lib/util.h @@ -354,6 +354,42 @@ raw_clz64(uint64_t n) { return __builtin_clzll(n); } +#elif _MSC_VER +static inline int +raw_ctz(uint64_t n) +{ +#ifdef _WIN64 + uint32_t r = 0; + _BitScanForward64(&r, n); + return r; +#else + uint32_t low = n, high, r = 0; + if (_BitScanForward(&r, low)) { + return r; + } + high = n >> 32; + _BitScanForward(&r, high); + return r + 32; +#endif +} + +static inline int +raw_clz64(uint64_t n) +{ +#ifdef _WIN64 + uint32_t r = 0; + _BitScanReverse64(&r, n); + return 63 - r; +#else + uint32_t low, high = n >> 32, r = 0; + if (_BitScanReverse(&r, high)) { + return 31 - r; + } + low = n; + _BitScanReverse(&r, low); + return 63 - r; +#endif +} #else /* Defined in util.c. */ int raw_ctz(uint64_t n);