This source file includes following definitions.
- count_one_bits_32
- __popcnt64
- popcount_supported
- count_one_bits
- count_one_bits_l
- count_one_bits_ll
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #ifndef COUNT_ONE_BITS_H
20 #define COUNT_ONE_BITS_H 1
21
22
23 #if !_GL_CONFIG_H_INCLUDED
24 #error "Please include config.h first."
25 #endif
26
27 #include <limits.h>
28 #include <stdlib.h>
29
30 _GL_INLINE_HEADER_BEGIN
31 #ifndef COUNT_ONE_BITS_INLINE
32 # define COUNT_ONE_BITS_INLINE _GL_INLINE
33 #endif
34
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39
40
41
42
43 #if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) \
44 || (__clang_major__ >= 4)
45 # define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \
46 return GCC_BUILTIN (x)
47 #else
48
49
50
51 COUNT_ONE_BITS_INLINE int
52 count_one_bits_32 (unsigned int x)
53 {
54 x = ((x & 0xaaaaaaaaU) >> 1) + (x & 0x55555555U);
55 x = ((x & 0xccccccccU) >> 2) + (x & 0x33333333U);
56 x = (x >> 16) + (x & 0xffff);
57 x = ((x & 0xf0f0) >> 4) + (x & 0x0f0f);
58 return (x >> 8) + (x & 0x00ff);
59 }
60
61
62
63
64 # define COUNT_ONE_BITS_GENERIC(TYPE) \
65 do \
66 { \
67 int count = 0; \
68 int bits; \
69 for (bits = 0; bits < sizeof (TYPE) * CHAR_BIT; bits += 32) \
70 { \
71 count += count_one_bits_32 (x); \
72 x = x >> 31 >> 1; \
73 } \
74 return count; \
75 } \
76 while (0)
77
78 # if 1500 <= _MSC_VER && (defined _M_IX86 || defined _M_X64)
79
80
81
82
83
84 # if 0
85 # include <intrin.h>
86 # else
87
88 # pragma intrinsic (__cpuid)
89 # pragma intrinsic (__popcnt)
90 # if defined _M_X64
91 # pragma intrinsic (__popcnt64)
92 # endif
93 # endif
94
95 # if !defined _M_X64
96 static inline __popcnt64 (unsigned long long x)
97 {
98 return __popcnt ((unsigned int) (x >> 32)) + __popcnt ((unsigned int) x);
99 }
100 # endif
101
102
103
104
105 extern int popcount_support;
106
107 COUNT_ONE_BITS_INLINE int
108 popcount_supported (void)
109 {
110 if (popcount_support < 0)
111 {
112
113
114 int cpu_info[4];
115 __cpuid (cpu_info, 1);
116 popcount_support = (cpu_info[2] >> 23) & 1;
117 }
118 return popcount_support;
119 }
120
121 # define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \
122 do \
123 { \
124 if (popcount_supported ()) \
125 return MSC_BUILTIN (x); \
126 else \
127 COUNT_ONE_BITS_GENERIC (TYPE); \
128 } \
129 while (0)
130
131 # else
132
133 # define COUNT_ONE_BITS(GCC_BUILTIN, MSC_BUILTIN, TYPE) \
134 COUNT_ONE_BITS_GENERIC (TYPE)
135
136 # endif
137 #endif
138
139
140 COUNT_ONE_BITS_INLINE int
141 count_one_bits (unsigned int x)
142 {
143 COUNT_ONE_BITS (__builtin_popcount, __popcnt, unsigned int);
144 }
145
146
147 COUNT_ONE_BITS_INLINE int
148 count_one_bits_l (unsigned long int x)
149 {
150 COUNT_ONE_BITS (__builtin_popcountl, __popcnt, unsigned long int);
151 }
152
153
154 COUNT_ONE_BITS_INLINE int
155 count_one_bits_ll (unsigned long long int x)
156 {
157 COUNT_ONE_BITS (__builtin_popcountll, __popcnt64, unsigned long long int);
158 }
159
160 #ifdef __cplusplus
161 }
162 #endif
163
164 _GL_INLINE_HEADER_END
165
166 #endif