diff options
Diffstat (limited to 'libcxx/include/__bits')
-rw-r--r-- | libcxx/include/__bits | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/libcxx/include/__bits b/libcxx/include/__bits index 1eee8f576e9e..92ef5c0a7b49 100644 --- a/libcxx/include/__bits +++ b/libcxx/include/__bits @@ -43,6 +43,23 @@ int __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } +# ifndef _LIBCPP_HAS_NO_INT128 +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR +int __libcpp_clz(__uint128_t __x) _NOEXCEPT { + // The function is written in this form due to C++ constexpr limitations. + // The algorithm: + // - Test whether any bit in the high 64-bits is set + // - No bits set: + // - The high 64-bits contain 64 leading zeros, + // - Add the result of the low 64-bits. + // - Any bits set: + // - The number of leading zeros of the input is the number of leading + // zeros in the high 64-bits. + return ((__x >> 64) == 0) + ? (64 + __builtin_clzll(static_cast<unsigned long long>(__x))) + : __builtin_clzll(static_cast<unsigned long long>(__x >> 64)); +} +# endif inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR int __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } |