xref: /linux-6.15/tools/include/linux/bitops.h (revision 9c313ccd)
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