xref: /linux-6.15/include/linux/bits.h (revision 0312e94a)
18bd9cb51SWill Deacon /* SPDX-License-Identifier: GPL-2.0 */
28bd9cb51SWill Deacon #ifndef __LINUX_BITS_H
38bd9cb51SWill Deacon #define __LINUX_BITS_H
495b980d6SMasahiro Yamada 
595b980d6SMasahiro Yamada #include <linux/const.h>
63945ff37SVincenzo Frascino #include <vdso/bits.h>
73c7a8e19SPaolo Bonzini #include <uapi/linux/bits.h>
88bd9cb51SWill Deacon #include <asm/bitsperlong.h>
98bd9cb51SWill Deacon 
1095b980d6SMasahiro Yamada #define BIT_MASK(nr)		(UL(1) << ((nr) % BITS_PER_LONG))
118bd9cb51SWill Deacon #define BIT_WORD(nr)		((nr) / BITS_PER_LONG)
1295b980d6SMasahiro Yamada #define BIT_ULL_MASK(nr)	(ULL(1) << ((nr) % BITS_PER_LONG_LONG))
138bd9cb51SWill Deacon #define BIT_ULL_WORD(nr)	((nr) / BITS_PER_LONG_LONG)
148bd9cb51SWill Deacon #define BITS_PER_BYTE		8
158bd9cb51SWill Deacon 
168bd9cb51SWill Deacon /*
178bd9cb51SWill Deacon  * Create a contiguous bitmask starting at bit position @l and ending at
188bd9cb51SWill Deacon  * position @h. For example
198bd9cb51SWill Deacon  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
208bd9cb51SWill Deacon  */
216ec4476aSLinus Torvalds #if !defined(__ASSEMBLY__)
22295bcca8SRikard Falkeborn #include <linux/build_bug.h>
234463a445SVincent Mailhol #include <linux/compiler.h>
244463a445SVincent Mailhol #define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(const_true((l) > (h)))
25295bcca8SRikard Falkeborn #else
26295bcca8SRikard Falkeborn /*
27295bcca8SRikard Falkeborn  * BUILD_BUG_ON_ZERO is not available in h files included from asm files,
28295bcca8SRikard Falkeborn  * disable the input check if that is the case.
29295bcca8SRikard Falkeborn  */
30295bcca8SRikard Falkeborn #define GENMASK_INPUT_CHECK(h, l) 0
31295bcca8SRikard Falkeborn #endif
32295bcca8SRikard Falkeborn 
33295bcca8SRikard Falkeborn #define GENMASK(h, l) \
34295bcca8SRikard Falkeborn 	(GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
35295bcca8SRikard Falkeborn #define GENMASK_ULL(h, l) \
36295bcca8SRikard Falkeborn 	(GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l))
378bd9cb51SWill Deacon 
38947697c6SAnshuman Khandual #if !defined(__ASSEMBLY__)
39947697c6SAnshuman Khandual /*
40947697c6SAnshuman Khandual  * Missing asm support
41947697c6SAnshuman Khandual  *
42947697c6SAnshuman Khandual  * __GENMASK_U128() depends on _BIT128() which would not work
43*0312e94aSVincent Mailhol  * in the asm code, as it shifts an 'unsigned __int128' data
44947697c6SAnshuman Khandual  * type instead of direct representation of 128 bit constants
45947697c6SAnshuman Khandual  * such as long and unsigned long. The fundamental problem is
46947697c6SAnshuman Khandual  * that a 128 bit constant will get silently truncated by the
47947697c6SAnshuman Khandual  * gcc compiler.
48947697c6SAnshuman Khandual  */
49947697c6SAnshuman Khandual #define GENMASK_U128(h, l) \
50947697c6SAnshuman Khandual 	(GENMASK_INPUT_CHECK(h, l) + __GENMASK_U128(h, l))
51947697c6SAnshuman Khandual #endif
52947697c6SAnshuman Khandual 
538bd9cb51SWill Deacon #endif	/* __LINUX_BITS_H */
54