1 /*-------------------------------------------------------------------------
4 * Miscellaneous functions for bit-wise operations.
6 * Copyright (c) 2019-2023, PostgreSQL Global Development Group
9 * src/port/pg_bitutils.c
11 *-------------------------------------------------------------------------
15 #ifdef HAVE__GET_CPUID
22 #include "port/pg_bitutils.h"
26 * Array giving the position of the left-most set bit for each possible
27 * byte value. We count the right-most position as the 0th bit, and the
28 * left-most the 7th bit. The 0th entry of the array should not be used.
30 * Note: this is not used by the functions in pg_bitutils.h when
31 * HAVE__BUILTIN_CLZ is defined, but we provide it anyway, so that
32 * extensions possibly compiled with a different compiler can use it.
34 const uint8 pg_leftmost_one_pos
[256] = {
35 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
36 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
37 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
38 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
39 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
40 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
41 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
42 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
43 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
44 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
45 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
46 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
47 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
48 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
49 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
50 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
54 * Array giving the position of the right-most set bit for each possible
55 * byte value. We count the right-most position as the 0th bit, and the
56 * left-most the 7th bit. The 0th entry of the array should not be used.
58 * Note: this is not used by the functions in pg_bitutils.h when
59 * HAVE__BUILTIN_CTZ is defined, but we provide it anyway, so that
60 * extensions possibly compiled with a different compiler can use it.
62 const uint8 pg_rightmost_one_pos
[256] = {
63 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
64 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
65 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
66 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
67 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
68 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
69 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
70 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
71 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
72 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
73 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
74 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
75 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
76 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
77 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
78 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
82 * Array giving the number of 1-bits in each possible byte value.
84 * Note: we export this for use by functions in which explicit use
85 * of the popcount functions seems unlikely to be a win.
87 const uint8 pg_number_of_ones
[256] = {
88 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
89 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
90 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
91 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
92 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
93 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
94 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
95 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
96 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
97 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
98 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
99 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
100 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
101 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
102 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
103 4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
106 static int pg_popcount32_slow(uint32 word
);
107 static int pg_popcount64_slow(uint64 word
);
109 #ifdef TRY_POPCNT_FAST
110 static bool pg_popcount_available(void);
111 static int pg_popcount32_choose(uint32 word
);
112 static int pg_popcount64_choose(uint64 word
);
113 static int pg_popcount32_fast(uint32 word
);
114 static int pg_popcount64_fast(uint64 word
);
116 int (*pg_popcount32
) (uint32 word
) = pg_popcount32_choose
;
117 int (*pg_popcount64
) (uint64 word
) = pg_popcount64_choose
;
118 #endif /* TRY_POPCNT_FAST */
120 #ifdef TRY_POPCNT_FAST
123 * Return true if CPUID indicates that the POPCNT instruction is available.
126 pg_popcount_available(void)
128 unsigned int exx
[4] = {0, 0, 0, 0};
130 #if defined(HAVE__GET_CPUID)
131 __get_cpuid(1, &exx
[0], &exx
[1], &exx
[2], &exx
[3]);
132 #elif defined(HAVE__CPUID)
135 #error cpuid instruction not available
138 return (exx
[2] & (1 << 23)) != 0; /* POPCNT */
142 * These functions get called on the first call to pg_popcount32 etc.
143 * They detect whether we can use the asm implementations, and replace
144 * the function pointers so that subsequent calls are routed directly to
145 * the chosen implementation.
148 pg_popcount32_choose(uint32 word
)
150 if (pg_popcount_available())
152 pg_popcount32
= pg_popcount32_fast
;
153 pg_popcount64
= pg_popcount64_fast
;
157 pg_popcount32
= pg_popcount32_slow
;
158 pg_popcount64
= pg_popcount64_slow
;
161 return pg_popcount32(word
);
165 pg_popcount64_choose(uint64 word
)
167 if (pg_popcount_available())
169 pg_popcount32
= pg_popcount32_fast
;
170 pg_popcount64
= pg_popcount64_fast
;
174 pg_popcount32
= pg_popcount32_slow
;
175 pg_popcount64
= pg_popcount64_slow
;
178 return pg_popcount64(word
);
183 * Return the number of 1 bits set in word
186 pg_popcount32_fast(uint32 word
)
189 return __popcnt(word
);
193 __asm__
__volatile__(" popcntl %1,%0\n":"=q"(res
):"rm"(word
):"cc");
200 * Return the number of 1 bits set in word
203 pg_popcount64_fast(uint64 word
)
206 return __popcnt64(word
);
210 __asm__
__volatile__(" popcntq %1,%0\n":"=q"(res
):"rm"(word
):"cc");
215 #endif /* TRY_POPCNT_FAST */
220 * Return the number of 1 bits set in word
223 pg_popcount32_slow(uint32 word
)
225 #ifdef HAVE__BUILTIN_POPCOUNT
226 return __builtin_popcount(word
);
227 #else /* !HAVE__BUILTIN_POPCOUNT */
232 result
+= pg_number_of_ones
[word
& 255];
237 #endif /* HAVE__BUILTIN_POPCOUNT */
242 * Return the number of 1 bits set in word
245 pg_popcount64_slow(uint64 word
)
247 #ifdef HAVE__BUILTIN_POPCOUNT
248 #if defined(HAVE_LONG_INT_64)
249 return __builtin_popcountl(word
);
250 #elif defined(HAVE_LONG_LONG_INT_64)
251 return __builtin_popcountll(word
);
253 #error must have a working 64-bit integer datatype
255 #else /* !HAVE__BUILTIN_POPCOUNT */
260 result
+= pg_number_of_ones
[word
& 255];
265 #endif /* HAVE__BUILTIN_POPCOUNT */
268 #ifndef TRY_POPCNT_FAST
271 * When the POPCNT instruction is not available, there's no point in using
272 * function pointers to vary the implementation between the fast and slow
273 * method. We instead just make these actual external functions when
274 * TRY_POPCNT_FAST is not defined. The compiler should be able to inline
275 * the slow versions here.
278 pg_popcount32(uint32 word
)
280 return pg_popcount32_slow(word
);
284 pg_popcount64(uint64 word
)
286 return pg_popcount64_slow(word
);
289 #endif /* !TRY_POPCNT_FAST */
293 * Returns the number of 1-bits in buf
296 pg_popcount(const char *buf
, int bytes
)
300 #if SIZEOF_VOID_P >= 8
301 /* Process in 64-bit chunks if the buffer is aligned. */
302 if (buf
== (const char *) TYPEALIGN(8, buf
))
304 const uint64
*words
= (const uint64
*) buf
;
308 popcnt
+= pg_popcount64(*words
++);
312 buf
= (const char *) words
;
315 /* Process in 32-bit chunks if the buffer is aligned. */
316 if (buf
== (const char *) TYPEALIGN(4, buf
))
318 const uint32
*words
= (const uint32
*) buf
;
322 popcnt
+= pg_popcount32(*words
++);
326 buf
= (const char *) words
;
330 /* Process any remaining bytes */
332 popcnt
+= pg_number_of_ones
[(unsigned char) *buf
++];