1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds #ifndef _LINUX_BITOPS_H 31da177e4SLinus Torvalds #define _LINUX_BITOPS_H 41da177e4SLinus Torvalds #include <asm/types.h> 58bd9cb51SWill Deacon #include <linux/bits.h> 61da177e4SLinus Torvalds 7*f5a1a536SAleksa Sarai /* Set bits in the first 'n' bytes when loaded from memory */ 8*f5a1a536SAleksa Sarai #ifdef __LITTLE_ENDIAN 9*f5a1a536SAleksa Sarai # define aligned_byte_mask(n) ((1UL << 8*(n))-1) 10*f5a1a536SAleksa Sarai #else 11*f5a1a536SAleksa Sarai # define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n))) 12*f5a1a536SAleksa Sarai #endif 13*f5a1a536SAleksa Sarai 149144d75eSChris Wilson #define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE) 159144d75eSChris Wilson #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_TYPE(long)) 1610ef6b0dSChen, Gong 174677d4a5SBorislav Petkov extern unsigned int __sw_hweight8(unsigned int w); 184677d4a5SBorislav Petkov extern unsigned int __sw_hweight16(unsigned int w); 194677d4a5SBorislav Petkov extern unsigned int __sw_hweight32(unsigned int w); 204677d4a5SBorislav Petkov extern unsigned long __sw_hweight64(__u64 w); 214677d4a5SBorislav Petkov 221da177e4SLinus Torvalds /* 231da177e4SLinus Torvalds * Include this here because some architectures need generic_ffs/fls in 241da177e4SLinus Torvalds * scope 251da177e4SLinus Torvalds */ 261da177e4SLinus Torvalds #include <asm/bitops.h> 271da177e4SLinus Torvalds 28984b3f57SAkinobu Mita #define for_each_set_bit(bit, addr, size) \ 293e037454SShannon Nelson for ((bit) = find_first_bit((addr), (size)); \ 303e037454SShannon Nelson (bit) < (size); \ 311e2ad28fSRobert Richter (bit) = find_next_bit((addr), (size), (bit) + 1)) 321e2ad28fSRobert Richter 331e2ad28fSRobert Richter /* same as for_each_set_bit() but use bit as value to start with */ 34307b1cd7SAkinobu Mita #define for_each_set_bit_from(bit, addr, size) \ 351e2ad28fSRobert Richter for ((bit) = find_next_bit((addr), (size), (bit)); \ 361e2ad28fSRobert Richter (bit) < (size); \ 373e037454SShannon Nelson (bit) = find_next_bit((addr), (size), (bit) + 1)) 383e037454SShannon Nelson 3903f4a822SAkinobu Mita #define for_each_clear_bit(bit, addr, size) \ 4003f4a822SAkinobu Mita for ((bit) = find_first_zero_bit((addr), (size)); \ 4103f4a822SAkinobu Mita (bit) < (size); \ 4203f4a822SAkinobu Mita (bit) = find_next_zero_bit((addr), (size), (bit) + 1)) 4303f4a822SAkinobu Mita 4403f4a822SAkinobu Mita /* same as for_each_clear_bit() but use bit as value to start with */ 4503f4a822SAkinobu Mita #define for_each_clear_bit_from(bit, addr, size) \ 4603f4a822SAkinobu Mita for ((bit) = find_next_zero_bit((addr), (size), (bit)); \ 4703f4a822SAkinobu Mita (bit) < (size); \ 4803f4a822SAkinobu Mita (bit) = find_next_zero_bit((addr), (size), (bit) + 1)) 4903f4a822SAkinobu Mita 501a1d48a4SDenys Vlasenko static inline int get_bitmask_order(unsigned int count) 511da177e4SLinus Torvalds { 521da177e4SLinus Torvalds int order; 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds order = fls(count); 551da177e4SLinus Torvalds return order; /* We could be slightly more clever with -1 here... */ 561da177e4SLinus Torvalds } 571da177e4SLinus Torvalds 581a1d48a4SDenys Vlasenko static __always_inline unsigned long hweight_long(unsigned long w) 591da177e4SLinus Torvalds { 60e9bebd6fSAkinobu Mita return sizeof(w) == 4 ? hweight32(w) : hweight64(w); 611da177e4SLinus Torvalds } 629f41699eSPeter Zijlstra 6345f8bde0SRobert P. J. Day /** 64f2ea0f5fSAlexey Dobriyan * rol64 - rotate a 64-bit value left 65f2ea0f5fSAlexey Dobriyan * @word: value to rotate 66f2ea0f5fSAlexey Dobriyan * @shift: bits to roll 67f2ea0f5fSAlexey Dobriyan */ 68f2ea0f5fSAlexey Dobriyan static inline __u64 rol64(__u64 word, unsigned int shift) 69f2ea0f5fSAlexey Dobriyan { 70ef4d6f6bSRasmus Villemoes return (word << (shift & 63)) | (word >> ((-shift) & 63)); 71f2ea0f5fSAlexey Dobriyan } 72f2ea0f5fSAlexey Dobriyan 73f2ea0f5fSAlexey Dobriyan /** 74f2ea0f5fSAlexey Dobriyan * ror64 - rotate a 64-bit value right 75f2ea0f5fSAlexey Dobriyan * @word: value to rotate 76f2ea0f5fSAlexey Dobriyan * @shift: bits to roll 77f2ea0f5fSAlexey Dobriyan */ 78f2ea0f5fSAlexey Dobriyan static inline __u64 ror64(__u64 word, unsigned int shift) 79f2ea0f5fSAlexey Dobriyan { 80ef4d6f6bSRasmus Villemoes return (word >> (shift & 63)) | (word << ((-shift) & 63)); 81f2ea0f5fSAlexey Dobriyan } 82f2ea0f5fSAlexey Dobriyan 83f2ea0f5fSAlexey Dobriyan /** 841da177e4SLinus Torvalds * rol32 - rotate a 32-bit value left 851da177e4SLinus Torvalds * @word: value to rotate 861da177e4SLinus Torvalds * @shift: bits to roll 871da177e4SLinus Torvalds */ 881da177e4SLinus Torvalds static inline __u32 rol32(__u32 word, unsigned int shift) 891da177e4SLinus Torvalds { 90ef4d6f6bSRasmus Villemoes return (word << (shift & 31)) | (word >> ((-shift) & 31)); 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds 9345f8bde0SRobert P. J. Day /** 941da177e4SLinus Torvalds * ror32 - rotate a 32-bit value right 951da177e4SLinus Torvalds * @word: value to rotate 961da177e4SLinus Torvalds * @shift: bits to roll 971da177e4SLinus Torvalds */ 981da177e4SLinus Torvalds static inline __u32 ror32(__u32 word, unsigned int shift) 991da177e4SLinus Torvalds { 100ef4d6f6bSRasmus Villemoes return (word >> (shift & 31)) | (word << ((-shift) & 31)); 1011da177e4SLinus Torvalds } 1021da177e4SLinus Torvalds 1033afe3925SHarvey Harrison /** 1043afe3925SHarvey Harrison * rol16 - rotate a 16-bit value left 1053afe3925SHarvey Harrison * @word: value to rotate 1063afe3925SHarvey Harrison * @shift: bits to roll 1073afe3925SHarvey Harrison */ 1083afe3925SHarvey Harrison static inline __u16 rol16(__u16 word, unsigned int shift) 1093afe3925SHarvey Harrison { 110ef4d6f6bSRasmus Villemoes return (word << (shift & 15)) | (word >> ((-shift) & 15)); 1113afe3925SHarvey Harrison } 1123afe3925SHarvey Harrison 1133afe3925SHarvey Harrison /** 1143afe3925SHarvey Harrison * ror16 - rotate a 16-bit value right 1153afe3925SHarvey Harrison * @word: value to rotate 1163afe3925SHarvey Harrison * @shift: bits to roll 1173afe3925SHarvey Harrison */ 1183afe3925SHarvey Harrison static inline __u16 ror16(__u16 word, unsigned int shift) 1193afe3925SHarvey Harrison { 120ef4d6f6bSRasmus Villemoes return (word >> (shift & 15)) | (word << ((-shift) & 15)); 1213afe3925SHarvey Harrison } 1223afe3925SHarvey Harrison 1233afe3925SHarvey Harrison /** 1243afe3925SHarvey Harrison * rol8 - rotate an 8-bit value left 1253afe3925SHarvey Harrison * @word: value to rotate 1263afe3925SHarvey Harrison * @shift: bits to roll 1273afe3925SHarvey Harrison */ 1283afe3925SHarvey Harrison static inline __u8 rol8(__u8 word, unsigned int shift) 1293afe3925SHarvey Harrison { 130ef4d6f6bSRasmus Villemoes return (word << (shift & 7)) | (word >> ((-shift) & 7)); 1313afe3925SHarvey Harrison } 1323afe3925SHarvey Harrison 1333afe3925SHarvey Harrison /** 1343afe3925SHarvey Harrison * ror8 - rotate an 8-bit value right 1353afe3925SHarvey Harrison * @word: value to rotate 1363afe3925SHarvey Harrison * @shift: bits to roll 1373afe3925SHarvey Harrison */ 1383afe3925SHarvey Harrison static inline __u8 ror8(__u8 word, unsigned int shift) 1393afe3925SHarvey Harrison { 140ef4d6f6bSRasmus Villemoes return (word >> (shift & 7)) | (word << ((-shift) & 7)); 1413afe3925SHarvey Harrison } 1423afe3925SHarvey Harrison 1437919a57bSAndreas Herrmann /** 1447919a57bSAndreas Herrmann * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit 1457919a57bSAndreas Herrmann * @value: value to sign extend 1467919a57bSAndreas Herrmann * @index: 0 based bit index (0<=index<32) to sign bit 147e2eb53aaSMartin Kepplinger * 148e2eb53aaSMartin Kepplinger * This is safe to use for 16- and 8-bit types as well. 1497919a57bSAndreas Herrmann */ 1507919a57bSAndreas Herrmann static inline __s32 sign_extend32(__u32 value, int index) 1517919a57bSAndreas Herrmann { 1527919a57bSAndreas Herrmann __u8 shift = 31 - index; 1537919a57bSAndreas Herrmann return (__s32)(value << shift) >> shift; 1547919a57bSAndreas Herrmann } 1557919a57bSAndreas Herrmann 15648e203e2SMartin Kepplinger /** 15748e203e2SMartin Kepplinger * sign_extend64 - sign extend a 64-bit value using specified bit as sign-bit 15848e203e2SMartin Kepplinger * @value: value to sign extend 15948e203e2SMartin Kepplinger * @index: 0 based bit index (0<=index<64) to sign bit 16048e203e2SMartin Kepplinger */ 16148e203e2SMartin Kepplinger static inline __s64 sign_extend64(__u64 value, int index) 16248e203e2SMartin Kepplinger { 16348e203e2SMartin Kepplinger __u8 shift = 63 - index; 16448e203e2SMartin Kepplinger return (__s64)(value << shift) >> shift; 16548e203e2SMartin Kepplinger } 16648e203e2SMartin Kepplinger 167962749afSAndrew Morton static inline unsigned fls_long(unsigned long l) 168962749afSAndrew Morton { 169962749afSAndrew Morton if (sizeof(l) == 4) 170962749afSAndrew Morton return fls(l); 171962749afSAndrew Morton return fls64(l); 172962749afSAndrew Morton } 173962749afSAndrew Morton 174252e5c6eSzijun_hu static inline int get_count_order(unsigned int count) 175252e5c6eSzijun_hu { 176252e5c6eSzijun_hu int order; 177252e5c6eSzijun_hu 178252e5c6eSzijun_hu order = fls(count) - 1; 179252e5c6eSzijun_hu if (count & (count - 1)) 180252e5c6eSzijun_hu order++; 181252e5c6eSzijun_hu return order; 182252e5c6eSzijun_hu } 183252e5c6eSzijun_hu 184252e5c6eSzijun_hu /** 185252e5c6eSzijun_hu * get_count_order_long - get order after rounding @l up to power of 2 186252e5c6eSzijun_hu * @l: parameter 187252e5c6eSzijun_hu * 188252e5c6eSzijun_hu * it is same as get_count_order() but with long type parameter 189252e5c6eSzijun_hu */ 190252e5c6eSzijun_hu static inline int get_count_order_long(unsigned long l) 191252e5c6eSzijun_hu { 192252e5c6eSzijun_hu if (l == 0UL) 193252e5c6eSzijun_hu return -1; 194252e5c6eSzijun_hu else if (l & (l - 1UL)) 195252e5c6eSzijun_hu return (int)fls_long(l); 196252e5c6eSzijun_hu else 197252e5c6eSzijun_hu return (int)fls_long(l) - 1; 198252e5c6eSzijun_hu } 199252e5c6eSzijun_hu 200952043acSSteven Whitehouse /** 201952043acSSteven Whitehouse * __ffs64 - find first set bit in a 64 bit word 202952043acSSteven Whitehouse * @word: The 64 bit word 203952043acSSteven Whitehouse * 204952043acSSteven Whitehouse * On 64 bit arches this is a synomyn for __ffs 205952043acSSteven Whitehouse * The result is not defined if no bits are set, so check that @word 206952043acSSteven Whitehouse * is non-zero before calling this. 207952043acSSteven Whitehouse */ 208952043acSSteven Whitehouse static inline unsigned long __ffs64(u64 word) 209952043acSSteven Whitehouse { 210952043acSSteven Whitehouse #if BITS_PER_LONG == 32 211952043acSSteven Whitehouse if (((u32)word) == 0UL) 212952043acSSteven Whitehouse return __ffs((u32)(word >> 32)) + 32; 213952043acSSteven Whitehouse #elif BITS_PER_LONG != 64 214952043acSSteven Whitehouse #error BITS_PER_LONG not 32 or 64 215952043acSSteven Whitehouse #endif 216952043acSSteven Whitehouse return __ffs((unsigned long)word); 217952043acSSteven Whitehouse } 218952043acSSteven Whitehouse 2195307e2adSLukas Wunner /** 2205307e2adSLukas Wunner * assign_bit - Assign value to a bit in memory 2215307e2adSLukas Wunner * @nr: the bit to set 2225307e2adSLukas Wunner * @addr: the address to start counting from 2235307e2adSLukas Wunner * @value: the value to assign 2245307e2adSLukas Wunner */ 2255307e2adSLukas Wunner static __always_inline void assign_bit(long nr, volatile unsigned long *addr, 2265307e2adSLukas Wunner bool value) 2275307e2adSLukas Wunner { 2285307e2adSLukas Wunner if (value) 2295307e2adSLukas Wunner set_bit(nr, addr); 2305307e2adSLukas Wunner else 2315307e2adSLukas Wunner clear_bit(nr, addr); 2325307e2adSLukas Wunner } 2335307e2adSLukas Wunner 2345307e2adSLukas Wunner static __always_inline void __assign_bit(long nr, volatile unsigned long *addr, 2355307e2adSLukas Wunner bool value) 2365307e2adSLukas Wunner { 2375307e2adSLukas Wunner if (value) 2385307e2adSLukas Wunner __set_bit(nr, addr); 2395307e2adSLukas Wunner else 2405307e2adSLukas Wunner __clear_bit(nr, addr); 2415307e2adSLukas Wunner } 2425307e2adSLukas Wunner 24364970b68SAlexander van Heukelum #ifdef __KERNEL__ 24477b9bd9cSAlexander van Heukelum 24500a1a053STheodore Ts'o #ifndef set_mask_bits 24618127429SMiklos Szeredi #define set_mask_bits(ptr, mask, bits) \ 24700a1a053STheodore Ts'o ({ \ 24818127429SMiklos Szeredi const typeof(*(ptr)) mask__ = (mask), bits__ = (bits); \ 24918127429SMiklos Szeredi typeof(*(ptr)) old__, new__; \ 25000a1a053STheodore Ts'o \ 25100a1a053STheodore Ts'o do { \ 25218127429SMiklos Szeredi old__ = READ_ONCE(*(ptr)); \ 25318127429SMiklos Szeredi new__ = (old__ & ~mask__) | bits__; \ 25418127429SMiklos Szeredi } while (cmpxchg(ptr, old__, new__) != old__); \ 25500a1a053STheodore Ts'o \ 2561db604f6SVineet Gupta old__; \ 25700a1a053STheodore Ts'o }) 25800a1a053STheodore Ts'o #endif 25900a1a053STheodore Ts'o 26085ad1d13SGuoqing Jiang #ifndef bit_clear_unless 261edfa8728SMiklos Szeredi #define bit_clear_unless(ptr, clear, test) \ 26285ad1d13SGuoqing Jiang ({ \ 263edfa8728SMiklos Szeredi const typeof(*(ptr)) clear__ = (clear), test__ = (test);\ 264edfa8728SMiklos Szeredi typeof(*(ptr)) old__, new__; \ 26585ad1d13SGuoqing Jiang \ 26685ad1d13SGuoqing Jiang do { \ 267edfa8728SMiklos Szeredi old__ = READ_ONCE(*(ptr)); \ 268edfa8728SMiklos Szeredi new__ = old__ & ~clear__; \ 269edfa8728SMiklos Szeredi } while (!(old__ & test__) && \ 270edfa8728SMiklos Szeredi cmpxchg(ptr, old__, new__) != old__); \ 27185ad1d13SGuoqing Jiang \ 272edfa8728SMiklos Szeredi !(old__ & test__); \ 27385ad1d13SGuoqing Jiang }) 27485ad1d13SGuoqing Jiang #endif 27585ad1d13SGuoqing Jiang 27619de85efSAkinobu Mita #ifndef find_last_bit 277ab53d472SRusty Russell /** 278ab53d472SRusty Russell * find_last_bit - find the last set bit in a memory region 279ab53d472SRusty Russell * @addr: The address to start the search at 2802c57a0e2SYury Norov * @size: The number of bits to search 281ab53d472SRusty Russell * 2822c57a0e2SYury Norov * Returns the bit number of the last set bit, or size. 283ab53d472SRusty Russell */ 284ab53d472SRusty Russell extern unsigned long find_last_bit(const unsigned long *addr, 285ab53d472SRusty Russell unsigned long size); 28619de85efSAkinobu Mita #endif 287ab53d472SRusty Russell 28864970b68SAlexander van Heukelum #endif /* __KERNEL__ */ 2891da177e4SLinus Torvalds #endif 290