|
16 | 16 | #define _LINUX_BITFIELD_H
|
17 | 17 |
|
18 | 18 | #include <linux/build_bug.h>
|
| 19 | +#include <asm/byteorder.h> |
19 | 20 |
|
20 | 21 | /*
|
21 | 22 | * Bitfield access macros
|
|
103 | 104 | (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
|
104 | 105 | })
|
105 | 106 |
|
| 107 | +extern void __compiletime_warning("value doesn't fit into mask") |
| 108 | +__field_overflow(void); |
| 109 | +extern void __compiletime_error("bad bitfield mask") |
| 110 | +__bad_mask(void); |
| 111 | +static __always_inline u64 field_multiplier(u64 field) |
| 112 | +{ |
| 113 | + if ((field | (field - 1)) & ((field | (field - 1)) + 1)) |
| 114 | + __bad_mask(); |
| 115 | + return field & -field; |
| 116 | +} |
| 117 | +static __always_inline u64 field_mask(u64 field) |
| 118 | +{ |
| 119 | + return field / field_multiplier(field); |
| 120 | +} |
| 121 | +#define ____MAKE_OP(type,base,to,from) \ |
| 122 | +static __always_inline __##type type##_encode_bits(base v, base field) \ |
| 123 | +{ \ |
| 124 | + if (__builtin_constant_p(v) && (v & ~field_multiplier(field))) \ |
| 125 | + __field_overflow(); \ |
| 126 | + return to((v & field_mask(field)) * field_multiplier(field)); \ |
| 127 | +} \ |
| 128 | +static __always_inline __##type type##_replace_bits(__##type old, \ |
| 129 | + base val, base field) \ |
| 130 | +{ \ |
| 131 | + return (old & ~to(field)) | type##_encode_bits(val, field); \ |
| 132 | +} \ |
| 133 | +static __always_inline void type##p_replace_bits(__##type *p, \ |
| 134 | + base val, base field) \ |
| 135 | +{ \ |
| 136 | + *p = (*p & ~to(field)) | type##_encode_bits(val, field); \ |
| 137 | +} \ |
| 138 | +static __always_inline base type##_get_bits(__##type v, base field) \ |
| 139 | +{ \ |
| 140 | + return (from(v) & field)/field_multiplier(field); \ |
| 141 | +} |
| 142 | +#define __MAKE_OP(size) \ |
| 143 | + ____MAKE_OP(le##size,u##size,cpu_to_le##size,le##size##_to_cpu) \ |
| 144 | + ____MAKE_OP(be##size,u##size,cpu_to_be##size,be##size##_to_cpu) \ |
| 145 | + ____MAKE_OP(u##size,u##size,,) |
| 146 | +__MAKE_OP(16) |
| 147 | +__MAKE_OP(32) |
| 148 | +__MAKE_OP(64) |
| 149 | +#undef __MAKE_OP |
| 150 | +#undef ____MAKE_OP |
| 151 | + |
106 | 152 | #endif
|
0 commit comments