xref: /llvm-project-15.0.7/libcxx/include/__bits (revision 3f786833)
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