blob: 6481fd11012a9e471ae305d1627a72f7ffea8414 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001/* SPDX-License-Identifier: GPL-2.0 */
Arnaldo Carvalho de Melo23e1a352014-12-15 19:50:12 -03002#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
3#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
4
Yury Norovea81c1e2021-05-06 18:03:07 -07005extern unsigned long _find_next_bit(const unsigned long *addr1,
6 const unsigned long *addr2, unsigned long nbits,
7 unsigned long start, unsigned long invert, unsigned long le);
Yury Noroveaae7842021-05-06 18:03:18 -07008extern unsigned long _find_first_bit(const unsigned long *addr, unsigned long size);
9extern unsigned long _find_first_zero_bit(const unsigned long *addr, unsigned long size);
10extern unsigned long _find_last_bit(const unsigned long *addr, unsigned long size);
Yury Norovea81c1e2021-05-06 18:03:07 -070011
Arnaldo Carvalho de Melo23e1a352014-12-15 19:50:12 -030012#ifndef find_next_bit
13/**
14 * find_next_bit - find the next set bit in a memory region
15 * @addr: The address to base the search on
16 * @offset: The bitnumber to start searching at
17 * @size: The bitmap size in bits
18 *
19 * Returns the bit number for the next set bit
20 * If no bits are set, returns @size.
21 */
Yury Norovea81c1e2021-05-06 18:03:07 -070022static inline
23unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
24 unsigned long offset)
25{
Yury Noroveaae7842021-05-06 18:03:18 -070026 if (small_const_nbits(size)) {
27 unsigned long val;
28
29 if (unlikely(offset >= size))
30 return size;
31
32 val = *addr & GENMASK(size - 1, offset);
33 return val ? __ffs(val) : size;
34 }
35
Yury Norovea81c1e2021-05-06 18:03:07 -070036 return _find_next_bit(addr, NULL, size, offset, 0UL, 0);
37}
Arnaldo Carvalho de Melo23e1a352014-12-15 19:50:12 -030038#endif
39
Clement Courbet0ade34c2018-02-06 15:38:34 -080040#ifndef find_next_and_bit
41/**
42 * find_next_and_bit - find the next set bit in both memory regions
43 * @addr1: The first address to base the search on
44 * @addr2: The second address to base the search on
45 * @offset: The bitnumber to start searching at
46 * @size: The bitmap size in bits
47 *
48 * Returns the bit number for the next set bit
49 * If no bits are set, returns @size.
50 */
Yury Norovea81c1e2021-05-06 18:03:07 -070051static inline
52unsigned long find_next_and_bit(const unsigned long *addr1,
Clement Courbet0ade34c2018-02-06 15:38:34 -080053 const unsigned long *addr2, unsigned long size,
Yury Norovea81c1e2021-05-06 18:03:07 -070054 unsigned long offset)
55{
Yury Noroveaae7842021-05-06 18:03:18 -070056 if (small_const_nbits(size)) {
57 unsigned long val;
58
59 if (unlikely(offset >= size))
60 return size;
61
62 val = *addr1 & *addr2 & GENMASK(size - 1, offset);
63 return val ? __ffs(val) : size;
64 }
65
Yury Norovea81c1e2021-05-06 18:03:07 -070066 return _find_next_bit(addr1, addr2, size, offset, 0UL, 0);
67}
Clement Courbet0ade34c2018-02-06 15:38:34 -080068#endif
69
Jiri Olsa02bc11d2016-10-10 09:26:33 +020070#ifndef find_next_zero_bit
Jiri Olsa02bc11d2016-10-10 09:26:33 +020071/**
72 * find_next_zero_bit - find the next cleared bit in a memory region
73 * @addr: The address to base the search on
74 * @offset: The bitnumber to start searching at
75 * @size: The bitmap size in bits
76 *
77 * Returns the bit number of the next zero bit
78 * If no bits are zero, returns @size.
79 */
Yury Norovea81c1e2021-05-06 18:03:07 -070080static inline
Jiri Olsa02bc11d2016-10-10 09:26:33 +020081unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size,
Yury Norovea81c1e2021-05-06 18:03:07 -070082 unsigned long offset)
83{
Yury Noroveaae7842021-05-06 18:03:18 -070084 if (small_const_nbits(size)) {
85 unsigned long val;
86
87 if (unlikely(offset >= size))
88 return size;
89
90 val = *addr | ~GENMASK(size - 1, offset);
91 return val == ~0UL ? size : ffz(val);
92 }
93
Yury Norovea81c1e2021-05-06 18:03:07 -070094 return _find_next_bit(addr, NULL, size, offset, ~0UL, 0);
95}
Jiri Olsa02bc11d2016-10-10 09:26:33 +020096#endif
97
Arnaldo Carvalho de Melo23e1a352014-12-15 19:50:12 -030098#ifndef find_first_bit
99
100/**
101 * find_first_bit - find the first set bit in a memory region
102 * @addr: The address to start the search at
103 * @size: The maximum number of bits to search
104 *
105 * Returns the bit number of the first set bit.
106 * If no bits are set, returns @size.
107 */
Yury Noroveaae7842021-05-06 18:03:18 -0700108static inline
109unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
110{
111 if (small_const_nbits(size)) {
112 unsigned long val = *addr & GENMASK(size - 1, 0);
113
114 return val ? __ffs(val) : size;
115 }
116
117 return _find_first_bit(addr, size);
118}
Arnaldo Carvalho de Melo23e1a352014-12-15 19:50:12 -0300119
120#endif /* find_first_bit */
121
Jiri Olsa02bc11d2016-10-10 09:26:33 +0200122#ifndef find_first_zero_bit
123
124/**
125 * find_first_zero_bit - find the first cleared bit in a memory region
126 * @addr: The address to start the search at
127 * @size: The maximum number of bits to search
128 *
129 * Returns the bit number of the first cleared bit.
130 * If no bits are zero, returns @size.
131 */
Yury Noroveaae7842021-05-06 18:03:18 -0700132static inline
133unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size)
134{
135 if (small_const_nbits(size)) {
136 unsigned long val = *addr | ~GENMASK(size - 1, 0);
137
138 return val == ~0UL ? size : ffz(val);
139 }
140
141 return _find_first_zero_bit(addr, size);
142}
Jiri Olsa02bc11d2016-10-10 09:26:33 +0200143#endif
144
Arnaldo Carvalho de Melo23e1a352014-12-15 19:50:12 -0300145#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */