2 * Copyright (c) 2010 Isilon Systems, Inc.
3 * Copyright (c) 2010 iX Systems, Inc.
4 * Copyright (c) 2010 Panasas, Inc.
5 * Copyright (c) 2013-2017 Mellanox Technologies, Ltd.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice unmodified, this list of conditions, and the following
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef _LINUX_BITOPS_H_
32 #define _LINUX_BITOPS_H_
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/systm.h>
37 #include <sys/errno.h>
38 #include <sys/libkern.h>
40 #define BIT(nr) (1UL << (nr))
41 #define BIT_ULL(nr) (1ULL << (nr))
43 #define BITS_PER_LONG 64
45 #define BITS_PER_LONG 32
48 #define BITS_PER_LONG_LONG 64
50 #define BITMAP_FIRST_WORD_MASK(start) (~0UL << ((start) % BITS_PER_LONG))
51 #define BITMAP_LAST_WORD_MASK(n) (~0UL >> (BITS_PER_LONG - (n)))
52 #define BITS_TO_LONGS(n) howmany((n), BITS_PER_LONG)
53 #define BIT_MASK(nr) (1UL << ((nr) & (BITS_PER_LONG - 1)))
54 #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
55 #define GENMASK(h, l) (((~0UL) >> (BITS_PER_LONG - (h) - 1)) & ((~0UL) << (l)))
56 #define GENMASK_ULL(h, l) (((~0ULL) >> (BITS_PER_LONG_LONG - (h) - 1)) & ((~0ULL) << (l)))
57 #define BITS_PER_BYTE 8
59 #define hweight8(x) bitcount((uint8_t)(x))
60 #define hweight16(x) bitcount16(x)
61 #define hweight32(x) bitcount32(x)
62 #define hweight64(x) bitcount64(x)
63 #define hweight_long(x) bitcountl(x)
68 return (ffs(mask) - 1);
74 return (fls(mask) - 1);
80 return (ffsl(mask) - 1);
86 return (flsl(mask) - 1);
95 static inline uint32_t
96 ror32(uint32_t word, unsigned int shift)
98 return ((word >> shift) | (word << (32 - shift)));
101 #define ffz(mask) __ffs(~(mask))
103 static inline int get_count_order(unsigned int count)
107 order = fls(count) - 1;
108 if (count & (count - 1))
113 static inline unsigned long
114 find_first_bit(const unsigned long *addr, unsigned long size)
119 for (bit = 0; size >= BITS_PER_LONG;
120 size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) {
123 return (bit + __ffsl(*addr));
126 mask = (*addr) & BITMAP_LAST_WORD_MASK(size);
135 static inline unsigned long
136 find_first_zero_bit(const unsigned long *addr, unsigned long size)
141 for (bit = 0; size >= BITS_PER_LONG;
142 size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) {
145 return (bit + __ffsl(~(*addr)));
148 mask = ~(*addr) & BITMAP_LAST_WORD_MASK(size);
157 static inline unsigned long
158 find_last_bit(const unsigned long *addr, unsigned long size)
165 pos = size / BITS_PER_LONG;
166 offs = size % BITS_PER_LONG;
167 bit = BITS_PER_LONG * pos;
170 mask = (*addr) & BITMAP_LAST_WORD_MASK(offs);
172 return (bit + __flsl(mask));
176 bit -= BITS_PER_LONG;
178 return (bit + __flsl(*addr));
183 static inline unsigned long
184 find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
193 pos = offset / BITS_PER_LONG;
194 offs = offset % BITS_PER_LONG;
195 bit = BITS_PER_LONG * pos;
198 mask = (*addr) & ~BITMAP_LAST_WORD_MASK(offs);
200 return (bit + __ffsl(mask));
201 if (size - bit <= BITS_PER_LONG)
203 bit += BITS_PER_LONG;
206 for (size -= bit; size >= BITS_PER_LONG;
207 size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) {
210 return (bit + __ffsl(*addr));
213 mask = (*addr) & BITMAP_LAST_WORD_MASK(size);
222 static inline unsigned long
223 find_next_zero_bit(const unsigned long *addr, unsigned long size,
224 unsigned long offset)
233 pos = offset / BITS_PER_LONG;
234 offs = offset % BITS_PER_LONG;
235 bit = BITS_PER_LONG * pos;
238 mask = ~(*addr) & ~BITMAP_LAST_WORD_MASK(offs);
240 return (bit + __ffsl(mask));
241 if (size - bit <= BITS_PER_LONG)
243 bit += BITS_PER_LONG;
246 for (size -= bit; size >= BITS_PER_LONG;
247 size -= BITS_PER_LONG, bit += BITS_PER_LONG, addr++) {
250 return (bit + __ffsl(~(*addr)));
253 mask = ~(*addr) & BITMAP_LAST_WORD_MASK(size);
262 #define __set_bit(i, a) \
263 atomic_set_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i))
265 #define set_bit(i, a) \
266 atomic_set_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i))
268 #define __clear_bit(i, a) \
269 atomic_clear_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i))
271 #define clear_bit(i, a) \
272 atomic_clear_long(&((volatile unsigned long *)(a))[BIT_WORD(i)], BIT_MASK(i))
274 #define test_bit(i, a) \
275 !!(READ_ONCE(((volatile unsigned long *)(a))[BIT_WORD(i)]) & BIT_MASK(i))
278 test_and_clear_bit(long bit, volatile unsigned long *var)
282 var += BIT_WORD(bit);
283 bit %= BITS_PER_LONG;
287 while (!atomic_fcmpset_long(var, &val, val & ~bit))
289 return !!(val & bit);
293 __test_and_clear_bit(long bit, volatile unsigned long *var)
297 var += BIT_WORD(bit);
298 bit %= BITS_PER_LONG;
304 return !!(val & bit);
308 test_and_set_bit(long bit, volatile unsigned long *var)
312 var += BIT_WORD(bit);
313 bit %= BITS_PER_LONG;
317 while (!atomic_fcmpset_long(var, &val, val | bit))
319 return !!(val & bit);
323 __test_and_set_bit(long bit, volatile unsigned long *var)
327 var += BIT_WORD(bit);
328 bit %= BITS_PER_LONG;
334 return !!(val & bit);
344 linux_reg_op(unsigned long *bitmap, int pos, int order, int reg_op)
355 nbits_reg = 1 << order;
356 index = pos / BITS_PER_LONG;
357 offset = pos - (index * BITS_PER_LONG);
358 nlongs_reg = BITS_TO_LONGS(nbits_reg);
359 nbitsinlong = min(nbits_reg, BITS_PER_LONG);
361 mask = (1UL << (nbitsinlong - 1));
367 for (i = 0; i < nlongs_reg; i++) {
368 if (bitmap[index + i] & mask)
375 for (i = 0; i < nlongs_reg; i++)
376 bitmap[index + i] |= mask;
380 for (i = 0; i < nlongs_reg; i++)
381 bitmap[index + i] &= ~mask;
388 #define for_each_set_bit(bit, addr, size) \
389 for ((bit) = find_first_bit((addr), (size)); \
391 (bit) = find_next_bit((addr), (size), (bit) + 1))
393 #define for_each_clear_bit(bit, addr, size) \
394 for ((bit) = find_first_zero_bit((addr), (size)); \
396 (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
398 static inline uint64_t
399 sign_extend64(uint64_t value, int index)
401 uint8_t shift = 63 - index;
403 return ((int64_t)(value << shift) >> shift);
406 #endif /* _LINUX_BITOPS_H_ */