|
41 | 41 |
|
42 | 42 | #define __bf_shf(x) (__builtin_ffsll(x) - 1)
|
43 | 43 |
|
| 44 | +#define __scalar_type_to_unsigned_cases(type) \ |
| 45 | + unsigned type: (unsigned type)0, \ |
| 46 | + signed type: (unsigned type)0 |
| 47 | + |
| 48 | +#define __unsigned_scalar_typeof(x) typeof( \ |
| 49 | + _Generic((x), \ |
| 50 | + char: (unsigned char)0, \ |
| 51 | + __scalar_type_to_unsigned_cases(char), \ |
| 52 | + __scalar_type_to_unsigned_cases(short), \ |
| 53 | + __scalar_type_to_unsigned_cases(int), \ |
| 54 | + __scalar_type_to_unsigned_cases(long), \ |
| 55 | + __scalar_type_to_unsigned_cases(long long), \ |
| 56 | + default: (x))) |
| 57 | + |
| 58 | +#define __bf_cast_unsigned(type, x) ((__unsigned_scalar_typeof(type))(x)) |
| 59 | + |
44 | 60 | #define __BF_FIELD_CHECK(_mask, _reg, _val, _pfx) \
|
45 | 61 | ({ \
|
46 | 62 | BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask), \
|
|
49 | 65 | BUILD_BUG_ON_MSG(__builtin_constant_p(_val) ? \
|
50 | 66 | ~((_mask) >> __bf_shf(_mask)) & (_val) : 0, \
|
51 | 67 | _pfx "value too large for the field"); \
|
52 |
| - BUILD_BUG_ON_MSG((_mask) > (typeof(_reg))~0ull, \ |
| 68 | + BUILD_BUG_ON_MSG(__bf_cast_unsigned(_mask, _mask) > \ |
| 69 | + __bf_cast_unsigned(_reg, ~0ull), \ |
53 | 70 | _pfx "type of reg too small for mask"); \
|
54 | 71 | __BUILD_BUG_ON_NOT_POWER_OF_2((_mask) + \
|
55 | 72 | (1ULL << __bf_shf(_mask))); \
|
|
0 commit comments