1 // SPDX-License-Identifier: GPL-2.0
3 * MSB0 numbered special bitops handling.
5 * The bits are numbered:
6 * |0..............63|64............127|128...........191|192...........255|
8 * The reason for this bit numbering is the fact that the hardware sets bits
9 * in a bitmap starting at bit 0 (MSB) and we don't want to scan the bitmap
10 * from the 'wrong end'.
13 #include <linux/compiler.h>
14 #include <linux/bitops.h>
15 #include <linux/export.h>
17 unsigned long find_first_bit_inv(const unsigned long *addr
, unsigned long size
)
19 const unsigned long *p
= addr
;
20 unsigned long result
= 0;
23 while (size
& ~(BITS_PER_LONG
- 1)) {
26 result
+= BITS_PER_LONG
;
27 size
-= BITS_PER_LONG
;
31 tmp
= (*p
) & (~0UL << (BITS_PER_LONG
- size
));
32 if (!tmp
) /* Are any bits set? */
33 return result
+ size
; /* Nope. */
35 return result
+ (__fls(tmp
) ^ (BITS_PER_LONG
- 1));
37 EXPORT_SYMBOL(find_first_bit_inv
);
39 unsigned long find_next_bit_inv(const unsigned long *addr
, unsigned long size
,
42 const unsigned long *p
= addr
+ (offset
/ BITS_PER_LONG
);
43 unsigned long result
= offset
& ~(BITS_PER_LONG
- 1);
49 offset
%= BITS_PER_LONG
;
52 tmp
&= (~0UL >> offset
);
53 if (size
< BITS_PER_LONG
)
57 size
-= BITS_PER_LONG
;
58 result
+= BITS_PER_LONG
;
60 while (size
& ~(BITS_PER_LONG
-1)) {
63 result
+= BITS_PER_LONG
;
64 size
-= BITS_PER_LONG
;
70 tmp
&= (~0UL << (BITS_PER_LONG
- size
));
71 if (!tmp
) /* Are any bits set? */
72 return result
+ size
; /* Nope. */
74 return result
+ (__fls(tmp
) ^ (BITS_PER_LONG
- 1));
76 EXPORT_SYMBOL(find_next_bit_inv
);