2 # The MIT License (MIT)
4 # Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
6 # Permission is hereby granted, free of charge, to any person obtaining
7 # a copy of this software and associated documentation files (the
8 # "Software"), to deal in the Software without restriction, including
9 # without limitation the rights to use, copy, modify, merge, publish,
10 # distribute, sublicense, and/or sell copies of the Software, and to
11 # permit persons to whom the Software is furnished to do so, subject to
12 # the following conditions:
14 # The above copyright notice and this permission notice shall be
15 # included in all copies or substantial portions of the Software.
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
21 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 {% import 'common.j2' as common %}
26 {% set prefix = common.prefix %}
27 {% set ucprefix = common.ucprefix %}
28 #ifndef _{{ ucprefix }}BITFIELD_H
29 #define _{{ ucprefix }}BITFIELD_H
34 * Bitfields read/write functions.
36 * Copyright (c) 2010-2020 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
38 * Permission is hereby granted, free of charge, to any person obtaining
39 * a copy of this software and associated documentation files (the
40 * "Software"), to deal in the Software without restriction, including
41 * without limitation the rights to use, copy, modify, merge, publish,
42 * distribute, sublicense, and/or sell copies of the Software, and to
43 * permit persons to whom the Software is furnished to do so, subject to
44 * the following conditions:
46 * The above copyright notice and this permission notice shall be
47 * included in all copies or substantial portions of the Software.
49 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
50 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
51 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
52 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
53 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
54 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
55 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
62 # define {{ ucprefix }}CAST_PTR(_type, _value) \
63 static_cast<_type>(static_cast<void *>(_value))
65 # define {{ ucprefix }}CAST_PTR(_type, _value) ((void *) (_value))
68 {% set def_bo = cfg.trace.type.default_byte_order %}
69 {% set def_bo_str = 'LITTLE_ENDIAN' if def_bo == barectf_config.ByteOrder.LITTLE_ENDIAN else 'BIG_ENDIAN' %}
70 #define {{ ucprefix }}BYTE_ORDER {{ def_bo_str }}
73 /* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
74 #define _{{ prefix }}bt_piecewise_rshift(_vtype, _v, _shift) \
76 unsigned long ___shift = (_shift); \
77 unsigned long sb = (___shift) / (sizeof(_v) * CHAR_BIT - 1); \
78 unsigned long final = (___shift) % (sizeof(_v) * CHAR_BIT - 1); \
81 _v >>= sizeof(_v) * CHAR_BIT - 1; \
86 * {{ prefix }}bt_bitfield_write - write integer to a bitfield in native endianness
88 * Save integer to the bitfield, which starts at the "start" bit, has "len"
90 * The inside of a bitfield is from high bits to low bits.
91 * Uses native endianness.
92 * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
93 * For signed "v", sign-extend v if bitfield is larger than v.
95 * On little endian, bytes are placed from the less significant to the most
96 * significant. Also, consecutive bitfields are placed from lower bits to higher
99 * On big endian, bytes are places from most significant to less significant.
100 * Also, consecutive bitfields are placed from higher to lower bits.
103 #define _{{ prefix }}bt_bitfield_write_le(_ptr, type, _start, _length, _vtype, _v) \
106 type *__ptr = {{ ucprefix }}CAST_PTR(type *, _ptr); \
107 unsigned long __start = (_start), __length = (_length); \
109 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \
110 unsigned long start_unit, end_unit, this_unit; \
111 unsigned long end, cshift; /* cshift is "complement shift" */ \
116 end = __start + __length; \
117 start_unit = __start / ts; \
118 end_unit = (end + (ts - 1)) / ts; \
120 /* Trim v high bits */ \
121 if (__length < sizeof(__v) * CHAR_BIT) \
122 __v &= ~((~(_vtype) 0) << __length); \
124 /* We can now append v with a simple "or", shift it piece-wise */ \
125 this_unit = start_unit; \
126 if (start_unit == end_unit - 1) { \
127 mask = ~((~(type) 0) << (__start % ts)); \
129 mask |= (~(type) 0) << (end % ts); \
130 cmask = (type) __v << (__start % ts); \
132 __ptr[this_unit] &= mask; \
133 __ptr[this_unit] |= cmask; \
136 if (__start % ts) { \
137 cshift = __start % ts; \
138 mask = ~((~(type) 0) << cshift); \
139 cmask = (type) __v << cshift; \
141 __ptr[this_unit] &= mask; \
142 __ptr[this_unit] |= cmask; \
143 _{{ prefix }}bt_piecewise_rshift(_vtype, __v, ts - cshift); \
144 __start += ts - cshift; \
147 for (; this_unit < end_unit - 1; this_unit++) { \
148 __ptr[this_unit] = (type) __v; \
149 _{{ prefix }}bt_piecewise_rshift(_vtype, __v, ts); \
153 mask = (~(type) 0) << (end % ts); \
154 cmask = (type) __v; \
156 __ptr[this_unit] &= mask; \
157 __ptr[this_unit] |= cmask; \
159 __ptr[this_unit] = (type) __v; \
162 #define _{{ prefix }}bt_bitfield_write_be(_ptr, type, _start, _length, _vtype, _v) \
165 type *__ptr = {{ ucprefix }}CAST_PTR(type *, _ptr); \
166 unsigned long __start = (_start), __length = (_length); \
168 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \
169 unsigned long start_unit, end_unit, this_unit; \
170 unsigned long end, cshift; /* cshift is "complement shift" */ \
175 end = __start + __length; \
176 start_unit = __start / ts; \
177 end_unit = (end + (ts - 1)) / ts; \
179 /* Trim v high bits */ \
180 if (__length < sizeof(__v) * CHAR_BIT) \
181 __v &= ~((~(_vtype) 0) << __length); \
183 /* We can now append v with a simple "or", shift it piece-wise */ \
184 this_unit = end_unit - 1; \
185 if (start_unit == end_unit - 1) { \
186 mask = ~((~(type) 0) << ((ts - (end % ts)) % ts)); \
188 mask |= (~((type) 0)) << (ts - (__start % ts)); \
189 cmask = (type) __v << ((ts - (end % ts)) % ts); \
191 __ptr[this_unit] &= mask; \
192 __ptr[this_unit] |= cmask; \
197 mask = ~((~(type) 0) << (ts - cshift)); \
198 cmask = (type) __v << (ts - cshift); \
200 __ptr[this_unit] &= mask; \
201 __ptr[this_unit] |= cmask; \
202 _{{ prefix }}bt_piecewise_rshift(_vtype, __v, cshift); \
206 for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \
207 __ptr[this_unit] = (type) __v; \
208 _{{ prefix }}bt_piecewise_rshift(_vtype, __v, ts); \
211 if (__start % ts) { \
212 mask = (~(type) 0) << (ts - (__start % ts)); \
213 cmask = (type) __v; \
215 __ptr[this_unit] &= mask; \
216 __ptr[this_unit] |= cmask; \
218 __ptr[this_unit] = (type) __v; \
222 * {{ prefix }}bt_bitfield_write_le - write integer to a bitfield in little endian
223 * {{ prefix }}bt_bitfield_write_be - write integer to a bitfield in big endian
226 #if ({{ ucprefix }}BYTE_ORDER == LITTLE_ENDIAN)
228 #define {{ prefix }}bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \
229 _{{ prefix }}bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v)
231 #define {{ prefix }}bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \
232 _{{ prefix }}bt_bitfield_write_be(ptr, unsigned char, _start, _length, _vtype, _v)
234 #elif ({{ ucprefix }}BYTE_ORDER == BIG_ENDIAN)
236 #define {{ prefix }}bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \
237 _{{ prefix }}bt_bitfield_write_le(ptr, unsigned char, _start, _length, _vtype, _v)
239 #define {{ prefix }}bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \
240 _{{ prefix }}bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v)
242 #else /* ({{ ucprefix }}BYTE_ORDER == PDP_ENDIAN) */
244 #error "Byte order not supported"
248 #endif /* _{{ ucprefix }}BITFIELD_H */