1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds #ifndef _LINUX_BITOPS_H 31da177e4SLinus Torvalds #define _LINUX_BITOPS_H 4aa6159abSAndy Shevchenko 51da177e4SLinus Torvalds #include <asm/types.h> 68bd9cb51SWill Deacon #include <linux/bits.h> 7cb0f8003SKumar Kartikeya Dwivedi #include <linux/typecheck.h> 81da177e4SLinus Torvalds 9aa6159abSAndy Shevchenko #include <uapi/linux/kernel.h> 10aa6159abSAndy Shevchenko 11f5a1a536SAleksa Sarai /* Set bits in the first 'n' bytes when loaded from memory */ 12f5a1a536SAleksa Sarai #ifdef __LITTLE_ENDIAN 13f5a1a536SAleksa Sarai # define aligned_byte_mask(n) ((1UL << 8*(n))-1) 14f5a1a536SAleksa Sarai #else 15f5a1a536SAleksa Sarai # define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n))) 16f5a1a536SAleksa Sarai #endif 17f5a1a536SAleksa Sarai 189144d75eSChris Wilson #define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE) 19aa6159abSAndy Shevchenko #define BITS_TO_LONGS(nr) __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(long)) 20aa6159abSAndy Shevchenko #define BITS_TO_U64(nr) __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(u64)) 21aa6159abSAndy Shevchenko #define BITS_TO_U32(nr) __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(u32)) 22aa6159abSAndy Shevchenko #define BITS_TO_BYTES(nr) __KERNEL_DIV_ROUND_UP(nr, BITS_PER_TYPE(char)) 2310ef6b0dSChen, Gong 244677d4a5SBorislav Petkov extern unsigned int __sw_hweight8(unsigned int w); 254677d4a5SBorislav Petkov extern unsigned int __sw_hweight16(unsigned int w); 264677d4a5SBorislav Petkov extern unsigned int __sw_hweight32(unsigned int w); 274677d4a5SBorislav Petkov extern unsigned long __sw_hweight64(__u64 w); 284677d4a5SBorislav Petkov 290e862838SAlexander Lobakin #include <asm-generic/bitops/generic-non-atomic.h> 300e862838SAlexander Lobakin 311da177e4SLinus Torvalds /* 321da177e4SLinus Torvalds * Include this here because some architectures need generic_ffs/fls in 331da177e4SLinus Torvalds * scope 341da177e4SLinus Torvalds */ 351da177e4SLinus Torvalds #include <asm/bitops.h> 361da177e4SLinus Torvalds 370e862838SAlexander Lobakin /* Check that the bitops prototypes are sane */ 380e862838SAlexander Lobakin #define __check_bitop_pr(name) \ 390e862838SAlexander Lobakin static_assert(__same_type(arch_##name, generic_##name) && \ 40*bb7379bfSAlexander Lobakin __same_type(const_##name, generic_##name) && \ 410e862838SAlexander Lobakin __same_type(name, generic_##name)) 420e862838SAlexander Lobakin 430e862838SAlexander Lobakin __check_bitop_pr(__set_bit); 440e862838SAlexander Lobakin __check_bitop_pr(__clear_bit); 450e862838SAlexander Lobakin __check_bitop_pr(__change_bit); 460e862838SAlexander Lobakin __check_bitop_pr(__test_and_set_bit); 470e862838SAlexander Lobakin __check_bitop_pr(__test_and_clear_bit); 480e862838SAlexander Lobakin __check_bitop_pr(__test_and_change_bit); 490e862838SAlexander Lobakin __check_bitop_pr(test_bit); 500e862838SAlexander Lobakin 510e862838SAlexander Lobakin #undef __check_bitop_pr 520e862838SAlexander Lobakin 531a1d48a4SDenys Vlasenko static inline int get_bitmask_order(unsigned int count) 541da177e4SLinus Torvalds { 551da177e4SLinus Torvalds int order; 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds order = fls(count); 581da177e4SLinus Torvalds return order; /* We could be slightly more clever with -1 here... */ 591da177e4SLinus Torvalds } 601da177e4SLinus Torvalds 611a1d48a4SDenys Vlasenko static __always_inline unsigned long hweight_long(unsigned long w) 621da177e4SLinus Torvalds { 63bd93f003SArnd Bergmann return sizeof(w) == 4 ? hweight32(w) : hweight64((__u64)w); 641da177e4SLinus Torvalds } 659f41699eSPeter Zijlstra 6645f8bde0SRobert P. J. Day /** 67f2ea0f5fSAlexey Dobriyan * rol64 - rotate a 64-bit value left 68f2ea0f5fSAlexey Dobriyan * @word: value to rotate 69f2ea0f5fSAlexey Dobriyan * @shift: bits to roll 70f2ea0f5fSAlexey Dobriyan */ 71f2ea0f5fSAlexey Dobriyan static inline __u64 rol64(__u64 word, unsigned int shift) 72f2ea0f5fSAlexey Dobriyan { 73ef4d6f6bSRasmus Villemoes return (word << (shift & 63)) | (word >> ((-shift) & 63)); 74f2ea0f5fSAlexey Dobriyan } 75f2ea0f5fSAlexey Dobriyan 76f2ea0f5fSAlexey Dobriyan /** 77f2ea0f5fSAlexey Dobriyan * ror64 - rotate a 64-bit value right 78f2ea0f5fSAlexey Dobriyan * @word: value to rotate 79f2ea0f5fSAlexey Dobriyan * @shift: bits to roll 80f2ea0f5fSAlexey Dobriyan */ 81f2ea0f5fSAlexey Dobriyan static inline __u64 ror64(__u64 word, unsigned int shift) 82f2ea0f5fSAlexey Dobriyan { 83ef4d6f6bSRasmus Villemoes return (word >> (shift & 63)) | (word << ((-shift) & 63)); 84f2ea0f5fSAlexey Dobriyan } 85f2ea0f5fSAlexey Dobriyan 86f2ea0f5fSAlexey Dobriyan /** 871da177e4SLinus Torvalds * rol32 - rotate a 32-bit value left 881da177e4SLinus Torvalds * @word: value to rotate 891da177e4SLinus Torvalds * @shift: bits to roll 901da177e4SLinus Torvalds */ 911da177e4SLinus Torvalds static inline __u32 rol32(__u32 word, unsigned int shift) 921da177e4SLinus Torvalds { 93ef4d6f6bSRasmus Villemoes return (word << (shift & 31)) | (word >> ((-shift) & 31)); 941da177e4SLinus Torvalds } 951da177e4SLinus Torvalds 9645f8bde0SRobert P. J. Day /** 971da177e4SLinus Torvalds * ror32 - rotate a 32-bit value right 981da177e4SLinus Torvalds * @word: value to rotate 991da177e4SLinus Torvalds * @shift: bits to roll 1001da177e4SLinus Torvalds */ 1011da177e4SLinus Torvalds static inline __u32 ror32(__u32 word, unsigned int shift) 1021da177e4SLinus Torvalds { 103ef4d6f6bSRasmus Villemoes return (word >> (shift & 31)) | (word << ((-shift) & 31)); 1041da177e4SLinus Torvalds } 1051da177e4SLinus Torvalds 1063afe3925SHarvey Harrison /** 1073afe3925SHarvey Harrison * rol16 - rotate a 16-bit value left 1083afe3925SHarvey Harrison * @word: value to rotate 1093afe3925SHarvey Harrison * @shift: bits to roll 1103afe3925SHarvey Harrison */ 1113afe3925SHarvey Harrison static inline __u16 rol16(__u16 word, unsigned int shift) 1123afe3925SHarvey Harrison { 113ef4d6f6bSRasmus Villemoes return (word << (shift & 15)) | (word >> ((-shift) & 15)); 1143afe3925SHarvey Harrison } 1153afe3925SHarvey Harrison 1163afe3925SHarvey Harrison /** 1173afe3925SHarvey Harrison * ror16 - rotate a 16-bit value right 1183afe3925SHarvey Harrison * @word: value to rotate 1193afe3925SHarvey Harrison * @shift: bits to roll 1203afe3925SHarvey Harrison */ 1213afe3925SHarvey Harrison static inline __u16 ror16(__u16 word, unsigned int shift) 1223afe3925SHarvey Harrison { 123ef4d6f6bSRasmus Villemoes return (word >> (shift & 15)) | (word << ((-shift) & 15)); 1243afe3925SHarvey Harrison } 1253afe3925SHarvey Harrison 1263afe3925SHarvey Harrison /** 1273afe3925SHarvey Harrison * rol8 - rotate an 8-bit value left 1283afe3925SHarvey Harrison * @word: value to rotate 1293afe3925SHarvey Harrison * @shift: bits to roll 1303afe3925SHarvey Harrison */ 1313afe3925SHarvey Harrison static inline __u8 rol8(__u8 word, unsigned int shift) 1323afe3925SHarvey Harrison { 133ef4d6f6bSRasmus Villemoes return (word << (shift & 7)) | (word >> ((-shift) & 7)); 1343afe3925SHarvey Harrison } 1353afe3925SHarvey Harrison 1363afe3925SHarvey Harrison /** 1373afe3925SHarvey Harrison * ror8 - rotate an 8-bit value right 1383afe3925SHarvey Harrison * @word: value to rotate 1393afe3925SHarvey Harrison * @shift: bits to roll 1403afe3925SHarvey Harrison */ 1413afe3925SHarvey Harrison static inline __u8 ror8(__u8 word, unsigned int shift) 1423afe3925SHarvey Harrison { 143ef4d6f6bSRasmus Villemoes return (word >> (shift & 7)) | (word << ((-shift) & 7)); 1443afe3925SHarvey Harrison } 1453afe3925SHarvey Harrison 1467919a57bSAndreas Herrmann /** 1477919a57bSAndreas Herrmann * sign_extend32 - sign extend a 32-bit value using specified bit as sign-bit 1487919a57bSAndreas Herrmann * @value: value to sign extend 1497919a57bSAndreas Herrmann * @index: 0 based bit index (0<=index<32) to sign bit 150e2eb53aaSMartin Kepplinger * 151e2eb53aaSMartin Kepplinger * This is safe to use for 16- and 8-bit types as well. 1527919a57bSAndreas Herrmann */ 153f80ac98aSJosh Poimboeuf static __always_inline __s32 sign_extend32(__u32 value, int index) 1547919a57bSAndreas Herrmann { 1557919a57bSAndreas Herrmann __u8 shift = 31 - index; 1567919a57bSAndreas Herrmann return (__s32)(value << shift) >> shift; 1577919a57bSAndreas Herrmann } 1587919a57bSAndreas Herrmann 15948e203e2SMartin Kepplinger /** 16048e203e2SMartin Kepplinger * sign_extend64 - sign extend a 64-bit value using specified bit as sign-bit 16148e203e2SMartin Kepplinger * @value: value to sign extend 16248e203e2SMartin Kepplinger * @index: 0 based bit index (0<=index<64) to sign bit 16348e203e2SMartin Kepplinger */ 164f80ac98aSJosh Poimboeuf static __always_inline __s64 sign_extend64(__u64 value, int index) 16548e203e2SMartin Kepplinger { 16648e203e2SMartin Kepplinger __u8 shift = 63 - index; 16748e203e2SMartin Kepplinger return (__s64)(value << shift) >> shift; 16848e203e2SMartin Kepplinger } 16948e203e2SMartin Kepplinger 170962749afSAndrew Morton static inline unsigned fls_long(unsigned long l) 171962749afSAndrew Morton { 172962749afSAndrew Morton if (sizeof(l) == 4) 173962749afSAndrew Morton return fls(l); 174962749afSAndrew Morton return fls64(l); 175962749afSAndrew Morton } 176962749afSAndrew Morton 177252e5c6eSzijun_hu static inline int get_count_order(unsigned int count) 178252e5c6eSzijun_hu { 179004fba1aSWei Yang if (count == 0) 180004fba1aSWei Yang return -1; 181252e5c6eSzijun_hu 182004fba1aSWei Yang return fls(--count); 183252e5c6eSzijun_hu } 184252e5c6eSzijun_hu 185252e5c6eSzijun_hu /** 186252e5c6eSzijun_hu * get_count_order_long - get order after rounding @l up to power of 2 187252e5c6eSzijun_hu * @l: parameter 188252e5c6eSzijun_hu * 189252e5c6eSzijun_hu * it is same as get_count_order() but with long type parameter 190252e5c6eSzijun_hu */ 191252e5c6eSzijun_hu static inline int get_count_order_long(unsigned long l) 192252e5c6eSzijun_hu { 193252e5c6eSzijun_hu if (l == 0UL) 194252e5c6eSzijun_hu return -1; 195a9eb6370SWei Yang return (int)fls_long(--l); 196252e5c6eSzijun_hu } 197252e5c6eSzijun_hu 198952043acSSteven Whitehouse /** 199952043acSSteven Whitehouse * __ffs64 - find first set bit in a 64 bit word 200952043acSSteven Whitehouse * @word: The 64 bit word 201952043acSSteven Whitehouse * 2024945cca2SGeert Uytterhoeven * On 64 bit arches this is a synonym for __ffs 203952043acSSteven Whitehouse * The result is not defined if no bits are set, so check that @word 204952043acSSteven Whitehouse * is non-zero before calling this. 205952043acSSteven Whitehouse */ 206952043acSSteven Whitehouse static inline unsigned long __ffs64(u64 word) 207952043acSSteven Whitehouse { 208952043acSSteven Whitehouse #if BITS_PER_LONG == 32 209952043acSSteven Whitehouse if (((u32)word) == 0UL) 210952043acSSteven Whitehouse return __ffs((u32)(word >> 32)) + 32; 211952043acSSteven Whitehouse #elif BITS_PER_LONG != 64 212952043acSSteven Whitehouse #error BITS_PER_LONG not 32 or 64 213952043acSSteven Whitehouse #endif 214952043acSSteven Whitehouse return __ffs((unsigned long)word); 215952043acSSteven Whitehouse } 216952043acSSteven Whitehouse 2175307e2adSLukas Wunner /** 2185307e2adSLukas Wunner * assign_bit - Assign value to a bit in memory 2195307e2adSLukas Wunner * @nr: the bit to set 2205307e2adSLukas Wunner * @addr: the address to start counting from 2215307e2adSLukas Wunner * @value: the value to assign 2225307e2adSLukas Wunner */ 2235307e2adSLukas Wunner static __always_inline void assign_bit(long nr, volatile unsigned long *addr, 2245307e2adSLukas Wunner bool value) 2255307e2adSLukas Wunner { 2265307e2adSLukas Wunner if (value) 2275307e2adSLukas Wunner set_bit(nr, addr); 2285307e2adSLukas Wunner else 2295307e2adSLukas Wunner clear_bit(nr, addr); 2305307e2adSLukas Wunner } 2315307e2adSLukas Wunner 2325307e2adSLukas Wunner static __always_inline void __assign_bit(long nr, volatile unsigned long *addr, 2335307e2adSLukas Wunner bool value) 2345307e2adSLukas Wunner { 2355307e2adSLukas Wunner if (value) 2365307e2adSLukas Wunner __set_bit(nr, addr); 2375307e2adSLukas Wunner else 2385307e2adSLukas Wunner __clear_bit(nr, addr); 2395307e2adSLukas Wunner } 2405307e2adSLukas Wunner 241cb0f8003SKumar Kartikeya Dwivedi /** 242cb0f8003SKumar Kartikeya Dwivedi * __ptr_set_bit - Set bit in a pointer's value 243cb0f8003SKumar Kartikeya Dwivedi * @nr: the bit to set 244cb0f8003SKumar Kartikeya Dwivedi * @addr: the address of the pointer variable 245cb0f8003SKumar Kartikeya Dwivedi * 246cb0f8003SKumar Kartikeya Dwivedi * Example: 247cb0f8003SKumar Kartikeya Dwivedi * void *p = foo(); 248cb0f8003SKumar Kartikeya Dwivedi * __ptr_set_bit(bit, &p); 249cb0f8003SKumar Kartikeya Dwivedi */ 250cb0f8003SKumar Kartikeya Dwivedi #define __ptr_set_bit(nr, addr) \ 251cb0f8003SKumar Kartikeya Dwivedi ({ \ 252cb0f8003SKumar Kartikeya Dwivedi typecheck_pointer(*(addr)); \ 253cb0f8003SKumar Kartikeya Dwivedi __set_bit(nr, (unsigned long *)(addr)); \ 254cb0f8003SKumar Kartikeya Dwivedi }) 255cb0f8003SKumar Kartikeya Dwivedi 256cb0f8003SKumar Kartikeya Dwivedi /** 257cb0f8003SKumar Kartikeya Dwivedi * __ptr_clear_bit - Clear bit in a pointer's value 258cb0f8003SKumar Kartikeya Dwivedi * @nr: the bit to clear 259cb0f8003SKumar Kartikeya Dwivedi * @addr: the address of the pointer variable 260cb0f8003SKumar Kartikeya Dwivedi * 261cb0f8003SKumar Kartikeya Dwivedi * Example: 262cb0f8003SKumar Kartikeya Dwivedi * void *p = foo(); 263cb0f8003SKumar Kartikeya Dwivedi * __ptr_clear_bit(bit, &p); 264cb0f8003SKumar Kartikeya Dwivedi */ 265cb0f8003SKumar Kartikeya Dwivedi #define __ptr_clear_bit(nr, addr) \ 266cb0f8003SKumar Kartikeya Dwivedi ({ \ 267cb0f8003SKumar Kartikeya Dwivedi typecheck_pointer(*(addr)); \ 268cb0f8003SKumar Kartikeya Dwivedi __clear_bit(nr, (unsigned long *)(addr)); \ 269cb0f8003SKumar Kartikeya Dwivedi }) 270cb0f8003SKumar Kartikeya Dwivedi 271cb0f8003SKumar Kartikeya Dwivedi /** 272cb0f8003SKumar Kartikeya Dwivedi * __ptr_test_bit - Test bit in a pointer's value 273cb0f8003SKumar Kartikeya Dwivedi * @nr: the bit to test 274cb0f8003SKumar Kartikeya Dwivedi * @addr: the address of the pointer variable 275cb0f8003SKumar Kartikeya Dwivedi * 276cb0f8003SKumar Kartikeya Dwivedi * Example: 277cb0f8003SKumar Kartikeya Dwivedi * void *p = foo(); 278cb0f8003SKumar Kartikeya Dwivedi * if (__ptr_test_bit(bit, &p)) { 279cb0f8003SKumar Kartikeya Dwivedi * ... 280cb0f8003SKumar Kartikeya Dwivedi * } else { 281cb0f8003SKumar Kartikeya Dwivedi * ... 282cb0f8003SKumar Kartikeya Dwivedi * } 283cb0f8003SKumar Kartikeya Dwivedi */ 284cb0f8003SKumar Kartikeya Dwivedi #define __ptr_test_bit(nr, addr) \ 285cb0f8003SKumar Kartikeya Dwivedi ({ \ 286cb0f8003SKumar Kartikeya Dwivedi typecheck_pointer(*(addr)); \ 287cb0f8003SKumar Kartikeya Dwivedi test_bit(nr, (unsigned long *)(addr)); \ 288cb0f8003SKumar Kartikeya Dwivedi }) 289cb0f8003SKumar Kartikeya Dwivedi 29064970b68SAlexander van Heukelum #ifdef __KERNEL__ 29177b9bd9cSAlexander van Heukelum 29200a1a053STheodore Ts'o #ifndef set_mask_bits 29318127429SMiklos Szeredi #define set_mask_bits(ptr, mask, bits) \ 29400a1a053STheodore Ts'o ({ \ 29518127429SMiklos Szeredi const typeof(*(ptr)) mask__ = (mask), bits__ = (bits); \ 29618127429SMiklos Szeredi typeof(*(ptr)) old__, new__; \ 29700a1a053STheodore Ts'o \ 29800a1a053STheodore Ts'o do { \ 29918127429SMiklos Szeredi old__ = READ_ONCE(*(ptr)); \ 30018127429SMiklos Szeredi new__ = (old__ & ~mask__) | bits__; \ 30118127429SMiklos Szeredi } while (cmpxchg(ptr, old__, new__) != old__); \ 30200a1a053STheodore Ts'o \ 3031db604f6SVineet Gupta old__; \ 30400a1a053STheodore Ts'o }) 30500a1a053STheodore Ts'o #endif 30600a1a053STheodore Ts'o 30785ad1d13SGuoqing Jiang #ifndef bit_clear_unless 308edfa8728SMiklos Szeredi #define bit_clear_unless(ptr, clear, test) \ 30985ad1d13SGuoqing Jiang ({ \ 310edfa8728SMiklos Szeredi const typeof(*(ptr)) clear__ = (clear), test__ = (test);\ 311edfa8728SMiklos Szeredi typeof(*(ptr)) old__, new__; \ 31285ad1d13SGuoqing Jiang \ 31385ad1d13SGuoqing Jiang do { \ 314edfa8728SMiklos Szeredi old__ = READ_ONCE(*(ptr)); \ 315edfa8728SMiklos Szeredi new__ = old__ & ~clear__; \ 316edfa8728SMiklos Szeredi } while (!(old__ & test__) && \ 317edfa8728SMiklos Szeredi cmpxchg(ptr, old__, new__) != old__); \ 31885ad1d13SGuoqing Jiang \ 319edfa8728SMiklos Szeredi !(old__ & test__); \ 32085ad1d13SGuoqing Jiang }) 32185ad1d13SGuoqing Jiang #endif 32285ad1d13SGuoqing Jiang 32364970b68SAlexander van Heukelum #endif /* __KERNEL__ */ 3241da177e4SLinus Torvalds #endif 325