1 /* CC0 license (public domain) - see LICENSE file for details */
7 #if defined(CCAN_DEBUG) || defined(CCAN_BITOPS_DEBUG)
9 #define BITOPS_ASSERT_NONZERO(u) assert((u) != 0)
11 #define BITOPS_ASSERT_NONZERO(u)
14 #if HAVE_BUILTIN_FFS && HAVE_BUILTIN_FFSL && HAVE_BUILTIN_FFSLL
16 * bitops_ffs32: find first set bit in a uint32_t
18 * Returns 1 for least signficant bit, 32 for most significant bit, 0
21 static inline int bitops_ffs32(uint32_t u)
23 return __builtin_ffs(u);
27 * bitops_ffs64: find lowest set bit in a uint64_t
29 * Returns 1 for least signficant bit, 32 for most significant bit, 0
32 static inline int bitops_ffs64(uint64_t u)
34 if (sizeof(u) == sizeof(long))
35 return __builtin_ffsl(u);
37 return __builtin_ffsll(u);
40 int bitops_ffs32(uint32_t u);
41 int bitops_ffs64(uint64_t u);
42 #define BITOPS_NEED_FFS 1
45 #if HAVE_BUILTIN_CLZ && HAVE_BUILTIN_CLZL && HAVE_BUILTIN_CLZLL
47 * bitops_clz32: count leading zeros in a uint32_t (must not be 0)
49 * Returns 0 if most signficant bit is set, 31 if only least
50 * signficant bit is set.
52 static inline int bitops_clz32(uint32_t u)
54 BITOPS_ASSERT_NONZERO(u);
55 return __builtin_clz(u);
59 * bitops_clz64: count leading zeros in a uint64_t (must not be 0)
61 * Returns 0 if most signficant bit is set, 63 if only least
62 * signficant bit is set.
64 static inline int bitops_clz64(uint64_t u)
66 BITOPS_ASSERT_NONZERO(u);
67 if (sizeof(u) == sizeof(long))
68 return __builtin_clzl(u);
70 return __builtin_clzll(u);
73 int bitops_clz32(uint32_t u);
74 int bitops_clz64(uint64_t u);
75 #define BITOPS_NEED_CLZ 1
78 #if HAVE_BUILTIN_CTZ && HAVE_BUILTIN_CTZL && HAVE_BUILTIN_CTZLL
80 * bitops_ctz32: count trailing zeros in a uint32_t (must not be 0)
82 * Returns 0 if least signficant bit is set, 31 if only most
83 * signficant bit is set.
85 static inline int bitops_ctz32(uint32_t u)
87 BITOPS_ASSERT_NONZERO(u);
88 return __builtin_ctz(u);
92 * bitops_ctz64: count trailing zeros in a uint64_t (must not be 0)
94 * Returns 0 if least signficant bit is set, 63 if only most
95 * signficant bit is set.
97 static inline int bitops_ctz64(uint64_t u)
99 BITOPS_ASSERT_NONZERO(u);
100 if (sizeof(u) == sizeof(long))
101 return __builtin_ctzl(u);
103 return __builtin_ctzll(u);
106 int bitops_ctz32(uint32_t u);
107 int bitops_ctz64(uint64_t u);
108 #define BITOPS_NEED_CTZ 1
112 * bitops_ls32: find lowest set bit in a uint32_t (must not be zero)
114 * Returns 0 for least signficant bit, 31 for most significant bit.
116 static inline int bitops_ls32(uint32_t u)
118 BITOPS_ASSERT_NONZERO(u);
119 return bitops_ffs32(u) - 1;
123 * bitops_ls64: find lowest set bit in a uint64_t (must not be zero)
125 * Returns 0 for least signficant bit, 63 for most significant bit.
127 static inline int bitops_ls64(uint64_t u)
129 BITOPS_ASSERT_NONZERO(u);
130 return bitops_ffs64(u) - 1;
134 * bitops_hs32: find highest set bit in a uint32_t (must not be zero)
136 * Returns 0 for least signficant bit, 31 for most significant bit.
138 static inline int bitops_hs32(uint32_t u)
140 BITOPS_ASSERT_NONZERO(u);
141 return 31 - bitops_clz32(u);
145 * bitops_hs64: find highest set bit in a uint64_t (must not be zero)
147 * Returns 0 for least signficant bit, 63 for most significant bit.
149 static inline int bitops_hs64(uint64_t u)
151 BITOPS_ASSERT_NONZERO(u);
152 return 63 - bitops_clz64(u);
156 * bitops_lc32: find lowest clear bit in a uint32_t (must not be 0xFFFFFFFF)
158 * Returns 0 for least signficant bit, 31 for most significant bit.
160 static inline int bitops_lc32(uint32_t u)
162 return bitops_ctz32(~u);
166 * bitops_lc64: find lowest clear bit in a uint64_t (must not be 0xFFFFFFFFFFFFFFFF)
168 * Returns 0 for least signficant bit, 63 for most significant bit.
170 static inline int bitops_lc64(uint64_t u)
172 return bitops_ctz64(~u);
176 * bitops_hc32: find highest clear bit in a uint32_t (must not be 0xFFFFFFFF)
178 * Returns 0 for least signficant bit, 31 for most significant bit.
180 static inline int bitops_hc32(uint32_t u)
182 return 31 - bitops_clz32(~u);
186 * bitops_hc64: find highest clear bit in a uint64_t (must not be 0xFFFFFFFFFFFFFFFF)
188 * Returns 0 for least signficant bit, 63 for most significant bit.
190 static inline int bitops_hc64(uint64_t u)
192 return 63 - bitops_clz64(~u);
195 #if HAVE_BUILTIN_POPCOUNT && HAVE_BUILTIN_POPCOUNTL && HAVE_BUILTIN_POPCOUNTLL
197 * bitops_weight32: count number of bits set in a uint32_t
201 static inline int bitops_weight32(uint32_t u)
203 return __builtin_popcount(u);
207 * bitops_weight64: count number of bits set in a uint64_t
211 static inline int bitops_weight64(uint64_t u)
213 if (sizeof(u) == sizeof(long))
214 return __builtin_popcountl(u);
216 return __builtin_popcountll(u);
219 int bitops_weight32(uint32_t u);
220 int bitops_weight64(uint64_t u);
221 #define BITOPS_NEED_WEIGHT 1
223 #endif /* CCAN_BITOPS_H */