]>
Commit | Line | Data |
---|---|---|
ba4aa02b ACM |
1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef __LINUX_BITS_H | |
3 | #define __LINUX_BITS_H | |
b6589117 ACM |
4 | |
5 | #include <linux/const.h> | |
e3698b23 | 6 | #include <vdso/bits.h> |
450f941e | 7 | #include <uapi/linux/bits.h> |
ba4aa02b ACM |
8 | #include <asm/bitsperlong.h> |
9 | ||
b6589117 | 10 | #define BIT_MASK(nr) (UL(1) << ((nr) % BITS_PER_LONG)) |
ba4aa02b | 11 | #define BIT_WORD(nr) ((nr) / BITS_PER_LONG) |
b6589117 | 12 | #define BIT_ULL_MASK(nr) (ULL(1) << ((nr) % BITS_PER_LONG_LONG)) |
ba4aa02b ACM |
13 | #define BIT_ULL_WORD(nr) ((nr) / BITS_PER_LONG_LONG) |
14 | #define BITS_PER_BYTE 8 | |
fc920999 | 15 | #define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE) |
ba4aa02b ACM |
16 | |
17 | /* | |
18 | * Create a contiguous bitmask starting at bit position @l and ending at | |
19 | * position @h. For example | |
20 | * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000. | |
21 | */ | |
6ec4476a | 22 | #if !defined(__ASSEMBLY__) |
fc920999 ACM |
23 | |
24 | /* | |
25 | * Missing asm support | |
26 | * | |
27 | * GENMASK_U*() and BIT_U*() depend on BITS_PER_TYPE() which relies on sizeof(), | |
28 | * something not available in asm. Nevertheless, fixed width integers is a C | |
29 | * concept. Assembly code can rely on the long and long long versions instead. | |
30 | */ | |
31 | ||
e3698b23 | 32 | #include <linux/build_bug.h> |
e48b92f9 | 33 | #include <linux/compiler.h> |
fc920999 ACM |
34 | #include <linux/overflow.h> |
35 | ||
e48b92f9 | 36 | #define GENMASK_INPUT_CHECK(h, l) BUILD_BUG_ON_ZERO(const_true((l) > (h))) |
fc920999 ACM |
37 | |
38 | /* | |
39 | * Generate a mask for the specified type @t. Additional checks are made to | |
40 | * guarantee the value returned fits in that type, relying on | |
41 | * -Wshift-count-overflow compiler check to detect incompatible arguments. | |
42 | * For example, all these create build errors or warnings: | |
43 | * | |
44 | * - GENMASK(15, 20): wrong argument order | |
45 | * - GENMASK(72, 15): doesn't fit unsigned long | |
46 | * - GENMASK_U32(33, 15): doesn't fit in a u32 | |
47 | */ | |
48 | #define GENMASK_TYPE(t, h, l) \ | |
49 | ((t)(GENMASK_INPUT_CHECK(h, l) + \ | |
50 | (type_max(t) << (l) & \ | |
51 | type_max(t) >> (BITS_PER_TYPE(t) - 1 - (h))))) | |
52 | ||
53 | #define GENMASK_U8(h, l) GENMASK_TYPE(u8, h, l) | |
54 | #define GENMASK_U16(h, l) GENMASK_TYPE(u16, h, l) | |
55 | #define GENMASK_U32(h, l) GENMASK_TYPE(u32, h, l) | |
56 | #define GENMASK_U64(h, l) GENMASK_TYPE(u64, h, l) | |
57 | ||
58 | /* | |
59 | * Fixed-type variants of BIT(), with additional checks like GENMASK_TYPE(). The | |
60 | * following examples generate compiler warnings due to -Wshift-count-overflow: | |
61 | * | |
62 | * - BIT_U8(8) | |
63 | * - BIT_U32(-1) | |
64 | * - BIT_U32(40) | |
65 | */ | |
66 | #define BIT_INPUT_CHECK(type, nr) \ | |
67 | BUILD_BUG_ON_ZERO(const_true((nr) >= BITS_PER_TYPE(type))) | |
68 | ||
69 | #define BIT_TYPE(type, nr) ((type)(BIT_INPUT_CHECK(type, nr) + BIT_ULL(nr))) | |
70 | ||
71 | #define BIT_U8(nr) BIT_TYPE(u8, nr) | |
72 | #define BIT_U16(nr) BIT_TYPE(u16, nr) | |
73 | #define BIT_U32(nr) BIT_TYPE(u32, nr) | |
74 | #define BIT_U64(nr) BIT_TYPE(u64, nr) | |
75 | ||
76 | #else /* defined(__ASSEMBLY__) */ | |
77 | ||
e3698b23 ACM |
78 | /* |
79 | * BUILD_BUG_ON_ZERO is not available in h files included from asm files, | |
80 | * disable the input check if that is the case. | |
81 | */ | |
82 | #define GENMASK_INPUT_CHECK(h, l) 0 | |
fc920999 ACM |
83 | |
84 | #endif /* !defined(__ASSEMBLY__) */ | |
e3698b23 | 85 | |
e3698b23 ACM |
86 | #define GENMASK(h, l) \ |
87 | (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l)) | |
e3698b23 ACM |
88 | #define GENMASK_ULL(h, l) \ |
89 | (GENMASK_INPUT_CHECK(h, l) + __GENMASK_ULL(h, l)) | |
ba4aa02b | 90 | |
21a3a3d0 ACM |
91 | #if !defined(__ASSEMBLY__) |
92 | /* | |
93 | * Missing asm support | |
94 | * | |
95 | * __GENMASK_U128() depends on _BIT128() which would not work | |
0312e94a | 96 | * in the asm code, as it shifts an 'unsigned __int128' data |
21a3a3d0 ACM |
97 | * type instead of direct representation of 128 bit constants |
98 | * such as long and unsigned long. The fundamental problem is | |
99 | * that a 128 bit constant will get silently truncated by the | |
100 | * gcc compiler. | |
101 | */ | |
102 | #define GENMASK_U128(h, l) \ | |
103 | (GENMASK_INPUT_CHECK(h, l) + __GENMASK_U128(h, l)) | |
104 | #endif | |
105 | ||
ba4aa02b | 106 | #endif /* __LINUX_BITS_H */ |