xref: /kernel/linux/linux-5.10/include/linux/bitops.h (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _LINUX_BITOPS_H
38c2ecf20Sopenharmony_ci#define _LINUX_BITOPS_H
48c2ecf20Sopenharmony_ci#include <asm/types.h>
58c2ecf20Sopenharmony_ci#include <linux/bits.h>
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci/* Set bits in the first 'n' bytes when loaded from memory */
88c2ecf20Sopenharmony_ci#ifdef __LITTLE_ENDIAN
98c2ecf20Sopenharmony_ci#  define aligned_byte_mask(n) ((1UL << 8*(n))-1)
108c2ecf20Sopenharmony_ci#else
118c2ecf20Sopenharmony_ci#  define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n)))
128c2ecf20Sopenharmony_ci#endif
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#define BITS_PER_TYPE(type)	(sizeof(type) * BITS_PER_BYTE)
158c2ecf20Sopenharmony_ci#define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
168c2ecf20Sopenharmony_ci#define BITS_TO_U64(nr)		DIV_ROUND_UP(nr, BITS_PER_TYPE(u64))
178c2ecf20Sopenharmony_ci#define BITS_TO_U32(nr)		DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
188c2ecf20Sopenharmony_ci#define BITS_TO_BYTES(nr)	DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciextern unsigned int __sw_hweight8(unsigned int w);
218c2ecf20Sopenharmony_ciextern unsigned int __sw_hweight16(unsigned int w);
228c2ecf20Sopenharmony_ciextern unsigned int __sw_hweight32(unsigned int w);
238c2ecf20Sopenharmony_ciextern unsigned long __sw_hweight64(__u64 w);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci/*
268c2ecf20Sopenharmony_ci * Include this here because some architectures need generic_ffs/fls in
278c2ecf20Sopenharmony_ci * scope
288c2ecf20Sopenharmony_ci */
298c2ecf20Sopenharmony_ci#include <asm/bitops.h>
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci#define for_each_set_bit(bit, addr, size) \
328c2ecf20Sopenharmony_ci	for ((bit) = find_first_bit((addr), (size));		\
338c2ecf20Sopenharmony_ci	     (bit) < (size);					\
348c2ecf20Sopenharmony_ci	     (bit) = find_next_bit((addr), (size), (bit) + 1))
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci/* same as for_each_set_bit() but use bit as value to start with */
378c2ecf20Sopenharmony_ci#define for_each_set_bit_from(bit, addr, size) \
388c2ecf20Sopenharmony_ci	for ((bit) = find_next_bit((addr), (size), (bit));	\
398c2ecf20Sopenharmony_ci	     (bit) < (size);					\
408c2ecf20Sopenharmony_ci	     (bit) = find_next_bit((addr), (size), (bit) + 1))
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#define for_each_clear_bit(bit, addr, size) \
438c2ecf20Sopenharmony_ci	for ((bit) = find_first_zero_bit((addr), (size));	\
448c2ecf20Sopenharmony_ci	     (bit) < (size);					\
458c2ecf20Sopenharmony_ci	     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/* same as for_each_clear_bit() but use bit as value to start with */
488c2ecf20Sopenharmony_ci#define for_each_clear_bit_from(bit, addr, size) \
498c2ecf20Sopenharmony_ci	for ((bit) = find_next_zero_bit((addr), (size), (bit));	\
508c2ecf20Sopenharmony_ci	     (bit) < (size);					\
518c2ecf20Sopenharmony_ci	     (bit) = find_next_zero_bit((addr), (size), (bit) + 1))
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci/**
548c2ecf20Sopenharmony_ci * for_each_set_clump8 - iterate over bitmap for each 8-bit clump with set bits
558c2ecf20Sopenharmony_ci * @start: bit offset to start search and to store the current iteration offset
568c2ecf20Sopenharmony_ci * @clump: location to store copy of current 8-bit clump
578c2ecf20Sopenharmony_ci * @bits: bitmap address to base the search on
588c2ecf20Sopenharmony_ci * @size: bitmap size in number of bits
598c2ecf20Sopenharmony_ci */
608c2ecf20Sopenharmony_ci#define for_each_set_clump8(start, clump, bits, size) \
618c2ecf20Sopenharmony_ci	for ((start) = find_first_clump8(&(clump), (bits), (size)); \
628c2ecf20Sopenharmony_ci	     (start) < (size); \
638c2ecf20Sopenharmony_ci	     (start) = find_next_clump8(&(clump), (bits), (size), (start) + 8))
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_cistatic inline int get_bitmask_order(unsigned int count)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	int order;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	order = fls(count);
708c2ecf20Sopenharmony_ci	return order;	/* We could be slightly more clever with -1 here... */
718c2ecf20Sopenharmony_ci}
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_cistatic __always_inline unsigned long hweight_long(unsigned long w)
748c2ecf20Sopenharmony_ci{
758c2ecf20Sopenharmony_ci	return sizeof(w) == 4 ? hweight32(w) : hweight64((__u64)w);
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/**
798c2ecf20Sopenharmony_ci * rol64 - rotate a 64-bit value left
808c2ecf20Sopenharmony_ci * @word: value to rotate
818c2ecf20Sopenharmony_ci * @shift: bits to roll
828c2ecf20Sopenharmony_ci */
838c2ecf20Sopenharmony_cistatic inline __u64 rol64(__u64 word, unsigned int shift)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	return (word << (shift & 63)) | (word >> ((-shift) & 63));
868c2ecf20Sopenharmony_ci}
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci/**
898c2ecf20Sopenharmony_ci * ror64 - rotate a 64-bit value right
908c2ecf20Sopenharmony_ci * @word: value to rotate
918c2ecf20Sopenharmony_ci * @shift: bits to roll
928c2ecf20Sopenharmony_ci */
938c2ecf20Sopenharmony_cistatic inline __u64 ror64(__u64 word, unsigned int shift)
948c2ecf20Sopenharmony_ci{
958c2ecf20Sopenharmony_ci	return (word >> (shift & 63)) | (word << ((-shift) & 63));
968c2ecf20Sopenharmony_ci}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci/**
998c2ecf20Sopenharmony_ci * rol32 - rotate a 32-bit value left
1008c2ecf20Sopenharmony_ci * @word: value to rotate
1018c2ecf20Sopenharmony_ci * @shift: bits to roll
1028c2ecf20Sopenharmony_ci */
1038c2ecf20Sopenharmony_cistatic inline __u32 rol32(__u32 word, unsigned int shift)
1048c2ecf20Sopenharmony_ci{
1058c2ecf20Sopenharmony_ci	return (word << (shift & 31)) | (word >> ((-shift) & 31));
1068c2ecf20Sopenharmony_ci}
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci/**
1098c2ecf20Sopenharmony_ci * ror32 - rotate a 32-bit value right
1108c2ecf20Sopenharmony_ci * @word: value to rotate
1118c2ecf20Sopenharmony_ci * @shift: bits to roll
1128c2ecf20Sopenharmony_ci */
1138c2ecf20Sopenharmony_cistatic inline __u32 ror32(__u32 word, unsigned int shift)
1148c2ecf20Sopenharmony_ci{
1158c2ecf20Sopenharmony_ci	return (word >> (shift & 31)) | (word << ((-shift) & 31));
1168c2ecf20Sopenharmony_ci}
1178c2ecf20Sopenharmony_ci
1188c2ecf20Sopenharmony_ci/**
1198c2ecf20Sopenharmony_ci * rol16 - rotate a 16-bit value left
1208c2ecf20Sopenharmony_ci * @word: value to rotate
1218c2ecf20Sopenharmony_ci * @shift: bits to roll
1228c2ecf20Sopenharmony_ci */
1238c2ecf20Sopenharmony_cistatic inline __u16 rol16(__u16 word, unsigned int shift)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	return (word << (shift & 15)) | (word >> ((-shift) & 15));
1268c2ecf20Sopenharmony_ci}
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci/**
1298c2ecf20Sopenharmony_ci * ror16 - rotate a 16-bit value right
1308c2ecf20Sopenharmony_ci * @word: value to rotate
1318c2ecf20Sopenharmony_ci * @shift: bits to roll
1328c2ecf20Sopenharmony_ci */
1338c2ecf20Sopenharmony_cistatic inline __u16 ror16(__u16 word, unsigned int shift)
1348c2ecf20Sopenharmony_ci{
1358c2ecf20Sopenharmony_ci	return (word >> (shift & 15)) | (word << ((-shift) & 15));
1368c2ecf20Sopenharmony_ci}
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci/**
1398c2ecf20Sopenharmony_ci * rol8 - rotate an 8-bit value left
1408c2ecf20Sopenharmony_ci * @word: value to rotate
1418c2ecf20Sopenharmony_ci * @shift: bits to roll
1428c2ecf20Sopenharmony_ci */
1438c2ecf20Sopenharmony_cistatic inline __u8 rol8(__u8 word, unsigned int shift)
1448c2ecf20Sopenharmony_ci{
1458c2ecf20Sopenharmony_ci	return (word << (shift & 7)) | (word >> ((-shift) & 7));
1468c2ecf20Sopenharmony_ci}
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci/**
1498c2ecf20Sopenharmony_ci * ror8 - rotate an 8-bit value right
1508c2ecf20Sopenharmony_ci * @word: value to rotate
1518c2ecf20Sopenharmony_ci * @shift: bits to roll
1528c2ecf20Sopenharmony_ci */
1538c2ecf20Sopenharmony_cistatic inline __u8 ror8(__u8 word, unsigned int shift)
1548c2ecf20Sopenharmony_ci{
1558c2ecf20Sopenharmony_ci	return (word >> (shift & 7)) | (word << ((-shift) & 7));
1568c2ecf20Sopenharmony_ci}
1578c2ecf20Sopenharmony_ci
1588c2ecf20Sopenharmony_ci/**
1598c2ecf20Sopenharmony_ci * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit
1608c2ecf20Sopenharmony_ci * @value: value to sign extend
1618c2ecf20Sopenharmony_ci * @index: 0 based bit index (0<=index<32) to sign bit
1628c2ecf20Sopenharmony_ci *
1638c2ecf20Sopenharmony_ci * This is safe to use for 16- and 8-bit types as well.
1648c2ecf20Sopenharmony_ci */
1658c2ecf20Sopenharmony_cistatic __always_inline __s32 sign_extend32(__u32 value, int index)
1668c2ecf20Sopenharmony_ci{
1678c2ecf20Sopenharmony_ci	__u8 shift = 31 - index;
1688c2ecf20Sopenharmony_ci	return (__s32)(value << shift) >> shift;
1698c2ecf20Sopenharmony_ci}
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci/**
1728c2ecf20Sopenharmony_ci * sign_extend64 - sign extend a 64-bit value using specified bit as sign-bit
1738c2ecf20Sopenharmony_ci * @value: value to sign extend
1748c2ecf20Sopenharmony_ci * @index: 0 based bit index (0<=index<64) to sign bit
1758c2ecf20Sopenharmony_ci */
1768c2ecf20Sopenharmony_cistatic __always_inline __s64 sign_extend64(__u64 value, int index)
1778c2ecf20Sopenharmony_ci{
1788c2ecf20Sopenharmony_ci	__u8 shift = 63 - index;
1798c2ecf20Sopenharmony_ci	return (__s64)(value << shift) >> shift;
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic inline unsigned fls_long(unsigned long l)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	if (sizeof(l) == 4)
1858c2ecf20Sopenharmony_ci		return fls(l);
1868c2ecf20Sopenharmony_ci	return fls64(l);
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_cistatic inline int get_count_order(unsigned int count)
1908c2ecf20Sopenharmony_ci{
1918c2ecf20Sopenharmony_ci	if (count == 0)
1928c2ecf20Sopenharmony_ci		return -1;
1938c2ecf20Sopenharmony_ci
1948c2ecf20Sopenharmony_ci	return fls(--count);
1958c2ecf20Sopenharmony_ci}
1968c2ecf20Sopenharmony_ci
1978c2ecf20Sopenharmony_ci/**
1988c2ecf20Sopenharmony_ci * get_count_order_long - get order after rounding @l up to power of 2
1998c2ecf20Sopenharmony_ci * @l: parameter
2008c2ecf20Sopenharmony_ci *
2018c2ecf20Sopenharmony_ci * it is same as get_count_order() but with long type parameter
2028c2ecf20Sopenharmony_ci */
2038c2ecf20Sopenharmony_cistatic inline int get_count_order_long(unsigned long l)
2048c2ecf20Sopenharmony_ci{
2058c2ecf20Sopenharmony_ci	if (l == 0UL)
2068c2ecf20Sopenharmony_ci		return -1;
2078c2ecf20Sopenharmony_ci	return (int)fls_long(--l);
2088c2ecf20Sopenharmony_ci}
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_ci/**
2118c2ecf20Sopenharmony_ci * __ffs64 - find first set bit in a 64 bit word
2128c2ecf20Sopenharmony_ci * @word: The 64 bit word
2138c2ecf20Sopenharmony_ci *
2148c2ecf20Sopenharmony_ci * On 64 bit arches this is a synomyn for __ffs
2158c2ecf20Sopenharmony_ci * The result is not defined if no bits are set, so check that @word
2168c2ecf20Sopenharmony_ci * is non-zero before calling this.
2178c2ecf20Sopenharmony_ci */
2188c2ecf20Sopenharmony_cistatic inline unsigned long __ffs64(u64 word)
2198c2ecf20Sopenharmony_ci{
2208c2ecf20Sopenharmony_ci#if BITS_PER_LONG == 32
2218c2ecf20Sopenharmony_ci	if (((u32)word) == 0UL)
2228c2ecf20Sopenharmony_ci		return __ffs((u32)(word >> 32)) + 32;
2238c2ecf20Sopenharmony_ci#elif BITS_PER_LONG != 64
2248c2ecf20Sopenharmony_ci#error BITS_PER_LONG not 32 or 64
2258c2ecf20Sopenharmony_ci#endif
2268c2ecf20Sopenharmony_ci	return __ffs((unsigned long)word);
2278c2ecf20Sopenharmony_ci}
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci/**
2308c2ecf20Sopenharmony_ci * assign_bit - Assign value to a bit in memory
2318c2ecf20Sopenharmony_ci * @nr: the bit to set
2328c2ecf20Sopenharmony_ci * @addr: the address to start counting from
2338c2ecf20Sopenharmony_ci * @value: the value to assign
2348c2ecf20Sopenharmony_ci */
2358c2ecf20Sopenharmony_cistatic __always_inline void assign_bit(long nr, volatile unsigned long *addr,
2368c2ecf20Sopenharmony_ci				       bool value)
2378c2ecf20Sopenharmony_ci{
2388c2ecf20Sopenharmony_ci	if (value)
2398c2ecf20Sopenharmony_ci		set_bit(nr, addr);
2408c2ecf20Sopenharmony_ci	else
2418c2ecf20Sopenharmony_ci		clear_bit(nr, addr);
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_cistatic __always_inline void __assign_bit(long nr, volatile unsigned long *addr,
2458c2ecf20Sopenharmony_ci					 bool value)
2468c2ecf20Sopenharmony_ci{
2478c2ecf20Sopenharmony_ci	if (value)
2488c2ecf20Sopenharmony_ci		__set_bit(nr, addr);
2498c2ecf20Sopenharmony_ci	else
2508c2ecf20Sopenharmony_ci		__clear_bit(nr, addr);
2518c2ecf20Sopenharmony_ci}
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci#ifdef __KERNEL__
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci#ifndef set_mask_bits
2568c2ecf20Sopenharmony_ci#define set_mask_bits(ptr, mask, bits)	\
2578c2ecf20Sopenharmony_ci({								\
2588c2ecf20Sopenharmony_ci	const typeof(*(ptr)) mask__ = (mask), bits__ = (bits);	\
2598c2ecf20Sopenharmony_ci	typeof(*(ptr)) old__, new__;				\
2608c2ecf20Sopenharmony_ci								\
2618c2ecf20Sopenharmony_ci	do {							\
2628c2ecf20Sopenharmony_ci		old__ = READ_ONCE(*(ptr));			\
2638c2ecf20Sopenharmony_ci		new__ = (old__ & ~mask__) | bits__;		\
2648c2ecf20Sopenharmony_ci	} while (cmpxchg(ptr, old__, new__) != old__);		\
2658c2ecf20Sopenharmony_ci								\
2668c2ecf20Sopenharmony_ci	old__;							\
2678c2ecf20Sopenharmony_ci})
2688c2ecf20Sopenharmony_ci#endif
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci#ifndef bit_clear_unless
2718c2ecf20Sopenharmony_ci#define bit_clear_unless(ptr, clear, test)	\
2728c2ecf20Sopenharmony_ci({								\
2738c2ecf20Sopenharmony_ci	const typeof(*(ptr)) clear__ = (clear), test__ = (test);\
2748c2ecf20Sopenharmony_ci	typeof(*(ptr)) old__, new__;				\
2758c2ecf20Sopenharmony_ci								\
2768c2ecf20Sopenharmony_ci	do {							\
2778c2ecf20Sopenharmony_ci		old__ = READ_ONCE(*(ptr));			\
2788c2ecf20Sopenharmony_ci		new__ = old__ & ~clear__;			\
2798c2ecf20Sopenharmony_ci	} while (!(old__ & test__) &&				\
2808c2ecf20Sopenharmony_ci		 cmpxchg(ptr, old__, new__) != old__);		\
2818c2ecf20Sopenharmony_ci								\
2828c2ecf20Sopenharmony_ci	!(old__ & test__);					\
2838c2ecf20Sopenharmony_ci})
2848c2ecf20Sopenharmony_ci#endif
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ci#ifndef find_last_bit
2878c2ecf20Sopenharmony_ci/**
2888c2ecf20Sopenharmony_ci * find_last_bit - find the last set bit in a memory region
2898c2ecf20Sopenharmony_ci * @addr: The address to start the search at
2908c2ecf20Sopenharmony_ci * @size: The number of bits to search
2918c2ecf20Sopenharmony_ci *
2928c2ecf20Sopenharmony_ci * Returns the bit number of the last set bit, or size.
2938c2ecf20Sopenharmony_ci */
2948c2ecf20Sopenharmony_ciextern unsigned long find_last_bit(const unsigned long *addr,
2958c2ecf20Sopenharmony_ci				   unsigned long size);
2968c2ecf20Sopenharmony_ci#endif
2978c2ecf20Sopenharmony_ci
2988c2ecf20Sopenharmony_ci#endif /* __KERNEL__ */
2998c2ecf20Sopenharmony_ci#endif
300