aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/bitfield.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/bitfield.h')
-rw-r--r--include/linux/bitfield.h46
1 files changed, 46 insertions, 0 deletions
diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h
index 1030651f8309..cf2588d81148 100644
--- a/include/linux/bitfield.h
+++ b/include/linux/bitfield.h
@@ -16,6 +16,7 @@
16#define _LINUX_BITFIELD_H 16#define _LINUX_BITFIELD_H
17 17
18#include <linux/build_bug.h> 18#include <linux/build_bug.h>
19#include <asm/byteorder.h>
19 20
20/* 21/*
21 * Bitfield access macros 22 * Bitfield access macros
@@ -103,4 +104,49 @@
103 (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \ 104 (typeof(_mask))(((_reg) & (_mask)) >> __bf_shf(_mask)); \
104 }) 105 })
105 106
107extern void __compiletime_warning("value doesn't fit into mask")
108__field_overflow(void);
109extern void __compiletime_error("bad bitfield mask")
110__bad_mask(void);
111static __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}
117static __always_inline u64 field_mask(u64 field)
118{
119 return field / field_multiplier(field);
120}
121#define ____MAKE_OP(type,base,to,from) \
122static __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} \
128static __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} \
133static __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} \
138static __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#endif 152#endif