xref: /linux-6.15/include/linux/find.h (revision fda1dd3c)
147d8c156SYury Norov /* SPDX-License-Identifier: GPL-2.0 */
247d8c156SYury Norov #ifndef __LINUX_FIND_H_
347d8c156SYury Norov #define __LINUX_FIND_H_
447d8c156SYury Norov 
547d8c156SYury Norov #ifndef __LINUX_BITMAP_H
647d8c156SYury Norov #error only <linux/bitmap.h> can be included directly
747d8c156SYury Norov #endif
847d8c156SYury Norov 
947d8c156SYury Norov #include <linux/bitops.h>
1047d8c156SYury Norov 
11e79864f3SYury Norov unsigned long _find_next_bit(const unsigned long *addr1, unsigned long nbits,
12e79864f3SYury Norov 				unsigned long start);
13e79864f3SYury Norov unsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2,
14e79864f3SYury Norov 					unsigned long nbits, unsigned long start);
1590d48290SValentin Schneider unsigned long _find_next_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
1690d48290SValentin Schneider 					unsigned long nbits, unsigned long start);
171470afefSDave Chinner unsigned long _find_next_or_bit(const unsigned long *addr1, const unsigned long *addr2,
181470afefSDave Chinner 					unsigned long nbits, unsigned long start);
19e79864f3SYury Norov unsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits,
20e79864f3SYury Norov 					 unsigned long start);
2147d8c156SYury Norov extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size);
223cea8d47SYury Norov unsigned long __find_nth_bit(const unsigned long *addr, unsigned long size, unsigned long n);
233cea8d47SYury Norov unsigned long __find_nth_and_bit(const unsigned long *addr1, const unsigned long *addr2,
243cea8d47SYury Norov 				unsigned long size, unsigned long n);
253cea8d47SYury Norov unsigned long __find_nth_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
263cea8d47SYury Norov 					unsigned long size, unsigned long n);
2743245117SYury Norov unsigned long __find_nth_and_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
2843245117SYury Norov 					const unsigned long *addr3, unsigned long size,
2943245117SYury Norov 					unsigned long n);
30f68edc92SYury Norov extern unsigned long _find_first_and_bit(const unsigned long *addr1,
31f68edc92SYury Norov 					 const unsigned long *addr2, unsigned long size);
32cdc66553SDawei Li unsigned long _find_first_and_and_bit(const unsigned long *addr1, const unsigned long *addr2,
33cdc66553SDawei Li 				      const unsigned long *addr3, unsigned long size);
3447d8c156SYury Norov extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size);
3547d8c156SYury Norov extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size);
3647d8c156SYury Norov 
3714a99e13SYury Norov #ifdef __BIG_ENDIAN
3814a99e13SYury Norov unsigned long _find_first_zero_bit_le(const unsigned long *addr, unsigned long size);
39e79864f3SYury Norov unsigned long _find_next_zero_bit_le(const  unsigned long *addr, unsigned
40e79864f3SYury Norov 					long size, unsigned long offset);
41e79864f3SYury Norov unsigned long _find_next_bit_le(const unsigned long *addr, unsigned
42e79864f3SYury Norov 				long size, unsigned long offset);
4314a99e13SYury Norov #endif
4414a99e13SYury Norov 
4547d8c156SYury Norov #ifndef find_next_bit
4647d8c156SYury Norov /**
4747d8c156SYury Norov  * find_next_bit - find the next set bit in a memory region
4847d8c156SYury Norov  * @addr: The address to base the search on
4947d8c156SYury Norov  * @size: The bitmap size in bits
506d7131bdSAnna-Maria Behnsen  * @offset: The bitnumber to start searching at
5147d8c156SYury Norov  *
5247d8c156SYury Norov  * Returns the bit number for the next set bit
5347d8c156SYury Norov  * If no bits are set, returns @size.
5447d8c156SYury Norov  */
55*fda1dd3cSYury Norov static __always_inline
find_next_bit(const unsigned long * addr,unsigned long size,unsigned long offset)5647d8c156SYury Norov unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
5747d8c156SYury Norov 			    unsigned long offset)
5847d8c156SYury Norov {
5947d8c156SYury Norov 	if (small_const_nbits(size)) {
6047d8c156SYury Norov 		unsigned long val;
6147d8c156SYury Norov 
6247d8c156SYury Norov 		if (unlikely(offset >= size))
6347d8c156SYury Norov 			return size;
6447d8c156SYury Norov 
6547d8c156SYury Norov 		val = *addr & GENMASK(size - 1, offset);
6647d8c156SYury Norov 		return val ? __ffs(val) : size;
6747d8c156SYury Norov 	}
6847d8c156SYury Norov 
69e79864f3SYury Norov 	return _find_next_bit(addr, size, offset);
7047d8c156SYury Norov }
7147d8c156SYury Norov #endif
7247d8c156SYury Norov 
7347d8c156SYury Norov #ifndef find_next_and_bit
7447d8c156SYury Norov /**
7547d8c156SYury Norov  * find_next_and_bit - find the next set bit in both memory regions
7647d8c156SYury Norov  * @addr1: The first address to base the search on
7747d8c156SYury Norov  * @addr2: The second address to base the search on
7847d8c156SYury Norov  * @size: The bitmap size in bits
796d7131bdSAnna-Maria Behnsen  * @offset: The bitnumber to start searching at
8047d8c156SYury Norov  *
8147d8c156SYury Norov  * Returns the bit number for the next set bit
8247d8c156SYury Norov  * If no bits are set, returns @size.
8347d8c156SYury Norov  */
84*fda1dd3cSYury Norov static __always_inline
find_next_and_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long offset)8547d8c156SYury Norov unsigned long find_next_and_bit(const unsigned long *addr1,
8647d8c156SYury Norov 		const unsigned long *addr2, unsigned long size,
8747d8c156SYury Norov 		unsigned long offset)
8847d8c156SYury Norov {
8947d8c156SYury Norov 	if (small_const_nbits(size)) {
9047d8c156SYury Norov 		unsigned long val;
9147d8c156SYury Norov 
9247d8c156SYury Norov 		if (unlikely(offset >= size))
9347d8c156SYury Norov 			return size;
9447d8c156SYury Norov 
9547d8c156SYury Norov 		val = *addr1 & *addr2 & GENMASK(size - 1, offset);
9647d8c156SYury Norov 		return val ? __ffs(val) : size;
9747d8c156SYury Norov 	}
9847d8c156SYury Norov 
99e79864f3SYury Norov 	return _find_next_and_bit(addr1, addr2, size, offset);
10047d8c156SYury Norov }
10147d8c156SYury Norov #endif
10247d8c156SYury Norov 
10390d48290SValentin Schneider #ifndef find_next_andnot_bit
10490d48290SValentin Schneider /**
10590d48290SValentin Schneider  * find_next_andnot_bit - find the next set bit in *addr1 excluding all the bits
10690d48290SValentin Schneider  *                        in *addr2
10790d48290SValentin Schneider  * @addr1: The first address to base the search on
10890d48290SValentin Schneider  * @addr2: The second address to base the search on
10990d48290SValentin Schneider  * @size: The bitmap size in bits
11090d48290SValentin Schneider  * @offset: The bitnumber to start searching at
11190d48290SValentin Schneider  *
11290d48290SValentin Schneider  * Returns the bit number for the next set bit
11390d48290SValentin Schneider  * If no bits are set, returns @size.
11490d48290SValentin Schneider  */
115*fda1dd3cSYury Norov static __always_inline
find_next_andnot_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long offset)11690d48290SValentin Schneider unsigned long find_next_andnot_bit(const unsigned long *addr1,
11790d48290SValentin Schneider 		const unsigned long *addr2, unsigned long size,
11890d48290SValentin Schneider 		unsigned long offset)
11990d48290SValentin Schneider {
12090d48290SValentin Schneider 	if (small_const_nbits(size)) {
12190d48290SValentin Schneider 		unsigned long val;
12290d48290SValentin Schneider 
12390d48290SValentin Schneider 		if (unlikely(offset >= size))
12490d48290SValentin Schneider 			return size;
12590d48290SValentin Schneider 
12690d48290SValentin Schneider 		val = *addr1 & ~*addr2 & GENMASK(size - 1, offset);
12790d48290SValentin Schneider 		return val ? __ffs(val) : size;
12890d48290SValentin Schneider 	}
12990d48290SValentin Schneider 
13090d48290SValentin Schneider 	return _find_next_andnot_bit(addr1, addr2, size, offset);
13190d48290SValentin Schneider }
13290d48290SValentin Schneider #endif
13390d48290SValentin Schneider 
1341470afefSDave Chinner #ifndef find_next_or_bit
1351470afefSDave Chinner /**
1361470afefSDave Chinner  * find_next_or_bit - find the next set bit in either memory regions
1371470afefSDave Chinner  * @addr1: The first address to base the search on
1381470afefSDave Chinner  * @addr2: The second address to base the search on
1391470afefSDave Chinner  * @size: The bitmap size in bits
1401470afefSDave Chinner  * @offset: The bitnumber to start searching at
1411470afefSDave Chinner  *
1421470afefSDave Chinner  * Returns the bit number for the next set bit
1431470afefSDave Chinner  * If no bits are set, returns @size.
1441470afefSDave Chinner  */
145*fda1dd3cSYury Norov static __always_inline
find_next_or_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long offset)1461470afefSDave Chinner unsigned long find_next_or_bit(const unsigned long *addr1,
1471470afefSDave Chinner 		const unsigned long *addr2, unsigned long size,
1481470afefSDave Chinner 		unsigned long offset)
1491470afefSDave Chinner {
1501470afefSDave Chinner 	if (small_const_nbits(size)) {
1511470afefSDave Chinner 		unsigned long val;
1521470afefSDave Chinner 
1531470afefSDave Chinner 		if (unlikely(offset >= size))
1541470afefSDave Chinner 			return size;
1551470afefSDave Chinner 
1561470afefSDave Chinner 		val = (*addr1 | *addr2) & GENMASK(size - 1, offset);
1571470afefSDave Chinner 		return val ? __ffs(val) : size;
1581470afefSDave Chinner 	}
1591470afefSDave Chinner 
1601470afefSDave Chinner 	return _find_next_or_bit(addr1, addr2, size, offset);
1611470afefSDave Chinner }
1621470afefSDave Chinner #endif
1631470afefSDave Chinner 
16447d8c156SYury Norov #ifndef find_next_zero_bit
16547d8c156SYury Norov /**
16647d8c156SYury Norov  * find_next_zero_bit - find the next cleared bit in a memory region
16747d8c156SYury Norov  * @addr: The address to base the search on
16847d8c156SYury Norov  * @size: The bitmap size in bits
1696d7131bdSAnna-Maria Behnsen  * @offset: The bitnumber to start searching at
17047d8c156SYury Norov  *
17147d8c156SYury Norov  * Returns the bit number of the next zero bit
17247d8c156SYury Norov  * If no bits are zero, returns @size.
17347d8c156SYury Norov  */
174*fda1dd3cSYury Norov static __always_inline
find_next_zero_bit(const unsigned long * addr,unsigned long size,unsigned long offset)17547d8c156SYury Norov unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
17647d8c156SYury Norov 				 unsigned long offset)
17747d8c156SYury Norov {
17847d8c156SYury Norov 	if (small_const_nbits(size)) {
17947d8c156SYury Norov 		unsigned long val;
18047d8c156SYury Norov 
18147d8c156SYury Norov 		if (unlikely(offset >= size))
18247d8c156SYury Norov 			return size;
18347d8c156SYury Norov 
18447d8c156SYury Norov 		val = *addr | ~GENMASK(size - 1, offset);
18547d8c156SYury Norov 		return val == ~0UL ? size : ffz(val);
18647d8c156SYury Norov 	}
18747d8c156SYury Norov 
188e79864f3SYury Norov 	return _find_next_zero_bit(addr, size, offset);
18947d8c156SYury Norov }
19047d8c156SYury Norov #endif
19147d8c156SYury Norov 
19247d8c156SYury Norov #ifndef find_first_bit
19347d8c156SYury Norov /**
19447d8c156SYury Norov  * find_first_bit - find the first set bit in a memory region
19547d8c156SYury Norov  * @addr: The address to start the search at
19647d8c156SYury Norov  * @size: The maximum number of bits to search
19747d8c156SYury Norov  *
19847d8c156SYury Norov  * Returns the bit number of the first set bit.
19947d8c156SYury Norov  * If no bits are set, returns @size.
20047d8c156SYury Norov  */
201*fda1dd3cSYury Norov static __always_inline
find_first_bit(const unsigned long * addr,unsigned long size)20247d8c156SYury Norov unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
20347d8c156SYury Norov {
20447d8c156SYury Norov 	if (small_const_nbits(size)) {
20547d8c156SYury Norov 		unsigned long val = *addr & GENMASK(size - 1, 0);
20647d8c156SYury Norov 
20747d8c156SYury Norov 		return val ? __ffs(val) : size;
20847d8c156SYury Norov 	}
20947d8c156SYury Norov 
21047d8c156SYury Norov 	return _find_first_bit(addr, size);
21147d8c156SYury Norov }
21247d8c156SYury Norov #endif
21347d8c156SYury Norov 
2143cea8d47SYury Norov /**
2153cea8d47SYury Norov  * find_nth_bit - find N'th set bit in a memory region
2163cea8d47SYury Norov  * @addr: The address to start the search at
2173cea8d47SYury Norov  * @size: The maximum number of bits to search
2183cea8d47SYury Norov  * @n: The number of set bit, which position is needed, counting from 0
2193cea8d47SYury Norov  *
2203cea8d47SYury Norov  * The following is semantically equivalent:
2213cea8d47SYury Norov  *	 idx = find_nth_bit(addr, size, 0);
2223cea8d47SYury Norov  *	 idx = find_first_bit(addr, size);
2233cea8d47SYury Norov  *
2243cea8d47SYury Norov  * Returns the bit number of the N'th set bit.
2250b2811baSYury Norov  * If no such, returns >= @size.
2263cea8d47SYury Norov  */
227*fda1dd3cSYury Norov static __always_inline
find_nth_bit(const unsigned long * addr,unsigned long size,unsigned long n)2283cea8d47SYury Norov unsigned long find_nth_bit(const unsigned long *addr, unsigned long size, unsigned long n)
2293cea8d47SYury Norov {
2303cea8d47SYury Norov 	if (n >= size)
2313cea8d47SYury Norov 		return size;
2323cea8d47SYury Norov 
2333cea8d47SYury Norov 	if (small_const_nbits(size)) {
2343cea8d47SYury Norov 		unsigned long val =  *addr & GENMASK(size - 1, 0);
2353cea8d47SYury Norov 
2363cea8d47SYury Norov 		return val ? fns(val, n) : size;
2373cea8d47SYury Norov 	}
2383cea8d47SYury Norov 
2393cea8d47SYury Norov 	return __find_nth_bit(addr, size, n);
2403cea8d47SYury Norov }
2413cea8d47SYury Norov 
2423cea8d47SYury Norov /**
2433cea8d47SYury Norov  * find_nth_and_bit - find N'th set bit in 2 memory regions
2443cea8d47SYury Norov  * @addr1: The 1st address to start the search at
2453cea8d47SYury Norov  * @addr2: The 2nd address to start the search at
2463cea8d47SYury Norov  * @size: The maximum number of bits to search
2473cea8d47SYury Norov  * @n: The number of set bit, which position is needed, counting from 0
2483cea8d47SYury Norov  *
2493cea8d47SYury Norov  * Returns the bit number of the N'th set bit.
2503cea8d47SYury Norov  * If no such, returns @size.
2513cea8d47SYury Norov  */
252*fda1dd3cSYury Norov static __always_inline
find_nth_and_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long n)2533cea8d47SYury Norov unsigned long find_nth_and_bit(const unsigned long *addr1, const unsigned long *addr2,
2543cea8d47SYury Norov 				unsigned long size, unsigned long n)
2553cea8d47SYury Norov {
2563cea8d47SYury Norov 	if (n >= size)
2573cea8d47SYury Norov 		return size;
2583cea8d47SYury Norov 
2593cea8d47SYury Norov 	if (small_const_nbits(size)) {
2603cea8d47SYury Norov 		unsigned long val =  *addr1 & *addr2 & GENMASK(size - 1, 0);
2613cea8d47SYury Norov 
2623cea8d47SYury Norov 		return val ? fns(val, n) : size;
2633cea8d47SYury Norov 	}
2643cea8d47SYury Norov 
2653cea8d47SYury Norov 	return __find_nth_and_bit(addr1, addr2, size, n);
2663cea8d47SYury Norov }
2673cea8d47SYury Norov 
2683cea8d47SYury Norov /**
2693cea8d47SYury Norov  * find_nth_andnot_bit - find N'th set bit in 2 memory regions,
2703cea8d47SYury Norov  *			 flipping bits in 2nd region
2713cea8d47SYury Norov  * @addr1: The 1st address to start the search at
2723cea8d47SYury Norov  * @addr2: The 2nd address to start the search at
2733cea8d47SYury Norov  * @size: The maximum number of bits to search
2743cea8d47SYury Norov  * @n: The number of set bit, which position is needed, counting from 0
2753cea8d47SYury Norov  *
2763cea8d47SYury Norov  * Returns the bit number of the N'th set bit.
2773cea8d47SYury Norov  * If no such, returns @size.
2783cea8d47SYury Norov  */
279*fda1dd3cSYury Norov static __always_inline
find_nth_andnot_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long n)2803cea8d47SYury Norov unsigned long find_nth_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
2813cea8d47SYury Norov 				unsigned long size, unsigned long n)
2823cea8d47SYury Norov {
2833cea8d47SYury Norov 	if (n >= size)
2843cea8d47SYury Norov 		return size;
2853cea8d47SYury Norov 
2863cea8d47SYury Norov 	if (small_const_nbits(size)) {
2873cea8d47SYury Norov 		unsigned long val =  *addr1 & (~*addr2) & GENMASK(size - 1, 0);
2883cea8d47SYury Norov 
2893cea8d47SYury Norov 		return val ? fns(val, n) : size;
2903cea8d47SYury Norov 	}
2913cea8d47SYury Norov 
2923cea8d47SYury Norov 	return __find_nth_andnot_bit(addr1, addr2, size, n);
2933cea8d47SYury Norov }
2943cea8d47SYury Norov 
29543245117SYury Norov /**
29643245117SYury Norov  * find_nth_and_andnot_bit - find N'th set bit in 2 memory regions,
29743245117SYury Norov  *			     excluding those set in 3rd region
29843245117SYury Norov  * @addr1: The 1st address to start the search at
29943245117SYury Norov  * @addr2: The 2nd address to start the search at
30043245117SYury Norov  * @addr3: The 3rd address to start the search at
30143245117SYury Norov  * @size: The maximum number of bits to search
30243245117SYury Norov  * @n: The number of set bit, which position is needed, counting from 0
30343245117SYury Norov  *
30443245117SYury Norov  * Returns the bit number of the N'th set bit.
30543245117SYury Norov  * If no such, returns @size.
30643245117SYury Norov  */
30743245117SYury Norov static __always_inline
find_nth_and_andnot_bit(const unsigned long * addr1,const unsigned long * addr2,const unsigned long * addr3,unsigned long size,unsigned long n)30843245117SYury Norov unsigned long find_nth_and_andnot_bit(const unsigned long *addr1,
30943245117SYury Norov 					const unsigned long *addr2,
31043245117SYury Norov 					const unsigned long *addr3,
31143245117SYury Norov 					unsigned long size, unsigned long n)
31243245117SYury Norov {
31343245117SYury Norov 	if (n >= size)
31443245117SYury Norov 		return size;
31543245117SYury Norov 
31643245117SYury Norov 	if (small_const_nbits(size)) {
31743245117SYury Norov 		unsigned long val =  *addr1 & *addr2 & (~*addr3) & GENMASK(size - 1, 0);
31843245117SYury Norov 
31943245117SYury Norov 		return val ? fns(val, n) : size;
32043245117SYury Norov 	}
32143245117SYury Norov 
32243245117SYury Norov 	return __find_nth_and_andnot_bit(addr1, addr2, addr3, size, n);
32343245117SYury Norov }
32443245117SYury Norov 
325f68edc92SYury Norov #ifndef find_first_and_bit
326f68edc92SYury Norov /**
327f68edc92SYury Norov  * find_first_and_bit - find the first set bit in both memory regions
328f68edc92SYury Norov  * @addr1: The first address to base the search on
329f68edc92SYury Norov  * @addr2: The second address to base the search on
330f68edc92SYury Norov  * @size: The bitmap size in bits
331f68edc92SYury Norov  *
332f68edc92SYury Norov  * Returns the bit number for the next set bit
333f68edc92SYury Norov  * If no bits are set, returns @size.
334f68edc92SYury Norov  */
335*fda1dd3cSYury Norov static __always_inline
find_first_and_bit(const unsigned long * addr1,const unsigned long * addr2,unsigned long size)336f68edc92SYury Norov unsigned long find_first_and_bit(const unsigned long *addr1,
337f68edc92SYury Norov 				 const unsigned long *addr2,
338f68edc92SYury Norov 				 unsigned long size)
339f68edc92SYury Norov {
340f68edc92SYury Norov 	if (small_const_nbits(size)) {
341f68edc92SYury Norov 		unsigned long val = *addr1 & *addr2 & GENMASK(size - 1, 0);
342f68edc92SYury Norov 
343f68edc92SYury Norov 		return val ? __ffs(val) : size;
344f68edc92SYury Norov 	}
345f68edc92SYury Norov 
346f68edc92SYury Norov 	return _find_first_and_bit(addr1, addr2, size);
347f68edc92SYury Norov }
348f68edc92SYury Norov #endif
349f68edc92SYury Norov 
350cdc66553SDawei Li /**
351cdc66553SDawei Li  * find_first_and_and_bit - find the first set bit in 3 memory regions
352cdc66553SDawei Li  * @addr1: The first address to base the search on
353cdc66553SDawei Li  * @addr2: The second address to base the search on
354cdc66553SDawei Li  * @addr3: The third address to base the search on
355cdc66553SDawei Li  * @size: The bitmap size in bits
356cdc66553SDawei Li  *
357cdc66553SDawei Li  * Returns the bit number for the first set bit
358cdc66553SDawei Li  * If no bits are set, returns @size.
359cdc66553SDawei Li  */
360*fda1dd3cSYury Norov static __always_inline
find_first_and_and_bit(const unsigned long * addr1,const unsigned long * addr2,const unsigned long * addr3,unsigned long size)361cdc66553SDawei Li unsigned long find_first_and_and_bit(const unsigned long *addr1,
362cdc66553SDawei Li 				     const unsigned long *addr2,
363cdc66553SDawei Li 				     const unsigned long *addr3,
364cdc66553SDawei Li 				     unsigned long size)
365cdc66553SDawei Li {
366cdc66553SDawei Li 	if (small_const_nbits(size)) {
367cdc66553SDawei Li 		unsigned long val = *addr1 & *addr2 & *addr3 & GENMASK(size - 1, 0);
368cdc66553SDawei Li 
369cdc66553SDawei Li 		return val ? __ffs(val) : size;
370cdc66553SDawei Li 	}
371cdc66553SDawei Li 
372cdc66553SDawei Li 	return _find_first_and_and_bit(addr1, addr2, addr3, size);
373cdc66553SDawei Li }
374cdc66553SDawei Li 
37547d8c156SYury Norov #ifndef find_first_zero_bit
37647d8c156SYury Norov /**
37747d8c156SYury Norov  * find_first_zero_bit - find the first cleared bit in a memory region
37847d8c156SYury Norov  * @addr: The address to start the search at
37947d8c156SYury Norov  * @size: The maximum number of bits to search
38047d8c156SYury Norov  *
38147d8c156SYury Norov  * Returns the bit number of the first cleared bit.
38247d8c156SYury Norov  * If no bits are zero, returns @size.
38347d8c156SYury Norov  */
384*fda1dd3cSYury Norov static __always_inline
find_first_zero_bit(const unsigned long * addr,unsigned long size)38547d8c156SYury Norov unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
38647d8c156SYury Norov {
38747d8c156SYury Norov 	if (small_const_nbits(size)) {
38847d8c156SYury Norov 		unsigned long val = *addr | ~GENMASK(size - 1, 0);
38947d8c156SYury Norov 
39047d8c156SYury Norov 		return val == ~0UL ? size : ffz(val);
39147d8c156SYury Norov 	}
39247d8c156SYury Norov 
39347d8c156SYury Norov 	return _find_first_zero_bit(addr, size);
39447d8c156SYury Norov }
39547d8c156SYury Norov #endif
39647d8c156SYury Norov 
39747d8c156SYury Norov #ifndef find_last_bit
39847d8c156SYury Norov /**
39947d8c156SYury Norov  * find_last_bit - find the last set bit in a memory region
40047d8c156SYury Norov  * @addr: The address to start the search at
40147d8c156SYury Norov  * @size: The number of bits to search
40247d8c156SYury Norov  *
40347d8c156SYury Norov  * Returns the bit number of the last set bit, or size.
40447d8c156SYury Norov  */
405*fda1dd3cSYury Norov static __always_inline
find_last_bit(const unsigned long * addr,unsigned long size)40647d8c156SYury Norov unsigned long find_last_bit(const unsigned long *addr, unsigned long size)
40747d8c156SYury Norov {
40847d8c156SYury Norov 	if (small_const_nbits(size)) {
40947d8c156SYury Norov 		unsigned long val = *addr & GENMASK(size - 1, 0);
41047d8c156SYury Norov 
41147d8c156SYury Norov 		return val ? __fls(val) : size;
41247d8c156SYury Norov 	}
41347d8c156SYury Norov 
41447d8c156SYury Norov 	return _find_last_bit(addr, size);
41547d8c156SYury Norov }
41647d8c156SYury Norov #endif
41747d8c156SYury Norov 
41847d8c156SYury Norov /**
4196cc18331SYury Norov  * find_next_and_bit_wrap - find the next set bit in both memory regions
4206cc18331SYury Norov  * @addr1: The first address to base the search on
4216cc18331SYury Norov  * @addr2: The second address to base the search on
4226cc18331SYury Norov  * @size: The bitmap size in bits
4236cc18331SYury Norov  * @offset: The bitnumber to start searching at
4246cc18331SYury Norov  *
4256cc18331SYury Norov  * Returns the bit number for the next set bit, or first set bit up to @offset
4266cc18331SYury Norov  * If no bits are set, returns @size.
4276cc18331SYury Norov  */
428*fda1dd3cSYury Norov static __always_inline
find_next_and_bit_wrap(const unsigned long * addr1,const unsigned long * addr2,unsigned long size,unsigned long offset)4296cc18331SYury Norov unsigned long find_next_and_bit_wrap(const unsigned long *addr1,
4306cc18331SYury Norov 					const unsigned long *addr2,
4316cc18331SYury Norov 					unsigned long size, unsigned long offset)
4326cc18331SYury Norov {
4336cc18331SYury Norov 	unsigned long bit = find_next_and_bit(addr1, addr2, size, offset);
4346cc18331SYury Norov 
43527c82f14SYury Norov 	if (bit < size || offset == 0)
4366cc18331SYury Norov 		return bit;
4376cc18331SYury Norov 
4386cc18331SYury Norov 	bit = find_first_and_bit(addr1, addr2, offset);
4396cc18331SYury Norov 	return bit < offset ? bit : size;
4406cc18331SYury Norov }
4416cc18331SYury Norov 
4426cc18331SYury Norov /**
44392697139SGuanjun  * find_next_bit_wrap - find the next set bit in a memory region
44492697139SGuanjun  * @addr: The address to base the search on
4456cc18331SYury Norov  * @size: The bitmap size in bits
4466cc18331SYury Norov  * @offset: The bitnumber to start searching at
4476cc18331SYury Norov  *
4486cc18331SYury Norov  * Returns the bit number for the next set bit, or first set bit up to @offset
4496cc18331SYury Norov  * If no bits are set, returns @size.
4506cc18331SYury Norov  */
451*fda1dd3cSYury Norov static __always_inline
find_next_bit_wrap(const unsigned long * addr,unsigned long size,unsigned long offset)4526cc18331SYury Norov unsigned long find_next_bit_wrap(const unsigned long *addr,
4536cc18331SYury Norov 					unsigned long size, unsigned long offset)
4546cc18331SYury Norov {
4556cc18331SYury Norov 	unsigned long bit = find_next_bit(addr, size, offset);
4566cc18331SYury Norov 
45727c82f14SYury Norov 	if (bit < size || offset == 0)
4586cc18331SYury Norov 		return bit;
4596cc18331SYury Norov 
4606cc18331SYury Norov 	bit = find_first_bit(addr, offset);
4616cc18331SYury Norov 	return bit < offset ? bit : size;
4626cc18331SYury Norov }
4636cc18331SYury Norov 
4644fe49b3bSYury Norov /*
4654fe49b3bSYury Norov  * Helper for for_each_set_bit_wrap(). Make sure you're doing right thing
4664fe49b3bSYury Norov  * before using it alone.
4674fe49b3bSYury Norov  */
468*fda1dd3cSYury Norov static __always_inline
__for_each_wrap(const unsigned long * bitmap,unsigned long size,unsigned long start,unsigned long n)4694fe49b3bSYury Norov unsigned long __for_each_wrap(const unsigned long *bitmap, unsigned long size,
4704fe49b3bSYury Norov 				 unsigned long start, unsigned long n)
4714fe49b3bSYury Norov {
4724fe49b3bSYury Norov 	unsigned long bit;
4734fe49b3bSYury Norov 
4744fe49b3bSYury Norov 	/* If not wrapped around */
4754fe49b3bSYury Norov 	if (n > start) {
4764fe49b3bSYury Norov 		/* and have a bit, just return it. */
4774fe49b3bSYury Norov 		bit = find_next_bit(bitmap, size, n);
4784fe49b3bSYury Norov 		if (bit < size)
4794fe49b3bSYury Norov 			return bit;
4804fe49b3bSYury Norov 
4814fe49b3bSYury Norov 		/* Otherwise, wrap around and ... */
4824fe49b3bSYury Norov 		n = 0;
4834fe49b3bSYury Norov 	}
4844fe49b3bSYury Norov 
4854fe49b3bSYury Norov 	/* Search the other part. */
4864fe49b3bSYury Norov 	bit = find_next_bit(bitmap, start, n);
4874fe49b3bSYury Norov 	return bit < start ? bit : size;
4884fe49b3bSYury Norov }
4894fe49b3bSYury Norov 
4906cc18331SYury Norov /**
49147d8c156SYury Norov  * find_next_clump8 - find next 8-bit clump with set bits in a memory region
49247d8c156SYury Norov  * @clump: location to store copy of found clump
49347d8c156SYury Norov  * @addr: address to base the search on
49447d8c156SYury Norov  * @size: bitmap size in number of bits
49547d8c156SYury Norov  * @offset: bit offset at which to start searching
49647d8c156SYury Norov  *
49747d8c156SYury Norov  * Returns the bit offset for the next set clump; the found clump value is
49847d8c156SYury Norov  * copied to the location pointed by @clump. If no bits are set, returns @size.
49947d8c156SYury Norov  */
50047d8c156SYury Norov extern unsigned long find_next_clump8(unsigned long *clump,
50147d8c156SYury Norov 				      const unsigned long *addr,
50247d8c156SYury Norov 				      unsigned long size, unsigned long offset);
50347d8c156SYury Norov 
50447d8c156SYury Norov #define find_first_clump8(clump, bits, size) \
50547d8c156SYury Norov 	find_next_clump8((clump), (bits), (size), 0)
50647d8c156SYury Norov 
50747d8c156SYury Norov #if defined(__LITTLE_ENDIAN)
50847d8c156SYury Norov 
509*fda1dd3cSYury Norov static __always_inline
find_next_zero_bit_le(const void * addr,unsigned long size,unsigned long offset)510*fda1dd3cSYury Norov unsigned long find_next_zero_bit_le(const void *addr, unsigned long size, unsigned long offset)
51147d8c156SYury Norov {
51247d8c156SYury Norov 	return find_next_zero_bit(addr, size, offset);
51347d8c156SYury Norov }
51447d8c156SYury Norov 
515*fda1dd3cSYury Norov static __always_inline
find_next_bit_le(const void * addr,unsigned long size,unsigned long offset)516*fda1dd3cSYury Norov unsigned long find_next_bit_le(const void *addr, unsigned long size, unsigned long offset)
51747d8c156SYury Norov {
51847d8c156SYury Norov 	return find_next_bit(addr, size, offset);
51947d8c156SYury Norov }
52047d8c156SYury Norov 
521*fda1dd3cSYury Norov static __always_inline
find_first_zero_bit_le(const void * addr,unsigned long size)522*fda1dd3cSYury Norov unsigned long find_first_zero_bit_le(const void *addr, unsigned long size)
52347d8c156SYury Norov {
52447d8c156SYury Norov 	return find_first_zero_bit(addr, size);
52547d8c156SYury Norov }
52647d8c156SYury Norov 
52747d8c156SYury Norov #elif defined(__BIG_ENDIAN)
52847d8c156SYury Norov 
52947d8c156SYury Norov #ifndef find_next_zero_bit_le
530*fda1dd3cSYury Norov static __always_inline
find_next_zero_bit_le(const void * addr,unsigned long size,unsigned long offset)53147d8c156SYury Norov unsigned long find_next_zero_bit_le(const void *addr, unsigned
53247d8c156SYury Norov 		long size, unsigned long offset)
53347d8c156SYury Norov {
53447d8c156SYury Norov 	if (small_const_nbits(size)) {
53547d8c156SYury Norov 		unsigned long val = *(const unsigned long *)addr;
53647d8c156SYury Norov 
53747d8c156SYury Norov 		if (unlikely(offset >= size))
53847d8c156SYury Norov 			return size;
53947d8c156SYury Norov 
54047d8c156SYury Norov 		val = swab(val) | ~GENMASK(size - 1, offset);
54147d8c156SYury Norov 		return val == ~0UL ? size : ffz(val);
54247d8c156SYury Norov 	}
54347d8c156SYury Norov 
544e79864f3SYury Norov 	return _find_next_zero_bit_le(addr, size, offset);
54547d8c156SYury Norov }
54647d8c156SYury Norov #endif
54747d8c156SYury Norov 
54814a99e13SYury Norov #ifndef find_first_zero_bit_le
549*fda1dd3cSYury Norov static __always_inline
find_first_zero_bit_le(const void * addr,unsigned long size)55014a99e13SYury Norov unsigned long find_first_zero_bit_le(const void *addr, unsigned long size)
55114a99e13SYury Norov {
55214a99e13SYury Norov 	if (small_const_nbits(size)) {
55314a99e13SYury Norov 		unsigned long val = swab(*(const unsigned long *)addr) | ~GENMASK(size - 1, 0);
55414a99e13SYury Norov 
55514a99e13SYury Norov 		return val == ~0UL ? size : ffz(val);
55614a99e13SYury Norov 	}
55714a99e13SYury Norov 
55814a99e13SYury Norov 	return _find_first_zero_bit_le(addr, size);
55914a99e13SYury Norov }
56014a99e13SYury Norov #endif
56114a99e13SYury Norov 
56247d8c156SYury Norov #ifndef find_next_bit_le
563*fda1dd3cSYury Norov static __always_inline
find_next_bit_le(const void * addr,unsigned long size,unsigned long offset)56447d8c156SYury Norov unsigned long find_next_bit_le(const void *addr, unsigned
56547d8c156SYury Norov 		long size, unsigned long offset)
56647d8c156SYury Norov {
56747d8c156SYury Norov 	if (small_const_nbits(size)) {
56847d8c156SYury Norov 		unsigned long val = *(const unsigned long *)addr;
56947d8c156SYury Norov 
57047d8c156SYury Norov 		if (unlikely(offset >= size))
57147d8c156SYury Norov 			return size;
57247d8c156SYury Norov 
57347d8c156SYury Norov 		val = swab(val) & GENMASK(size - 1, offset);
57447d8c156SYury Norov 		return val ? __ffs(val) : size;
57547d8c156SYury Norov 	}
57647d8c156SYury Norov 
577e79864f3SYury Norov 	return _find_next_bit_le(addr, size, offset);
57847d8c156SYury Norov }
57947d8c156SYury Norov #endif
58047d8c156SYury Norov 
58147d8c156SYury Norov #else
58247d8c156SYury Norov #error "Please fix <asm/byteorder.h>"
58347d8c156SYury Norov #endif
58447d8c156SYury Norov 
585bc9d6635SYury Norov #define for_each_set_bit(bit, addr, size) \
586fdae96a3SYury Norov 	for ((bit) = 0; (bit) = find_next_bit((addr), (size), (bit)), (bit) < (size); (bit)++)
587bc9d6635SYury Norov 
58833e67710SYury Norov #define for_each_and_bit(bit, addr1, addr2, size) \
589fdae96a3SYury Norov 	for ((bit) = 0;									\
590fdae96a3SYury Norov 	     (bit) = find_next_and_bit((addr1), (addr2), (size), (bit)), (bit) < (size);\
591fdae96a3SYury Norov 	     (bit)++)
59233e67710SYury Norov 
5935f75ff29SValentin Schneider #define for_each_andnot_bit(bit, addr1, addr2, size) \
5945f75ff29SValentin Schneider 	for ((bit) = 0;									\
5955f75ff29SValentin Schneider 	     (bit) = find_next_andnot_bit((addr1), (addr2), (size), (bit)), (bit) < (size);\
5965f75ff29SValentin Schneider 	     (bit)++)
5975f75ff29SValentin Schneider 
5981470afefSDave Chinner #define for_each_or_bit(bit, addr1, addr2, size) \
5991470afefSDave Chinner 	for ((bit) = 0;									\
6001470afefSDave Chinner 	     (bit) = find_next_or_bit((addr1), (addr2), (size), (bit)), (bit) < (size);\
6011470afefSDave Chinner 	     (bit)++)
6021470afefSDave Chinner 
603bc9d6635SYury Norov /* same as for_each_set_bit() but use bit as value to start with */
604bc9d6635SYury Norov #define for_each_set_bit_from(bit, addr, size) \
605fdae96a3SYury Norov 	for (; (bit) = find_next_bit((addr), (size), (bit)), (bit) < (size); (bit)++)
606bc9d6635SYury Norov 
607bc9d6635SYury Norov #define for_each_clear_bit(bit, addr, size) \
608fdae96a3SYury Norov 	for ((bit) = 0;									\
609fdae96a3SYury Norov 	     (bit) = find_next_zero_bit((addr), (size), (bit)), (bit) < (size);		\
610fdae96a3SYury Norov 	     (bit)++)
611bc9d6635SYury Norov 
612bc9d6635SYury Norov /* same as for_each_clear_bit() but use bit as value to start with */
613bc9d6635SYury Norov #define for_each_clear_bit_from(bit, addr, size) \
614fdae96a3SYury Norov 	for (; (bit) = find_next_zero_bit((addr), (size), (bit)), (bit) < (size); (bit)++)
615bc9d6635SYury Norov 
616bc9d6635SYury Norov /**
617ec288a2cSYury Norov  * for_each_set_bitrange - iterate over all set bit ranges [b; e)
618ec288a2cSYury Norov  * @b: bit offset of start of current bitrange (first set bit)
619ec288a2cSYury Norov  * @e: bit offset of end of current bitrange (first unset bit)
620ec288a2cSYury Norov  * @addr: bitmap address to base the search on
621ec288a2cSYury Norov  * @size: bitmap size in number of bits
622ec288a2cSYury Norov  */
623ec288a2cSYury Norov #define for_each_set_bitrange(b, e, addr, size)			\
624fdae96a3SYury Norov 	for ((b) = 0;						\
625fdae96a3SYury Norov 	     (b) = find_next_bit((addr), (size), b),		\
626fdae96a3SYury Norov 	     (e) = find_next_zero_bit((addr), (size), (b) + 1),	\
627ec288a2cSYury Norov 	     (b) < (size);					\
628fdae96a3SYury Norov 	     (b) = (e) + 1)
629ec288a2cSYury Norov 
630ec288a2cSYury Norov /**
631ec288a2cSYury Norov  * for_each_set_bitrange_from - iterate over all set bit ranges [b; e)
632ec288a2cSYury Norov  * @b: bit offset of start of current bitrange (first set bit); must be initialized
633ec288a2cSYury Norov  * @e: bit offset of end of current bitrange (first unset bit)
634ec288a2cSYury Norov  * @addr: bitmap address to base the search on
635ec288a2cSYury Norov  * @size: bitmap size in number of bits
636ec288a2cSYury Norov  */
637ec288a2cSYury Norov #define for_each_set_bitrange_from(b, e, addr, size)		\
638fdae96a3SYury Norov 	for (;							\
639fdae96a3SYury Norov 	     (b) = find_next_bit((addr), (size), (b)),		\
640fdae96a3SYury Norov 	     (e) = find_next_zero_bit((addr), (size), (b) + 1),	\
641ec288a2cSYury Norov 	     (b) < (size);					\
642fdae96a3SYury Norov 	     (b) = (e) + 1)
643ec288a2cSYury Norov 
644ec288a2cSYury Norov /**
645ec288a2cSYury Norov  * for_each_clear_bitrange - iterate over all unset bit ranges [b; e)
646ec288a2cSYury Norov  * @b: bit offset of start of current bitrange (first unset bit)
647ec288a2cSYury Norov  * @e: bit offset of end of current bitrange (first set bit)
648ec288a2cSYury Norov  * @addr: bitmap address to base the search on
649ec288a2cSYury Norov  * @size: bitmap size in number of bits
650ec288a2cSYury Norov  */
651ec288a2cSYury Norov #define for_each_clear_bitrange(b, e, addr, size)		\
652fdae96a3SYury Norov 	for ((b) = 0;						\
653fdae96a3SYury Norov 	     (b) = find_next_zero_bit((addr), (size), (b)),	\
654fdae96a3SYury Norov 	     (e) = find_next_bit((addr), (size), (b) + 1),	\
655ec288a2cSYury Norov 	     (b) < (size);					\
656fdae96a3SYury Norov 	     (b) = (e) + 1)
657ec288a2cSYury Norov 
658ec288a2cSYury Norov /**
659ec288a2cSYury Norov  * for_each_clear_bitrange_from - iterate over all unset bit ranges [b; e)
660ec288a2cSYury Norov  * @b: bit offset of start of current bitrange (first set bit); must be initialized
661ec288a2cSYury Norov  * @e: bit offset of end of current bitrange (first unset bit)
662ec288a2cSYury Norov  * @addr: bitmap address to base the search on
663ec288a2cSYury Norov  * @size: bitmap size in number of bits
664ec288a2cSYury Norov  */
665ec288a2cSYury Norov #define for_each_clear_bitrange_from(b, e, addr, size)		\
666fdae96a3SYury Norov 	for (;							\
667fdae96a3SYury Norov 	     (b) = find_next_zero_bit((addr), (size), (b)),	\
668fdae96a3SYury Norov 	     (e) = find_next_bit((addr), (size), (b) + 1),	\
669ec288a2cSYury Norov 	     (b) < (size);					\
670fdae96a3SYury Norov 	     (b) = (e) + 1)
671ec288a2cSYury Norov 
672ec288a2cSYury Norov /**
6734fe49b3bSYury Norov  * for_each_set_bit_wrap - iterate over all set bits starting from @start, and
6744fe49b3bSYury Norov  * wrapping around the end of bitmap.
6754fe49b3bSYury Norov  * @bit: offset for current iteration
6764fe49b3bSYury Norov  * @addr: bitmap address to base the search on
6774fe49b3bSYury Norov  * @size: bitmap size in number of bits
6784fe49b3bSYury Norov  * @start: Starting bit for bitmap traversing, wrapping around the bitmap end
6794fe49b3bSYury Norov  */
6804fe49b3bSYury Norov #define for_each_set_bit_wrap(bit, addr, size, start) \
6814fe49b3bSYury Norov 	for ((bit) = find_next_bit_wrap((addr), (size), (start));		\
6824fe49b3bSYury Norov 	     (bit) < (size);							\
6834fe49b3bSYury Norov 	     (bit) = __for_each_wrap((addr), (size), (start), (bit) + 1))
6844fe49b3bSYury Norov 
6854fe49b3bSYury Norov /**
686bc9d6635SYury Norov  * for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
687bc9d6635SYury Norov  * @start: bit offset to start search and to store the current iteration offset
688bc9d6635SYury Norov  * @clump: location to store copy of current 8-bit clump
689bc9d6635SYury Norov  * @bits: bitmap address to base the search on
690bc9d6635SYury Norov  * @size: bitmap size in number of bits
691bc9d6635SYury Norov  */
692bc9d6635SYury Norov #define for_each_set_clump8(start, clump, bits, size) \
693bc9d6635SYury Norov 	for ((start) = find_first_clump8(&(clump), (bits), (size)); \
694bc9d6635SYury Norov 	     (start) < (size); \
695bc9d6635SYury Norov 	     (start) = find_next_clump8(&(clump), (bits), (size), (start) + 8))
696bc9d6635SYury Norov 
69747d8c156SYury Norov #endif /*__LINUX_FIND_H_ */
698