1b973e2e2SThorsten Schütt// -*- C++ -*- 2b973e2e2SThorsten Schütt//===----------------------------------------------------------------------===// 3b973e2e2SThorsten Schütt// 4b973e2e2SThorsten Schütt// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5b973e2e2SThorsten Schütt// See https://llvm.org/LICENSE.txt for license information. 6b973e2e2SThorsten Schütt// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7b973e2e2SThorsten Schütt// 8b973e2e2SThorsten Schütt//===----------------------------------------------------------------------===// 9b973e2e2SThorsten Schütt 10b973e2e2SThorsten Schütt#ifndef _LIBCPP___BITS 11b973e2e2SThorsten Schütt#define _LIBCPP___BITS 12b973e2e2SThorsten Schütt 13b973e2e2SThorsten Schütt#include <__config> 14b973e2e2SThorsten Schütt 15b973e2e2SThorsten Schütt#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 16b973e2e2SThorsten Schütt# pragma GCC system_header 17b973e2e2SThorsten Schütt#endif 18b973e2e2SThorsten Schütt 19b973e2e2SThorsten Schütt_LIBCPP_PUSH_MACROS 20b973e2e2SThorsten Schütt#include <__undef_macros> 21b973e2e2SThorsten Schütt 22b973e2e2SThorsten Schütt 23b973e2e2SThorsten Schütt_LIBCPP_BEGIN_NAMESPACE_STD 24b973e2e2SThorsten Schütt 25b973e2e2SThorsten Schütt#ifndef _LIBCPP_COMPILER_MSVC 26b973e2e2SThorsten Schütt 27b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 28b973e2e2SThorsten Schüttint __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } 29b973e2e2SThorsten Schütt 30b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 31b973e2e2SThorsten Schüttint __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } 32b973e2e2SThorsten Schütt 33b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 34b973e2e2SThorsten Schüttint __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } 35b973e2e2SThorsten Schütt 36b973e2e2SThorsten Schütt 37b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 38b973e2e2SThorsten Schüttint __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } 39b973e2e2SThorsten Schütt 40b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 41b973e2e2SThorsten Schüttint __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } 42b973e2e2SThorsten Schütt 43b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 44b973e2e2SThorsten Schüttint __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } 45b973e2e2SThorsten Schütt 46*3f786833SMark de Wever# ifndef _LIBCPP_HAS_NO_INT128 47*3f786833SMark de Weverinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 48*3f786833SMark de Weverint __libcpp_clz(__uint128_t __x) _NOEXCEPT { 49*3f786833SMark de Wever // The function is written in this form due to C++ constexpr limitations. 50*3f786833SMark de Wever // The algorithm: 51*3f786833SMark de Wever // - Test whether any bit in the high 64-bits is set 52*3f786833SMark de Wever // - No bits set: 53*3f786833SMark de Wever // - The high 64-bits contain 64 leading zeros, 54*3f786833SMark de Wever // - Add the result of the low 64-bits. 55*3f786833SMark de Wever // - Any bits set: 56*3f786833SMark de Wever // - The number of leading zeros of the input is the number of leading 57*3f786833SMark de Wever // zeros in the high 64-bits. 58*3f786833SMark de Wever return ((__x >> 64) == 0) 59*3f786833SMark de Wever ? (64 + __builtin_clzll(static_cast<unsigned long long>(__x))) 60*3f786833SMark de Wever : __builtin_clzll(static_cast<unsigned long long>(__x >> 64)); 61*3f786833SMark de Wever} 62*3f786833SMark de Wever# endif 63b973e2e2SThorsten Schütt 64b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 65b973e2e2SThorsten Schüttint __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } 66b973e2e2SThorsten Schütt 67b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 68b973e2e2SThorsten Schüttint __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } 69b973e2e2SThorsten Schütt 70b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 71b973e2e2SThorsten Schüttint __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } 72b973e2e2SThorsten Schütt 73b973e2e2SThorsten Schütt#else // _LIBCPP_COMPILER_MSVC 74b973e2e2SThorsten Schütt 75b973e2e2SThorsten Schütt// Precondition: __x != 0 76b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY 77b973e2e2SThorsten Schüttint __libcpp_ctz(unsigned __x) { 78b973e2e2SThorsten Schütt static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 79b973e2e2SThorsten Schütt static_assert(sizeof(unsigned long) == 4, ""); 80b973e2e2SThorsten Schütt unsigned long __where; 81b973e2e2SThorsten Schütt if (_BitScanForward(&__where, __x)) 82b973e2e2SThorsten Schütt return static_cast<int>(__where); 83b973e2e2SThorsten Schütt return 32; 84b973e2e2SThorsten Schütt} 85b973e2e2SThorsten Schütt 86b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY 87b973e2e2SThorsten Schüttint __libcpp_ctz(unsigned long __x) { 88b973e2e2SThorsten Schütt static_assert(sizeof(unsigned long) == sizeof(unsigned), ""); 89b973e2e2SThorsten Schütt return __ctz(static_cast<unsigned>(__x)); 90b973e2e2SThorsten Schütt} 91b973e2e2SThorsten Schütt 92b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY 93b973e2e2SThorsten Schüttint __libcpp_ctz(unsigned long long __x) { 94b973e2e2SThorsten Schütt unsigned long __where; 95b973e2e2SThorsten Schütt#if defined(_LIBCPP_HAS_BITSCAN64) 96b973e2e2SThorsten Schütt if (_BitScanForward64(&__where, __x)) 97b973e2e2SThorsten Schütt return static_cast<int>(__where); 98b973e2e2SThorsten Schütt#else 99b973e2e2SThorsten Schütt // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. 100b973e2e2SThorsten Schütt if (_BitScanForward(&__where, static_cast<unsigned long>(__x))) 101b973e2e2SThorsten Schütt return static_cast<int>(__where); 102b973e2e2SThorsten Schütt if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32))) 103b973e2e2SThorsten Schütt return static_cast<int>(__where + 32); 104b973e2e2SThorsten Schütt#endif 105b973e2e2SThorsten Schütt return 64; 106b973e2e2SThorsten Schütt} 107b973e2e2SThorsten Schütt 108b973e2e2SThorsten Schütt// Precondition: __x != 0 109b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY 110b973e2e2SThorsten Schüttint __libcpp_clz(unsigned __x) { 111b973e2e2SThorsten Schütt static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 112b973e2e2SThorsten Schütt static_assert(sizeof(unsigned long) == 4, ""); 113b973e2e2SThorsten Schütt unsigned long __where; 114b973e2e2SThorsten Schütt if (_BitScanReverse(&__where, __x)) 115b973e2e2SThorsten Schütt return static_cast<int>(31 - __where); 116b973e2e2SThorsten Schütt return 32; // Undefined Behavior. 117b973e2e2SThorsten Schütt} 118b973e2e2SThorsten Schütt 119b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY 120b973e2e2SThorsten Schüttint __libcpp_clz(unsigned long __x) { 121b973e2e2SThorsten Schütt static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 122b973e2e2SThorsten Schütt return __libcpp_clz(static_cast<unsigned>(__x)); 123b973e2e2SThorsten Schütt} 124b973e2e2SThorsten Schütt 125b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY 126b973e2e2SThorsten Schüttint __libcpp_clz(unsigned long long __x) { 127b973e2e2SThorsten Schütt unsigned long __where; 128b973e2e2SThorsten Schütt#if defined(_LIBCPP_HAS_BITSCAN64) 129b973e2e2SThorsten Schütt if (_BitScanReverse64(&__where, __x)) 130b973e2e2SThorsten Schütt return static_cast<int>(63 - __where); 131b973e2e2SThorsten Schütt#else 132b973e2e2SThorsten Schütt // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls. 133b973e2e2SThorsten Schütt if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32))) 134b973e2e2SThorsten Schütt return static_cast<int>(63 - (__where + 32)); 135b973e2e2SThorsten Schütt if (_BitScanReverse(&__where, static_cast<unsigned long>(__x))) 136b973e2e2SThorsten Schütt return static_cast<int>(63 - __where); 137b973e2e2SThorsten Schütt#endif 138b973e2e2SThorsten Schütt return 64; // Undefined Behavior. 139b973e2e2SThorsten Schütt} 140b973e2e2SThorsten Schütt 141b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned __x) { 142b973e2e2SThorsten Schütt static_assert(sizeof(unsigned) == 4, ""); 143b973e2e2SThorsten Schütt return __popcnt(__x); 144b973e2e2SThorsten Schütt} 145b973e2e2SThorsten Schütt 146b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long __x) { 147b973e2e2SThorsten Schütt static_assert(sizeof(unsigned long) == 4, ""); 148b973e2e2SThorsten Schütt return __popcnt(__x); 149b973e2e2SThorsten Schütt} 150b973e2e2SThorsten Schütt 151b973e2e2SThorsten Schüttinline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long long __x) { 152b973e2e2SThorsten Schütt static_assert(sizeof(unsigned long long) == 8, ""); 153b973e2e2SThorsten Schütt return __popcnt64(__x); 154b973e2e2SThorsten Schütt} 155b973e2e2SThorsten Schütt 156b973e2e2SThorsten Schütt#endif // _LIBCPP_COMPILER_MSVC 157b973e2e2SThorsten Schütt 158b973e2e2SThorsten Schütt_LIBCPP_END_NAMESPACE_STD 159b973e2e2SThorsten Schütt 160b973e2e2SThorsten Schütt_LIBCPP_POP_MACROS 161b973e2e2SThorsten Schütt 162e6972024SArthur O'Dwyer#endif // _LIBCPP___BITS 163