1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
239672784SArnaldo Carvalho de Melo #ifndef _TOOLS_LINUX_BITOPS_H_
339672784SArnaldo Carvalho de Melo #define _TOOLS_LINUX_BITOPS_H_
439672784SArnaldo Carvalho de Melo
525cd480eSArnaldo Carvalho de Melo #include <asm/types.h>
66e98bc34SArnaldo Carvalho de Melo #include <limits.h>
739672784SArnaldo Carvalho de Melo #ifndef __WORDSIZE
839672784SArnaldo Carvalho de Melo #define __WORDSIZE (__SIZEOF_LONG__ * 8)
939672784SArnaldo Carvalho de Melo #endif
1039672784SArnaldo Carvalho de Melo
117b39cafbSIngo Molnar #ifndef BITS_PER_LONG
1239672784SArnaldo Carvalho de Melo # define BITS_PER_LONG __WORDSIZE
137b39cafbSIngo Molnar #endif
14ba4aa02bSArnaldo Carvalho de Melo #include <linux/bits.h>
15ba4aa02bSArnaldo Carvalho de Melo #include <linux/compiler.h>
1639672784SArnaldo Carvalho de Melo
170bddc1bdSYury Norov #define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
180bddc1bdSYury Norov #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
190bddc1bdSYury Norov #define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(u64))
200bddc1bdSYury Norov #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
210bddc1bdSYury Norov #define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
2239672784SArnaldo Carvalho de Melo
2325cd480eSArnaldo Carvalho de Melo #define BYTES_TO_BITS(nb) ((nb) * BITS_PER_BYTE)
2425cd480eSArnaldo Carvalho de Melo
2525cd480eSArnaldo Carvalho de Melo extern unsigned int __sw_hweight8(unsigned int w);
2625cd480eSArnaldo Carvalho de Melo extern unsigned int __sw_hweight16(unsigned int w);
2725cd480eSArnaldo Carvalho de Melo extern unsigned int __sw_hweight32(unsigned int w);
2839672784SArnaldo Carvalho de Melo extern unsigned long __sw_hweight64(__u64 w);
29e69eb9c4SAlexander Lobakin
30e69eb9c4SAlexander Lobakin /*
31e69eb9c4SAlexander Lobakin * Defined here because those may be needed by architecture-specific static
32e69eb9c4SAlexander Lobakin * inlines.
33e69eb9c4SAlexander Lobakin */
34e69eb9c4SAlexander Lobakin
35e69eb9c4SAlexander Lobakin #define bitop(op, nr, addr) \
36e69eb9c4SAlexander Lobakin op(nr, addr)
37e69eb9c4SAlexander Lobakin
38e69eb9c4SAlexander Lobakin #define __set_bit(nr, addr) bitop(___set_bit, nr, addr)
39e69eb9c4SAlexander Lobakin #define __clear_bit(nr, addr) bitop(___clear_bit, nr, addr)
40e69eb9c4SAlexander Lobakin #define __change_bit(nr, addr) bitop(___change_bit, nr, addr)
41e69eb9c4SAlexander Lobakin #define __test_and_set_bit(nr, addr) bitop(___test_and_set_bit, nr, addr)
42e69eb9c4SAlexander Lobakin #define __test_and_clear_bit(nr, addr) bitop(___test_and_clear_bit, nr, addr)
43e69eb9c4SAlexander Lobakin #define __test_and_change_bit(nr, addr) bitop(___test_and_change_bit, nr, addr)
44e69eb9c4SAlexander Lobakin #define test_bit(nr, addr) bitop(_test_bit, nr, addr)
4539672784SArnaldo Carvalho de Melo
4639672784SArnaldo Carvalho de Melo /*
4739672784SArnaldo Carvalho de Melo * Include this here because some architectures need generic_ffs/fls in
4839672784SArnaldo Carvalho de Melo * scope
4939672784SArnaldo Carvalho de Melo *
5039672784SArnaldo Carvalho de Melo * XXX: this needs to be asm/bitops.h, when we get to per arch optimizations
5139672784SArnaldo Carvalho de Melo */
5239672784SArnaldo Carvalho de Melo #include <asm-generic/bitops.h>
5339672784SArnaldo Carvalho de Melo
5439672784SArnaldo Carvalho de Melo #define for_each_set_bit(bit, addr, size) \
5539672784SArnaldo Carvalho de Melo for ((bit) = find_first_bit((addr), (size)); \
5639672784SArnaldo Carvalho de Melo (bit) < (size); \
5702bc11deSJiri Olsa (bit) = find_next_bit((addr), (size), (bit) + 1))
5802bc11deSJiri Olsa
5902bc11deSJiri Olsa #define for_each_clear_bit(bit, addr, size) \
6002bc11deSJiri Olsa for ((bit) = find_first_zero_bit((addr), (size)); \
6102bc11deSJiri Olsa (bit) < (size); \
6239672784SArnaldo Carvalho de Melo (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
6339672784SArnaldo Carvalho de Melo
6439672784SArnaldo Carvalho de Melo /* same as for_each_set_bit() but use bit as value to start with */
6539672784SArnaldo Carvalho de Melo #define for_each_set_bit_from(bit, addr, size) \
6639672784SArnaldo Carvalho de Melo for ((bit) = find_next_bit((addr), (size), (bit)); \
6739672784SArnaldo Carvalho de Melo (bit) < (size); \
6839672784SArnaldo Carvalho de Melo (bit) = find_next_bit((addr), (size), (bit) + 1))
6939672784SArnaldo Carvalho de Melo
hweight_long(unsigned long w)7039672784SArnaldo Carvalho de Melo static inline unsigned long hweight_long(unsigned long w)
7139672784SArnaldo Carvalho de Melo {
7239672784SArnaldo Carvalho de Melo return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
73*9c313ccdSThorsten Blum }
74afcd4f62SArnaldo Carvalho de Melo
fls_long(unsigned long l)75afcd4f62SArnaldo Carvalho de Melo static inline unsigned int fls_long(unsigned long l)
76afcd4f62SArnaldo Carvalho de Melo {
77afcd4f62SArnaldo Carvalho de Melo if (sizeof(l) == 4)
78afcd4f62SArnaldo Carvalho de Melo return fls(l);
79afcd4f62SArnaldo Carvalho de Melo return fls64(l);
806c8e6483SLevin, Alexander (Sasha Levin) }
816c8e6483SLevin, Alexander (Sasha Levin)
826c8e6483SLevin, Alexander (Sasha Levin) /**
836c8e6483SLevin, Alexander (Sasha Levin) * rol32 - rotate a 32-bit value left
846c8e6483SLevin, Alexander (Sasha Levin) * @word: value to rotate
856c8e6483SLevin, Alexander (Sasha Levin) * @shift: bits to roll
866c8e6483SLevin, Alexander (Sasha Levin) */
rol32(__u32 word,unsigned int shift)876c8e6483SLevin, Alexander (Sasha Levin) static inline __u32 rol32(__u32 word, unsigned int shift)
886c8e6483SLevin, Alexander (Sasha Levin) {
896c8e6483SLevin, Alexander (Sasha Levin) return (word << shift) | (word >> ((-shift) & 31));
90b2d23158STiezhu Yang }
91b2d23158STiezhu Yang
92b2d23158STiezhu Yang /**
93b2d23158STiezhu Yang * sign_extend64 - sign extend a 64-bit value using specified bit as sign-bit
94b2d23158STiezhu Yang * @value: value to sign extend
95b2d23158STiezhu Yang * @index: 0 based bit index (0<=index<64) to sign bit
96b2d23158STiezhu Yang */
sign_extend64(__u64 value,int index)97b2d23158STiezhu Yang static __always_inline __s64 sign_extend64(__u64 value, int index)
98b2d23158STiezhu Yang {
99b2d23158STiezhu Yang __u8 shift = 63 - index;
100b2d23158STiezhu Yang return (__s64)(value << shift) >> shift;
10139672784SArnaldo Carvalho de Melo }
102
103 #endif
104