execute, spawn-pipe: Make multithread-safe on native Windows.
[gnulib.git] / lib / count-trailing-zeros.h
blob727b21dcc564f490bd8713e2e42894620f0b2b81
1 /* count-trailing-zeros.h -- counts the number of trailing 0 bits in a word.
2 Copyright 2013-2020 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Paul Eggert. */
19 #ifndef COUNT_TRAILING_ZEROS_H
20 #define COUNT_TRAILING_ZEROS_H 1
22 #include <limits.h>
23 #include <stdlib.h>
25 #ifndef _GL_INLINE_HEADER_BEGIN
26 #error "Please include config.h first."
27 #endif
28 _GL_INLINE_HEADER_BEGIN
29 #ifndef COUNT_TRAILING_ZEROS_INLINE
30 # define COUNT_TRAILING_ZEROS_INLINE _GL_INLINE
31 #endif
33 #ifdef __cplusplus
34 extern "C" {
35 #endif
37 /* Assuming the GCC builtin is BUILTIN and the MSC builtin is MSC_BUILTIN,
38 expand to code that computes the number of trailing zeros of the local
39 variable 'x' of type TYPE (an unsigned integer type) and return it
40 from the current function. */
41 #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) \
42 || (__clang_major__ >= 4)
43 # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
44 return x ? BUILTIN (x) : CHAR_BIT * sizeof x;
45 #elif _MSC_VER
46 # pragma intrinsic _BitScanForward
47 # pragma intrinsic _BitScanForward64
48 # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
49 do \
50 { \
51 unsigned long result; \
52 return MSC_BUILTIN (&result, x) ? result : CHAR_BIT * sizeof x; \
53 } \
54 while (0)
55 #else
56 # define COUNT_TRAILING_ZEROS(BUILTIN, MSC_BUILTIN, TYPE) \
57 do \
58 { \
59 int count = 0; \
60 if (! x) \
61 return CHAR_BIT * sizeof x; \
62 for (count = 0; \
63 (count < CHAR_BIT * sizeof x - 32 \
64 && ! (x & 0xffffffffU)); \
65 count += 32) \
66 x = x >> 31 >> 1; \
67 return count + count_trailing_zeros_32 (x); \
68 } \
69 while (0)
71 /* Compute and return the number of trailing zeros in the least
72 significant 32 bits of X. One of these bits must be nonzero. */
73 COUNT_TRAILING_ZEROS_INLINE int
74 count_trailing_zeros_32 (unsigned int x)
76 /* <https://github.com/gibsjose/BitHacks>
77 <https://www.fit.vutbr.cz/~ibarina/pub/bithacks.pdf> */
78 static const char de_Bruijn_lookup[32] = {
79 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
80 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
82 return de_Bruijn_lookup[(((x & -x) * 0x077cb531U) & 0xffffffffU) >> 27];
84 #endif
86 /* Compute and return the number of trailing zeros in X. */
87 COUNT_TRAILING_ZEROS_INLINE int
88 count_trailing_zeros (unsigned int x)
90 COUNT_TRAILING_ZEROS (__builtin_ctz, _BitScanForward, unsigned int);
93 /* Compute and return the number of trailing zeros in X. */
94 COUNT_TRAILING_ZEROS_INLINE int
95 count_trailing_zeros_l (unsigned long int x)
97 COUNT_TRAILING_ZEROS (__builtin_ctzl, _BitScanForward, unsigned long int);
100 /* Compute and return the number of trailing zeros in X. */
101 COUNT_TRAILING_ZEROS_INLINE int
102 count_trailing_zeros_ll (unsigned long long int x)
104 COUNT_TRAILING_ZEROS (__builtin_ctzll, _BitScanForward64,
105 unsigned long long int);
108 #ifdef __cplusplus
110 #endif
112 _GL_INLINE_HEADER_END
114 #endif