L4Re Operating System Framework – Interface and Usage Documentation
Loading...
Searching...
No Matches
bitfield
1// vi:set ft=cpp: -*- Mode: C++ -*-
2/*
3 * (c) 2012 Alexander Warg <warg@os.inf.tu-dresden.de>,
4 * economic rights: Technische Universität Dresden (Germany)
5 *
6 * This file is part of TUD:OS and distributed under the terms of the
7 * GNU General Public License 2.
8 * Please see the COPYING-GPL-2 file for details.
9 *
10 * As a special exception, you may use this file as part of a free software
11 * library without restriction. Specifically, if other files instantiate
12 * templates or use macros or inline functions from this file, or you compile
13 * this file and link it with other files to produce an executable, this
14 * file does not by itself cause the resulting executable to be covered by
15 * the GNU General Public License. This exception does not however
16 * invalidate any other reasons why the executable file might be covered by
17 * the GNU General Public License.
18 */
19
20#pragma once
21
22#include "type_list"
23
25namespace cxx {
26
34template<typename T, unsigned LSB, unsigned MSB>
36{
37private:
38 static_assert(MSB >= LSB, "boundary mismatch in bit-field definition");
39 static_assert(MSB < sizeof(T) * 8, "MSB outside of bit-field type");
40 static_assert(LSB < sizeof(T) * 8, "LSB outside of bit-field type");
41
47 template<unsigned BITS> struct Best_type
48 {
49 template< typename TY > struct Cmp { enum { value = (BITS <= sizeof(TY)*8) }; };
50 typedef cxx::type_list<
51 unsigned char,
52 unsigned short,
53 unsigned int,
54 unsigned long,
55 unsigned long long
56 > Unsigned_types;
57 typedef cxx::find_type_t<Unsigned_types, Cmp> Type;
58 };
59
60public:
61 enum
62 {
63 Bits = MSB + 1 - LSB,
64 Lsb = LSB,
65 Msb = MSB,
66 };
67
69 enum Masks : T
70 {
72 Low_mask = ((T)~0ULL) >> (sizeof(T)*8 - Bits),
75 };
76
83 typedef typename Best_type<Bits>::Type Bits_type;
84
91 typedef typename Best_type<Bits + Lsb>::Type Shift_type;
92
93private:
94 static_assert(sizeof(Bits_type)*8 >= Bits, "error finding the type to store the bits");
95 static_assert(sizeof(Shift_type)*8 >= Bits + Lsb, "error finding the type to keep the shifted bits");
96 static_assert(sizeof(Bits_type) <= sizeof(T), "size mismatch for Bits_type");
97 static_assert(sizeof(Shift_type) <= sizeof(T), "size mismatch for Shift_type");
98 static_assert(sizeof(Bits_type) <= sizeof(Shift_type), "size mismacht for Shift_type and Bits_type");
99
100public:
109 { return (val >> Lsb) & Low_mask; }
110
122 { return val & Mask; }
123
136 static T set_dirty(T dest, Shift_type val)
137 {
138 //assert (!(val & ~Low_mask));
139 return (dest & ~Mask) | (val << Lsb);
140 }
141
157 {
158 //assert (!(val & ~Mask));
159 return (dest & ~Mask) | val;
160 }
161
170 static T set(T dest, Bits_type val)
171 { return set_dirty(dest, val & Low_mask); }
172
182 static T set_unshifted(T dest, Shift_type val)
183 { return set_unshifted_dirty(dest, val & Mask); }
184
196 static T val_dirty(Shift_type val) { return val << Lsb; }
197
205 static T val(Bits_type val) { return val_dirty(val & Low_mask); }
206
215 static T val_unshifted(Shift_type val) { return val & Mask; }
216
218 template< typename TT >
220 {
221 private:
222 TT v;
223
224 public:
225 Value_base(TT t) : v(t) {}
226 Bits_type get() const { return Bitfield::get(v); }
227 T get_unshifted() const { return Bitfield::get_unshifted(v); }
228
229 void set(Bits_type val) { v = Bitfield::set(v, val); }
230 void set_dirty(Bits_type val) { v = Bitfield::set_dirty(v, val); }
231 void set_unshifted(Shift_type val) { v = Bitfield::set_unshifted(v, val); }
232 void set_unshifted_dirty(Shift_type val) { v = Bitfield::set_unshifted_dirty(v, val); }
233 };
234
236 template< typename TT >
237 class Value : public Value_base<TT>
238 {
239 public:
240 Value(TT t) : Value_base<TT>(t) {}
241 operator Bits_type () const { return this->get(); }
242 Value &operator = (Bits_type val) { this->set(val); return *this; }
243 Value &operator = (Value const &o) { this->set(o.get()); return *this; }
244 // This copy constructor initializes more bits than necessary but this is
245 // usually not a problem.
246 Value (Value const &o) = default;
247 };
248
250 template< typename TT >
251 class Value_unshifted : public Value_base<TT>
252 {
253 public:
254 Value_unshifted(TT t) : Value_base<TT>(t) {}
255 operator Shift_type () const { return this->get_unshifted(); }
256 Value_unshifted &operator = (Shift_type val) { this->set_unshifted(val); return *this; }
257 Value_unshifted &operator = (Value_unshifted const &o)
258 {
259 this->set_unshifted(o.get_unshifted());
260 return *this;
261 }
262 // This copy constructor initializes more bits than necessary but this is
263 // usually not a problem.
264 Value_unshifted(Value_unshifted const &) = default;
265 };
266
268 typedef Value<T&> Ref;
271
276};
277
278#define CXX_BITFIELD_MEMBER(LSB, MSB, name, data_member) \
279 \
280 \
281 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
282 \
283 typename name ## _bfm_t::Val name() const { return data_member; } \
284 \
285 typename name ## _bfm_t::Ref name() { return data_member; } \
286
288#define CXX_BITFIELD_MEMBER_RO(LSB, MSB, name, data_member) \
289 \
290 \
291 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
292 \
293 typename name ## _bfm_t::Val name() const { return data_member; } \
294
296#define CXX_BITFIELD_MEMBER_UNSHIFTED(LSB, MSB, name, data_member) \
297 \
298 \
299 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
300 \
301 typename name ## _bfm_t::Val_unshifted name() const { return data_member; } \
302 \
303 typename name ## _bfm_t::Ref_unshifted name() { return data_member; } \
304
306#define CXX_BITFIELD_MEMBER_UNSHIFTED_RO(LSB, MSB, name, data_member) \
307 \
308 \
309 typedef cxx::Bitfield<decltype(data_member), LSB, MSB> name ## _bfm_t; \
310 \
311 typename name ## _bfm_t::Val_unshifted name() const { return data_member; } \
312
313}
Internal helper type.
Definition bitfield:220
Internal helper type.
Definition bitfield:252
Internal helper type.
Definition bitfield:238
Definition for a member (part) of a bit field.
Definition bitfield:36
static T set(T dest, Bits_type val)
Set the bits corresponding to val.
Definition bitfield:170
Value_unshifted< T const > Val_unshifted
Value type to access the bits inside a raw bit field (in place).
Definition bitfield:275
static T val(Bits_type val)
Get the shifted bits for val.
Definition bitfield:205
static Bits_type get(Shift_type val)
Get the bits out of val.
Definition bitfield:108
Value_unshifted< T & > Ref_unshifted
Reference type to access the bits inside a raw bit field (in place).
Definition bitfield:273
static T set_dirty(T dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:136
Best_type< Bits+Lsb >::Type Shift_type
Type to hold at least Bits + Lsb bits.
Definition bitfield:91
static T val_dirty(Shift_type val)
Get the shifted bits for val.
Definition bitfield:196
Masks
Masks for bitswise operation on internal parts of a bitfield.
Definition bitfield:70
@ Low_mask
Mask value to get Bits bits.
Definition bitfield:72
@ Mask
Mask value to the bits out of a T.
Definition bitfield:74
@ Msb
index of the MSB
Definition bitfield:65
@ Bits
Number of bits.
Definition bitfield:63
@ Lsb
index of the LSB
Definition bitfield:64
Value< T const > Val
Value type to access the bits inside a raw bit field.
Definition bitfield:270
static T val_unshifted(Shift_type val)
Get the shifted bits for val.
Definition bitfield:215
Value< T & > Ref
Reference type to access the bits inside a raw bit field.
Definition bitfield:268
Best_type< Bits >::Type Bits_type
Type to hold at least Bits bits.
Definition bitfield:83
static T set_unshifted_dirty(T dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:156
static T set_unshifted(T dest, Shift_type val)
Set the bits corresponding to val.
Definition bitfield:182
static T get_unshifted(Shift_type val)
Get the bits in place out of val.
Definition bitfield:121
Our C++ library.
Definition arith:22