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