1 1.17 rin /* $NetBSD: bitops.h,v 1.17 2024/10/02 01:56:02 rin Exp $ */ 2 1.1 riastrad 3 1.1 riastrad /*- 4 1.1 riastrad * Copyright (c) 2013 The NetBSD Foundation, Inc. 5 1.1 riastrad * All rights reserved. 6 1.1 riastrad * 7 1.1 riastrad * This code is derived from software contributed to The NetBSD Foundation 8 1.1 riastrad * by Taylor R. Campbell. 9 1.1 riastrad * 10 1.1 riastrad * Redistribution and use in source and binary forms, with or without 11 1.1 riastrad * modification, are permitted provided that the following conditions 12 1.1 riastrad * are met: 13 1.1 riastrad * 1. Redistributions of source code must retain the above copyright 14 1.1 riastrad * notice, this list of conditions and the following disclaimer. 15 1.1 riastrad * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 riastrad * notice, this list of conditions and the following disclaimer in the 17 1.1 riastrad * documentation and/or other materials provided with the distribution. 18 1.1 riastrad * 19 1.1 riastrad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 riastrad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 riastrad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 riastrad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 riastrad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 riastrad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 riastrad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 riastrad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 riastrad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 riastrad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 riastrad * POSSIBILITY OF SUCH DAMAGE. 30 1.1 riastrad */ 31 1.1 riastrad 32 1.1 riastrad #ifndef _LINUX_BITOPS_H_ 33 1.1 riastrad #define _LINUX_BITOPS_H_ 34 1.1 riastrad 35 1.1 riastrad #include <sys/cdefs.h> 36 1.1 riastrad #include <sys/types.h> 37 1.1 riastrad #include <sys/param.h> 38 1.1 riastrad #include <sys/atomic.h> 39 1.1 riastrad #include <sys/bitops.h> 40 1.1 riastrad 41 1.1 riastrad #include <machine/limits.h> 42 1.1 riastrad 43 1.1 riastrad #include <lib/libkern/libkern.h> 44 1.16 riastrad 45 1.16 riastrad #include <asm/barrier.h> 46 1.16 riastrad 47 1.14 riastrad #include <linux/bits.h> 48 1.1 riastrad 49 1.1 riastrad /* 50 1.1 riastrad * Linux __ffs/__ffs64 is zero-based; zero input is undefined. Our 51 1.1 riastrad * ffs/ffs64 is one-based; zero input yields zero. 52 1.1 riastrad */ 53 1.1 riastrad static inline unsigned long 54 1.1 riastrad __ffs(unsigned long x) 55 1.1 riastrad { 56 1.1 riastrad 57 1.1 riastrad KASSERT(x != 0); 58 1.1 riastrad return ffs64(x) - 1; 59 1.1 riastrad } 60 1.1 riastrad 61 1.1 riastrad static inline unsigned long 62 1.1 riastrad __ffs64(uint64_t x) 63 1.1 riastrad { 64 1.1 riastrad 65 1.1 riastrad KASSERT(x != 0); 66 1.1 riastrad return ffs64(x) - 1; 67 1.1 riastrad } 68 1.1 riastrad 69 1.4 riastrad /* 70 1.4 riastrad * Linux fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32, so it matches 71 1.4 riastrad * our fls semantics. 72 1.4 riastrad */ 73 1.4 riastrad static inline int 74 1.4 riastrad fls(int x) 75 1.4 riastrad { 76 1.4 riastrad return fls32(x); 77 1.4 riastrad } 78 1.4 riastrad 79 1.1 riastrad static inline unsigned int 80 1.7 riastrad hweight8(uint8_t w) 81 1.7 riastrad { 82 1.7 riastrad return popcount(w & 0xff); 83 1.7 riastrad } 84 1.7 riastrad 85 1.7 riastrad static inline unsigned int 86 1.1 riastrad hweight16(uint16_t n) 87 1.1 riastrad { 88 1.1 riastrad return popcount32(n); 89 1.1 riastrad } 90 1.1 riastrad 91 1.1 riastrad static inline unsigned int 92 1.1 riastrad hweight32(uint32_t n) 93 1.1 riastrad { 94 1.1 riastrad return popcount32(n); 95 1.1 riastrad } 96 1.1 riastrad 97 1.3 riastrad static inline unsigned int 98 1.3 riastrad hweight64(uint64_t n) 99 1.3 riastrad { 100 1.3 riastrad return popcount64(n); 101 1.3 riastrad } 102 1.3 riastrad 103 1.11 riastrad static inline int64_t 104 1.11 riastrad sign_extend64(uint64_t x, unsigned n) 105 1.11 riastrad { 106 1.11 riastrad return (int64_t)(x << (63 - n)) >> (63 - n); 107 1.11 riastrad } 108 1.11 riastrad 109 1.1 riastrad #define BITS_TO_LONGS(n) \ 110 1.17 rin howmany((n), (sizeof(unsigned long) * CHAR_BIT)) 111 1.1 riastrad 112 1.15 riastrad #define BITS_PER_TYPE(type) (sizeof(type) * NBBY) 113 1.15 riastrad #define BITS_PER_BYTE NBBY 114 1.15 riastrad #define BITS_PER_LONG (__SIZEOF_LONG__ * CHAR_BIT) 115 1.10 riastrad 116 1.10 riastrad #define BIT(n) ((unsigned long)__BIT(n)) 117 1.10 riastrad #define BIT_ULL(n) ((unsigned long long)__BIT(n)) 118 1.11 riastrad #define GENMASK(h,l) ((unsigned long)__BITS(h,l)) 119 1.11 riastrad #define GENMASK_ULL(h,l)((unsigned long long)__BITS(h,l)) 120 1.1 riastrad 121 1.1 riastrad static inline int 122 1.1 riastrad test_bit(unsigned int n, const volatile unsigned long *p) 123 1.1 riastrad { 124 1.1 riastrad const unsigned units = (sizeof(unsigned long) * CHAR_BIT); 125 1.1 riastrad 126 1.1 riastrad return ((p[n / units] & (1UL << (n % units))) != 0); 127 1.1 riastrad } 128 1.1 riastrad 129 1.1 riastrad static inline void 130 1.1 riastrad __set_bit(unsigned int n, volatile unsigned long *p) 131 1.1 riastrad { 132 1.1 riastrad const unsigned units = (sizeof(unsigned long) * CHAR_BIT); 133 1.1 riastrad 134 1.1 riastrad p[n / units] |= (1UL << (n % units)); 135 1.1 riastrad } 136 1.1 riastrad 137 1.1 riastrad static inline void 138 1.1 riastrad __clear_bit(unsigned int n, volatile unsigned long *p) 139 1.1 riastrad { 140 1.1 riastrad const unsigned units = (sizeof(unsigned long) * CHAR_BIT); 141 1.1 riastrad 142 1.1 riastrad p[n / units] &= ~(1UL << (n % units)); 143 1.1 riastrad } 144 1.1 riastrad 145 1.1 riastrad static inline void 146 1.1 riastrad __change_bit(unsigned int n, volatile unsigned long *p) 147 1.1 riastrad { 148 1.1 riastrad const unsigned units = (sizeof(unsigned long) * CHAR_BIT); 149 1.1 riastrad 150 1.1 riastrad p[n / units] ^= (1UL << (n % units)); 151 1.1 riastrad } 152 1.1 riastrad 153 1.1 riastrad static inline unsigned long 154 1.1 riastrad __test_and_set_bit(unsigned int bit, volatile unsigned long *ptr) 155 1.1 riastrad { 156 1.1 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 157 1.1 riastrad volatile unsigned long *const p = &ptr[bit / units]; 158 1.1 riastrad const unsigned long mask = (1UL << (bit % units)); 159 1.1 riastrad unsigned long v; 160 1.1 riastrad 161 1.1 riastrad v = *p; 162 1.1 riastrad *p |= mask; 163 1.1 riastrad 164 1.1 riastrad return ((v & mask) != 0); 165 1.1 riastrad } 166 1.1 riastrad 167 1.1 riastrad static inline unsigned long 168 1.1 riastrad __test_and_clear_bit(unsigned int bit, volatile unsigned long *ptr) 169 1.1 riastrad { 170 1.1 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 171 1.1 riastrad volatile unsigned long *const p = &ptr[bit / units]; 172 1.1 riastrad const unsigned long mask = (1UL << (bit % units)); 173 1.1 riastrad unsigned long v; 174 1.1 riastrad 175 1.1 riastrad v = *p; 176 1.1 riastrad *p &= ~mask; 177 1.1 riastrad 178 1.1 riastrad return ((v & mask) != 0); 179 1.1 riastrad } 180 1.1 riastrad 181 1.1 riastrad static inline unsigned long 182 1.1 riastrad __test_and_change_bit(unsigned int bit, volatile unsigned long *ptr) 183 1.1 riastrad { 184 1.1 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 185 1.1 riastrad volatile unsigned long *const p = &ptr[bit / units]; 186 1.1 riastrad const unsigned long mask = (1UL << (bit % units)); 187 1.1 riastrad unsigned long v; 188 1.1 riastrad 189 1.1 riastrad v = *p; 190 1.1 riastrad *p ^= mask; 191 1.1 riastrad 192 1.1 riastrad return ((v & mask) != 0); 193 1.1 riastrad } 194 1.1 riastrad 195 1.1 riastrad static inline unsigned long 196 1.6 riastrad __find_next_bit(const unsigned long *ptr, unsigned long nbits, 197 1.6 riastrad unsigned long startbit, unsigned long toggle) 198 1.1 riastrad { 199 1.1 riastrad const size_t bpl = (CHAR_BIT * sizeof(*ptr)); 200 1.5 riastrad const unsigned long *p = ptr + startbit/bpl; 201 1.8 riastrad size_t n = howmany(nbits, bpl); 202 1.8 riastrad unsigned long result; 203 1.5 riastrad uint64_t word; 204 1.5 riastrad 205 1.5 riastrad /* 206 1.5 riastrad * We use ffs64 because NetBSD doesn't have a handy ffsl that 207 1.5 riastrad * works on unsigned long. This is a waste on 32-bit systems 208 1.5 riastrad * but I'd rather not maintain multiple copies of this -- the 209 1.5 riastrad * first version had enough bugs already. 210 1.5 riastrad */ 211 1.5 riastrad 212 1.5 riastrad /* Do we need to examine a partial starting word? */ 213 1.5 riastrad if (startbit % bpl) { 214 1.8 riastrad /* Toggle the bits and convert to 64 bits for ffs64. */ 215 1.8 riastrad word = *p ^ toggle; 216 1.8 riastrad 217 1.8 riastrad /* Clear the low startbit%bpl bits. */ 218 1.8 riastrad word &= (~0UL << (startbit % bpl)); 219 1.8 riastrad 220 1.8 riastrad /* Are any of these bits set now? */ 221 1.8 riastrad if (word) 222 1.8 riastrad goto out; 223 1.8 riastrad 224 1.8 riastrad /* Move past it. */ 225 1.8 riastrad p++; 226 1.8 riastrad n--; 227 1.5 riastrad } 228 1.1 riastrad 229 1.8 riastrad /* Find the first word with any bits set. */ 230 1.8 riastrad for (; n --> 0; p++) { 231 1.8 riastrad /* Toggle the bits and convert to 64 bits for ffs64. */ 232 1.8 riastrad word = *p ^ toggle; 233 1.8 riastrad 234 1.8 riastrad /* Are any of these bits set now? */ 235 1.8 riastrad if (word) 236 1.8 riastrad goto out; 237 1.1 riastrad } 238 1.1 riastrad 239 1.8 riastrad /* Nada. */ 240 1.8 riastrad return nbits; 241 1.8 riastrad 242 1.8 riastrad out: 243 1.8 riastrad /* Count how many words we've skipped. */ 244 1.8 riastrad result = bpl*(p - ptr); 245 1.5 riastrad 246 1.8 riastrad /* Find the first set bit in this word, zero-based. */ 247 1.8 riastrad result += ffs64(word) - 1; 248 1.5 riastrad 249 1.8 riastrad /* We may have overshot, so clamp down to at most nbits. */ 250 1.5 riastrad return MIN(result, nbits); 251 1.5 riastrad } 252 1.5 riastrad 253 1.5 riastrad static inline unsigned long 254 1.6 riastrad find_next_bit(const unsigned long *ptr, unsigned long nbits, 255 1.6 riastrad unsigned long startbit) 256 1.6 riastrad { 257 1.6 riastrad return __find_next_bit(ptr, nbits, startbit, 0); 258 1.6 riastrad } 259 1.6 riastrad 260 1.6 riastrad static inline unsigned long 261 1.6 riastrad find_first_bit(const unsigned long *ptr, unsigned long nbits) 262 1.6 riastrad { 263 1.6 riastrad return find_next_bit(ptr, nbits, 0); 264 1.6 riastrad } 265 1.6 riastrad 266 1.6 riastrad static inline unsigned long 267 1.6 riastrad find_next_zero_bit(const unsigned long *ptr, unsigned long nbits, 268 1.6 riastrad unsigned long startbit) 269 1.6 riastrad { 270 1.6 riastrad return __find_next_bit(ptr, nbits, startbit, ~0UL); 271 1.6 riastrad } 272 1.6 riastrad 273 1.6 riastrad static inline unsigned long 274 1.5 riastrad find_first_zero_bit(const unsigned long *ptr, unsigned long nbits) 275 1.5 riastrad { 276 1.5 riastrad return find_next_zero_bit(ptr, nbits, 0); 277 1.1 riastrad } 278 1.1 riastrad 279 1.6 riastrad #define for_each_set_bit(BIT, PTR, NBITS) \ 280 1.6 riastrad for ((BIT) = find_first_bit((PTR), (NBITS)); \ 281 1.6 riastrad (BIT) < (NBITS); \ 282 1.6 riastrad (BIT) = find_next_bit((PTR), (NBITS), (BIT) + 1)) 283 1.6 riastrad 284 1.11 riastrad #define for_each_clear_bit(BIT, PTR, NBITS) \ 285 1.11 riastrad for ((BIT) = find_first_zero_bit((PTR), (NBITS)); \ 286 1.11 riastrad (BIT) < (NBITS); \ 287 1.11 riastrad (BIT) = find_next_zero_bit((PTR), (NBITS), (BIT) + 1)) 288 1.11 riastrad 289 1.16 riastrad static inline void 290 1.16 riastrad set_bit(unsigned int bit, volatile unsigned long *ptr) 291 1.16 riastrad { 292 1.16 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 293 1.16 riastrad 294 1.16 riastrad /* no memory barrier */ 295 1.16 riastrad atomic_or_ulong(&ptr[bit / units], (1UL << (bit % units))); 296 1.16 riastrad } 297 1.16 riastrad 298 1.16 riastrad static inline void 299 1.16 riastrad clear_bit(unsigned int bit, volatile unsigned long *ptr) 300 1.16 riastrad { 301 1.16 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 302 1.16 riastrad 303 1.16 riastrad /* no memory barrier */ 304 1.16 riastrad atomic_and_ulong(&ptr[bit / units], ~(1UL << (bit % units))); 305 1.16 riastrad } 306 1.16 riastrad 307 1.16 riastrad static inline void 308 1.16 riastrad clear_bit_unlock(unsigned int bit, volatile unsigned long *ptr) 309 1.16 riastrad { 310 1.16 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 311 1.16 riastrad 312 1.16 riastrad /* store-release */ 313 1.16 riastrad smp_mb__before_atomic(); 314 1.16 riastrad atomic_and_ulong(&ptr[bit / units], ~(1UL << (bit % units))); 315 1.16 riastrad } 316 1.16 riastrad 317 1.16 riastrad static inline void 318 1.16 riastrad change_bit(unsigned int bit, volatile unsigned long *ptr) 319 1.16 riastrad { 320 1.16 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 321 1.16 riastrad volatile unsigned long *const p = &ptr[bit / units]; 322 1.16 riastrad const unsigned long mask = (1UL << (bit % units)); 323 1.16 riastrad unsigned long v; 324 1.16 riastrad 325 1.16 riastrad /* no memory barrier */ 326 1.16 riastrad do v = *p; while (atomic_cas_ulong(p, v, (v ^ mask)) != v); 327 1.16 riastrad } 328 1.16 riastrad 329 1.16 riastrad static inline int 330 1.16 riastrad test_and_set_bit(unsigned int bit, volatile unsigned long *ptr) 331 1.16 riastrad { 332 1.16 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 333 1.16 riastrad volatile unsigned long *const p = &ptr[bit / units]; 334 1.16 riastrad const unsigned long mask = (1UL << (bit % units)); 335 1.16 riastrad unsigned long v; 336 1.16 riastrad 337 1.16 riastrad smp_mb__before_atomic(); 338 1.16 riastrad do v = *p; while (atomic_cas_ulong(p, v, (v | mask)) != v); 339 1.16 riastrad smp_mb__after_atomic(); 340 1.16 riastrad 341 1.16 riastrad return ((v & mask) != 0); 342 1.16 riastrad } 343 1.16 riastrad 344 1.16 riastrad static inline int 345 1.16 riastrad test_and_clear_bit(unsigned int bit, volatile unsigned long *ptr) 346 1.16 riastrad { 347 1.16 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 348 1.16 riastrad volatile unsigned long *const p = &ptr[bit / units]; 349 1.16 riastrad const unsigned long mask = (1UL << (bit % units)); 350 1.16 riastrad unsigned long v; 351 1.16 riastrad 352 1.16 riastrad smp_mb__before_atomic(); 353 1.16 riastrad do v = *p; while (atomic_cas_ulong(p, v, (v & ~mask)) != v); 354 1.16 riastrad smp_mb__after_atomic(); 355 1.16 riastrad 356 1.16 riastrad return ((v & mask) != 0); 357 1.16 riastrad } 358 1.16 riastrad 359 1.16 riastrad static inline int 360 1.16 riastrad test_and_change_bit(unsigned int bit, volatile unsigned long *ptr) 361 1.16 riastrad { 362 1.16 riastrad const unsigned int units = (sizeof(*ptr) * CHAR_BIT); 363 1.16 riastrad volatile unsigned long *const p = &ptr[bit / units]; 364 1.16 riastrad const unsigned long mask = (1UL << (bit % units)); 365 1.16 riastrad unsigned long v; 366 1.16 riastrad 367 1.16 riastrad smp_mb__before_atomic(); 368 1.16 riastrad do v = *p; while (atomic_cas_ulong(p, v, (v ^ mask)) != v); 369 1.16 riastrad smp_mb__after_atomic(); 370 1.16 riastrad 371 1.16 riastrad return ((v & mask) != 0); 372 1.16 riastrad } 373 1.16 riastrad 374 1.1 riastrad #endif /* _LINUX_BITOPS_H_ */ 375