162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/* bit search implementation
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
562306a36Sopenharmony_ci * Written by David Howells (dhowells@redhat.com)
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Copyright (C) 2008 IBM Corporation
862306a36Sopenharmony_ci * 'find_last_bit' is written by Rusty Russell <rusty@rustcorp.com.au>
962306a36Sopenharmony_ci * (Inspired by David Howell's find_next_bit implementation)
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci * Rewritten by Yury Norov <yury.norov@gmail.com> to decrease
1262306a36Sopenharmony_ci * size and improve performance, 2015.
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/bitops.h>
1662306a36Sopenharmony_ci#include <linux/bitmap.h>
1762306a36Sopenharmony_ci#include <linux/export.h>
1862306a36Sopenharmony_ci#include <linux/math.h>
1962306a36Sopenharmony_ci#include <linux/minmax.h>
2062306a36Sopenharmony_ci#include <linux/swab.h>
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/*
2362306a36Sopenharmony_ci * Common helper for find_bit() function family
2462306a36Sopenharmony_ci * @FETCH: The expression that fetches and pre-processes each word of bitmap(s)
2562306a36Sopenharmony_ci * @MUNGE: The expression that post-processes a word containing found bit (may be empty)
2662306a36Sopenharmony_ci * @size: The bitmap size in bits
2762306a36Sopenharmony_ci */
2862306a36Sopenharmony_ci#define FIND_FIRST_BIT(FETCH, MUNGE, size)					\
2962306a36Sopenharmony_ci({										\
3062306a36Sopenharmony_ci	unsigned long idx, val, sz = (size);					\
3162306a36Sopenharmony_ci										\
3262306a36Sopenharmony_ci	for (idx = 0; idx * BITS_PER_LONG < sz; idx++) {			\
3362306a36Sopenharmony_ci		val = (FETCH);							\
3462306a36Sopenharmony_ci		if (val) {							\
3562306a36Sopenharmony_ci			sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(val)), sz);	\
3662306a36Sopenharmony_ci			break;							\
3762306a36Sopenharmony_ci		}								\
3862306a36Sopenharmony_ci	}									\
3962306a36Sopenharmony_ci										\
4062306a36Sopenharmony_ci	sz;									\
4162306a36Sopenharmony_ci})
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci/*
4462306a36Sopenharmony_ci * Common helper for find_next_bit() function family
4562306a36Sopenharmony_ci * @FETCH: The expression that fetches and pre-processes each word of bitmap(s)
4662306a36Sopenharmony_ci * @MUNGE: The expression that post-processes a word containing found bit (may be empty)
4762306a36Sopenharmony_ci * @size: The bitmap size in bits
4862306a36Sopenharmony_ci * @start: The bitnumber to start searching at
4962306a36Sopenharmony_ci */
5062306a36Sopenharmony_ci#define FIND_NEXT_BIT(FETCH, MUNGE, size, start)				\
5162306a36Sopenharmony_ci({										\
5262306a36Sopenharmony_ci	unsigned long mask, idx, tmp, sz = (size), __start = (start);		\
5362306a36Sopenharmony_ci										\
5462306a36Sopenharmony_ci	if (unlikely(__start >= sz))						\
5562306a36Sopenharmony_ci		goto out;							\
5662306a36Sopenharmony_ci										\
5762306a36Sopenharmony_ci	mask = MUNGE(BITMAP_FIRST_WORD_MASK(__start));				\
5862306a36Sopenharmony_ci	idx = __start / BITS_PER_LONG;						\
5962306a36Sopenharmony_ci										\
6062306a36Sopenharmony_ci	for (tmp = (FETCH) & mask; !tmp; tmp = (FETCH)) {			\
6162306a36Sopenharmony_ci		if ((idx + 1) * BITS_PER_LONG >= sz)				\
6262306a36Sopenharmony_ci			goto out;						\
6362306a36Sopenharmony_ci		idx++;								\
6462306a36Sopenharmony_ci	}									\
6562306a36Sopenharmony_ci										\
6662306a36Sopenharmony_ci	sz = min(idx * BITS_PER_LONG + __ffs(MUNGE(tmp)), sz);			\
6762306a36Sopenharmony_ciout:										\
6862306a36Sopenharmony_ci	sz;									\
6962306a36Sopenharmony_ci})
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci#define FIND_NTH_BIT(FETCH, size, num)						\
7262306a36Sopenharmony_ci({										\
7362306a36Sopenharmony_ci	unsigned long sz = (size), nr = (num), idx, w, tmp;			\
7462306a36Sopenharmony_ci										\
7562306a36Sopenharmony_ci	for (idx = 0; (idx + 1) * BITS_PER_LONG <= sz; idx++) {			\
7662306a36Sopenharmony_ci		if (idx * BITS_PER_LONG + nr >= sz)				\
7762306a36Sopenharmony_ci			goto out;						\
7862306a36Sopenharmony_ci										\
7962306a36Sopenharmony_ci		tmp = (FETCH);							\
8062306a36Sopenharmony_ci		w = hweight_long(tmp);						\
8162306a36Sopenharmony_ci		if (w > nr)							\
8262306a36Sopenharmony_ci			goto found;						\
8362306a36Sopenharmony_ci										\
8462306a36Sopenharmony_ci		nr -= w;							\
8562306a36Sopenharmony_ci	}									\
8662306a36Sopenharmony_ci										\
8762306a36Sopenharmony_ci	if (sz % BITS_PER_LONG)							\
8862306a36Sopenharmony_ci		tmp = (FETCH) & BITMAP_LAST_WORD_MASK(sz);			\
8962306a36Sopenharmony_cifound:										\
9062306a36Sopenharmony_ci	sz = min(idx * BITS_PER_LONG + fns(tmp, nr), sz);			\
9162306a36Sopenharmony_ciout:										\
9262306a36Sopenharmony_ci	sz;									\
9362306a36Sopenharmony_ci})
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci#ifndef find_first_bit
9662306a36Sopenharmony_ci/*
9762306a36Sopenharmony_ci * Find the first set bit in a memory region.
9862306a36Sopenharmony_ci */
9962306a36Sopenharmony_ciunsigned long _find_first_bit(const unsigned long *addr, unsigned long size)
10062306a36Sopenharmony_ci{
10162306a36Sopenharmony_ci	return FIND_FIRST_BIT(addr[idx], /* nop */, size);
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_ciEXPORT_SYMBOL(_find_first_bit);
10462306a36Sopenharmony_ci#endif
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci#ifndef find_first_and_bit
10762306a36Sopenharmony_ci/*
10862306a36Sopenharmony_ci * Find the first set bit in two memory regions.
10962306a36Sopenharmony_ci */
11062306a36Sopenharmony_ciunsigned long _find_first_and_bit(const unsigned long *addr1,
11162306a36Sopenharmony_ci				  const unsigned long *addr2,
11262306a36Sopenharmony_ci				  unsigned long size)
11362306a36Sopenharmony_ci{
11462306a36Sopenharmony_ci	return FIND_FIRST_BIT(addr1[idx] & addr2[idx], /* nop */, size);
11562306a36Sopenharmony_ci}
11662306a36Sopenharmony_ciEXPORT_SYMBOL(_find_first_and_bit);
11762306a36Sopenharmony_ci#endif
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#ifndef find_first_zero_bit
12062306a36Sopenharmony_ci/*
12162306a36Sopenharmony_ci * Find the first cleared bit in a memory region.
12262306a36Sopenharmony_ci */
12362306a36Sopenharmony_ciunsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size)
12462306a36Sopenharmony_ci{
12562306a36Sopenharmony_ci	return FIND_FIRST_BIT(~addr[idx], /* nop */, size);
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ciEXPORT_SYMBOL(_find_first_zero_bit);
12862306a36Sopenharmony_ci#endif
12962306a36Sopenharmony_ci
13062306a36Sopenharmony_ci#ifndef find_next_bit
13162306a36Sopenharmony_ciunsigned long _find_next_bit(const unsigned long *addr, unsigned long nbits, unsigned long start)
13262306a36Sopenharmony_ci{
13362306a36Sopenharmony_ci	return FIND_NEXT_BIT(addr[idx], /* nop */, nbits, start);
13462306a36Sopenharmony_ci}
13562306a36Sopenharmony_ciEXPORT_SYMBOL(_find_next_bit);
13662306a36Sopenharmony_ci#endif
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ciunsigned long __find_nth_bit(const unsigned long *addr, unsigned long size, unsigned long n)
13962306a36Sopenharmony_ci{
14062306a36Sopenharmony_ci	return FIND_NTH_BIT(addr[idx], size, n);
14162306a36Sopenharmony_ci}
14262306a36Sopenharmony_ciEXPORT_SYMBOL(__find_nth_bit);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ciunsigned long __find_nth_and_bit(const unsigned long *addr1, const unsigned long *addr2,
14562306a36Sopenharmony_ci				 unsigned long size, unsigned long n)
14662306a36Sopenharmony_ci{
14762306a36Sopenharmony_ci	return FIND_NTH_BIT(addr1[idx] & addr2[idx], size, n);
14862306a36Sopenharmony_ci}
14962306a36Sopenharmony_ciEXPORT_SYMBOL(__find_nth_and_bit);
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ciunsigned long __find_nth_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
15262306a36Sopenharmony_ci				 unsigned long size, unsigned long n)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci	return FIND_NTH_BIT(addr1[idx] & ~addr2[idx], size, n);
15562306a36Sopenharmony_ci}
15662306a36Sopenharmony_ciEXPORT_SYMBOL(__find_nth_andnot_bit);
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ciunsigned long __find_nth_and_andnot_bit(const unsigned long *addr1,
15962306a36Sopenharmony_ci					const unsigned long *addr2,
16062306a36Sopenharmony_ci					const unsigned long *addr3,
16162306a36Sopenharmony_ci					unsigned long size, unsigned long n)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	return FIND_NTH_BIT(addr1[idx] & addr2[idx] & ~addr3[idx], size, n);
16462306a36Sopenharmony_ci}
16562306a36Sopenharmony_ciEXPORT_SYMBOL(__find_nth_and_andnot_bit);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci#ifndef find_next_and_bit
16862306a36Sopenharmony_ciunsigned long _find_next_and_bit(const unsigned long *addr1, const unsigned long *addr2,
16962306a36Sopenharmony_ci					unsigned long nbits, unsigned long start)
17062306a36Sopenharmony_ci{
17162306a36Sopenharmony_ci	return FIND_NEXT_BIT(addr1[idx] & addr2[idx], /* nop */, nbits, start);
17262306a36Sopenharmony_ci}
17362306a36Sopenharmony_ciEXPORT_SYMBOL(_find_next_and_bit);
17462306a36Sopenharmony_ci#endif
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci#ifndef find_next_andnot_bit
17762306a36Sopenharmony_ciunsigned long _find_next_andnot_bit(const unsigned long *addr1, const unsigned long *addr2,
17862306a36Sopenharmony_ci					unsigned long nbits, unsigned long start)
17962306a36Sopenharmony_ci{
18062306a36Sopenharmony_ci	return FIND_NEXT_BIT(addr1[idx] & ~addr2[idx], /* nop */, nbits, start);
18162306a36Sopenharmony_ci}
18262306a36Sopenharmony_ciEXPORT_SYMBOL(_find_next_andnot_bit);
18362306a36Sopenharmony_ci#endif
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci#ifndef find_next_or_bit
18662306a36Sopenharmony_ciunsigned long _find_next_or_bit(const unsigned long *addr1, const unsigned long *addr2,
18762306a36Sopenharmony_ci					unsigned long nbits, unsigned long start)
18862306a36Sopenharmony_ci{
18962306a36Sopenharmony_ci	return FIND_NEXT_BIT(addr1[idx] | addr2[idx], /* nop */, nbits, start);
19062306a36Sopenharmony_ci}
19162306a36Sopenharmony_ciEXPORT_SYMBOL(_find_next_or_bit);
19262306a36Sopenharmony_ci#endif
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci#ifndef find_next_zero_bit
19562306a36Sopenharmony_ciunsigned long _find_next_zero_bit(const unsigned long *addr, unsigned long nbits,
19662306a36Sopenharmony_ci					 unsigned long start)
19762306a36Sopenharmony_ci{
19862306a36Sopenharmony_ci	return FIND_NEXT_BIT(~addr[idx], /* nop */, nbits, start);
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ciEXPORT_SYMBOL(_find_next_zero_bit);
20162306a36Sopenharmony_ci#endif
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci#ifndef find_last_bit
20462306a36Sopenharmony_ciunsigned long _find_last_bit(const unsigned long *addr, unsigned long size)
20562306a36Sopenharmony_ci{
20662306a36Sopenharmony_ci	if (size) {
20762306a36Sopenharmony_ci		unsigned long val = BITMAP_LAST_WORD_MASK(size);
20862306a36Sopenharmony_ci		unsigned long idx = (size-1) / BITS_PER_LONG;
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci		do {
21162306a36Sopenharmony_ci			val &= addr[idx];
21262306a36Sopenharmony_ci			if (val)
21362306a36Sopenharmony_ci				return idx * BITS_PER_LONG + __fls(val);
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci			val = ~0ul;
21662306a36Sopenharmony_ci		} while (idx--);
21762306a36Sopenharmony_ci	}
21862306a36Sopenharmony_ci	return size;
21962306a36Sopenharmony_ci}
22062306a36Sopenharmony_ciEXPORT_SYMBOL(_find_last_bit);
22162306a36Sopenharmony_ci#endif
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ciunsigned long find_next_clump8(unsigned long *clump, const unsigned long *addr,
22462306a36Sopenharmony_ci			       unsigned long size, unsigned long offset)
22562306a36Sopenharmony_ci{
22662306a36Sopenharmony_ci	offset = find_next_bit(addr, size, offset);
22762306a36Sopenharmony_ci	if (offset == size)
22862306a36Sopenharmony_ci		return size;
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	offset = round_down(offset, 8);
23162306a36Sopenharmony_ci	*clump = bitmap_get_value8(addr, offset);
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	return offset;
23462306a36Sopenharmony_ci}
23562306a36Sopenharmony_ciEXPORT_SYMBOL(find_next_clump8);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci#ifdef __BIG_ENDIAN
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci#ifndef find_first_zero_bit_le
24062306a36Sopenharmony_ci/*
24162306a36Sopenharmony_ci * Find the first cleared bit in an LE memory region.
24262306a36Sopenharmony_ci */
24362306a36Sopenharmony_ciunsigned long _find_first_zero_bit_le(const unsigned long *addr, unsigned long size)
24462306a36Sopenharmony_ci{
24562306a36Sopenharmony_ci	return FIND_FIRST_BIT(~addr[idx], swab, size);
24662306a36Sopenharmony_ci}
24762306a36Sopenharmony_ciEXPORT_SYMBOL(_find_first_zero_bit_le);
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci#endif
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci#ifndef find_next_zero_bit_le
25262306a36Sopenharmony_ciunsigned long _find_next_zero_bit_le(const unsigned long *addr,
25362306a36Sopenharmony_ci					unsigned long size, unsigned long offset)
25462306a36Sopenharmony_ci{
25562306a36Sopenharmony_ci	return FIND_NEXT_BIT(~addr[idx], swab, size, offset);
25662306a36Sopenharmony_ci}
25762306a36Sopenharmony_ciEXPORT_SYMBOL(_find_next_zero_bit_le);
25862306a36Sopenharmony_ci#endif
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci#ifndef find_next_bit_le
26162306a36Sopenharmony_ciunsigned long _find_next_bit_le(const unsigned long *addr,
26262306a36Sopenharmony_ci				unsigned long size, unsigned long offset)
26362306a36Sopenharmony_ci{
26462306a36Sopenharmony_ci	return FIND_NEXT_BIT(addr[idx], swab, size, offset);
26562306a36Sopenharmony_ci}
26662306a36Sopenharmony_ciEXPORT_SYMBOL(_find_next_bit_le);
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_ci#endif
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci#endif /* __BIG_ENDIAN */
271