1*4d6fc14bSjoerg// -*- C++ -*- 2*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 3*4d6fc14bSjoerg// 4*4d6fc14bSjoerg// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*4d6fc14bSjoerg// See https://llvm.org/LICENSE.txt for license information. 6*4d6fc14bSjoerg// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*4d6fc14bSjoerg// 8*4d6fc14bSjoerg//===----------------------------------------------------------------------===// 9*4d6fc14bSjoerg 10*4d6fc14bSjoerg#ifndef _LIBCPP___BITS 11*4d6fc14bSjoerg#define _LIBCPP___BITS 12*4d6fc14bSjoerg 13*4d6fc14bSjoerg#include <__config> 14*4d6fc14bSjoerg 15*4d6fc14bSjoerg#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) 16*4d6fc14bSjoerg#pragma GCC system_header 17*4d6fc14bSjoerg#endif 18*4d6fc14bSjoerg 19*4d6fc14bSjoerg_LIBCPP_PUSH_MACROS 20*4d6fc14bSjoerg#include <__undef_macros> 21*4d6fc14bSjoerg 22*4d6fc14bSjoerg 23*4d6fc14bSjoerg_LIBCPP_BEGIN_NAMESPACE_STD 24*4d6fc14bSjoerg 25*4d6fc14bSjoerg#ifndef _LIBCPP_COMPILER_MSVC 26*4d6fc14bSjoerg 27*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 28*4d6fc14bSjoergint __libcpp_ctz(unsigned __x) _NOEXCEPT { return __builtin_ctz(__x); } 29*4d6fc14bSjoerg 30*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 31*4d6fc14bSjoergint __libcpp_ctz(unsigned long __x) _NOEXCEPT { return __builtin_ctzl(__x); } 32*4d6fc14bSjoerg 33*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 34*4d6fc14bSjoergint __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); } 35*4d6fc14bSjoerg 36*4d6fc14bSjoerg 37*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 38*4d6fc14bSjoergint __libcpp_clz(unsigned __x) _NOEXCEPT { return __builtin_clz(__x); } 39*4d6fc14bSjoerg 40*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 41*4d6fc14bSjoergint __libcpp_clz(unsigned long __x) _NOEXCEPT { return __builtin_clzl(__x); } 42*4d6fc14bSjoerg 43*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 44*4d6fc14bSjoergint __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); } 45*4d6fc14bSjoerg 46*4d6fc14bSjoerg 47*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 48*4d6fc14bSjoergint __libcpp_popcount(unsigned __x) _NOEXCEPT { return __builtin_popcount(__x); } 49*4d6fc14bSjoerg 50*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 51*4d6fc14bSjoergint __libcpp_popcount(unsigned long __x) _NOEXCEPT { return __builtin_popcountl(__x); } 52*4d6fc14bSjoerg 53*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR 54*4d6fc14bSjoergint __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); } 55*4d6fc14bSjoerg 56*4d6fc14bSjoerg#else // _LIBCPP_COMPILER_MSVC 57*4d6fc14bSjoerg 58*4d6fc14bSjoerg// Precondition: __x != 0 59*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 60*4d6fc14bSjoergint __libcpp_ctz(unsigned __x) { 61*4d6fc14bSjoerg static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 62*4d6fc14bSjoerg static_assert(sizeof(unsigned long) == 4, ""); 63*4d6fc14bSjoerg unsigned long __where; 64*4d6fc14bSjoerg if (_BitScanForward(&__where, __x)) 65*4d6fc14bSjoerg return static_cast<int>(__where); 66*4d6fc14bSjoerg return 32; 67*4d6fc14bSjoerg} 68*4d6fc14bSjoerg 69*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 70*4d6fc14bSjoergint __libcpp_ctz(unsigned long __x) { 71*4d6fc14bSjoerg static_assert(sizeof(unsigned long) == sizeof(unsigned), ""); 72*4d6fc14bSjoerg return __ctz(static_cast<unsigned>(__x)); 73*4d6fc14bSjoerg} 74*4d6fc14bSjoerg 75*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 76*4d6fc14bSjoergint __libcpp_ctz(unsigned long long __x) { 77*4d6fc14bSjoerg unsigned long __where; 78*4d6fc14bSjoerg#if defined(_LIBCPP_HAS_BITSCAN64) 79*4d6fc14bSjoerg if (_BitScanForward64(&__where, __x)) 80*4d6fc14bSjoerg return static_cast<int>(__where); 81*4d6fc14bSjoerg#else 82*4d6fc14bSjoerg // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. 83*4d6fc14bSjoerg if (_BitScanForward(&__where, static_cast<unsigned long>(__x))) 84*4d6fc14bSjoerg return static_cast<int>(__where); 85*4d6fc14bSjoerg if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32))) 86*4d6fc14bSjoerg return static_cast<int>(__where + 32); 87*4d6fc14bSjoerg#endif 88*4d6fc14bSjoerg return 64; 89*4d6fc14bSjoerg} 90*4d6fc14bSjoerg 91*4d6fc14bSjoerg// Precondition: __x != 0 92*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 93*4d6fc14bSjoergint __libcpp_clz(unsigned __x) { 94*4d6fc14bSjoerg static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 95*4d6fc14bSjoerg static_assert(sizeof(unsigned long) == 4, ""); 96*4d6fc14bSjoerg unsigned long __where; 97*4d6fc14bSjoerg if (_BitScanReverse(&__where, __x)) 98*4d6fc14bSjoerg return static_cast<int>(31 - __where); 99*4d6fc14bSjoerg return 32; // Undefined Behavior. 100*4d6fc14bSjoerg} 101*4d6fc14bSjoerg 102*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 103*4d6fc14bSjoergint __libcpp_clz(unsigned long __x) { 104*4d6fc14bSjoerg static_assert(sizeof(unsigned) == sizeof(unsigned long), ""); 105*4d6fc14bSjoerg return __libcpp_clz(static_cast<unsigned>(__x)); 106*4d6fc14bSjoerg} 107*4d6fc14bSjoerg 108*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY 109*4d6fc14bSjoergint __libcpp_clz(unsigned long long __x) { 110*4d6fc14bSjoerg unsigned long __where; 111*4d6fc14bSjoerg#if defined(_LIBCPP_HAS_BITSCAN64) 112*4d6fc14bSjoerg if (_BitScanReverse64(&__where, __x)) 113*4d6fc14bSjoerg return static_cast<int>(63 - __where); 114*4d6fc14bSjoerg#else 115*4d6fc14bSjoerg // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls. 116*4d6fc14bSjoerg if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32))) 117*4d6fc14bSjoerg return static_cast<int>(63 - (__where + 32)); 118*4d6fc14bSjoerg if (_BitScanReverse(&__where, static_cast<unsigned long>(__x))) 119*4d6fc14bSjoerg return static_cast<int>(63 - __where); 120*4d6fc14bSjoerg#endif 121*4d6fc14bSjoerg return 64; // Undefined Behavior. 122*4d6fc14bSjoerg} 123*4d6fc14bSjoerg 124*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned __x) { 125*4d6fc14bSjoerg static_assert(sizeof(unsigned) == 4, ""); 126*4d6fc14bSjoerg return __popcnt(__x); 127*4d6fc14bSjoerg} 128*4d6fc14bSjoerg 129*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long __x) { 130*4d6fc14bSjoerg static_assert(sizeof(unsigned long) == 4, ""); 131*4d6fc14bSjoerg return __popcnt(__x); 132*4d6fc14bSjoerg} 133*4d6fc14bSjoerg 134*4d6fc14bSjoerginline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long long __x) { 135*4d6fc14bSjoerg static_assert(sizeof(unsigned long long) == 8, ""); 136*4d6fc14bSjoerg return __popcnt64(__x); 137*4d6fc14bSjoerg} 138*4d6fc14bSjoerg 139*4d6fc14bSjoerg#endif // _LIBCPP_COMPILER_MSVC 140*4d6fc14bSjoerg 141*4d6fc14bSjoerg_LIBCPP_END_NAMESPACE_STD 142*4d6fc14bSjoerg 143*4d6fc14bSjoerg_LIBCPP_POP_MACROS 144*4d6fc14bSjoerg 145*4d6fc14bSjoerg#endif // _LIBCPP___BITS 146