tsdl182gen.py: remove unused `jinja2` import
[deliverable/barectf.git] / barectf / templates / bitfield.h.j2
CommitLineData
a8731bda
PP
1{% import 'common.j2' as common %}
2{% set prefix = common.prefix %}
3{% set ucprefix = common.ucprefix %}
75bae33c
PP
4#ifndef _{{ ucprefix }}BITFIELD_H
5#define _{{ ucprefix }}BITFIELD_H
6
7/*
8 * BabelTrace
9 *
10 * Bitfields read/write functions.
11 *
12 * Copyright (c) 2010-2020 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining
15 * a copy of this software and associated documentation files (the
16 * "Software"), to deal in the Software without restriction, including
17 * without limitation the rights to use, copy, modify, merge, publish,
18 * distribute, sublicense, and/or sell copies of the Software, and to
19 * permit persons to whom the Software is furnished to do so, subject to
20 * the following conditions:
21 *
22 * The above copyright notice and this permission notice shall be
23 * included in all copies or substantial portions of the Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */
34
35#include <limits.h>
36
37#ifdef __cplusplus
a0b64802 38# define {{ ucprefix }}CAST_PTR(_type, _value) \
75bae33c
PP
39 static_cast<_type>(static_cast<void *>(_value))
40#else
a0b64802 41# define {{ ucprefix }}CAST_PTR(_type, _value) ((void *) (_value))
75bae33c
PP
42#endif
43
44{% set def_bo = cfg.trace.type.default_byte_order %}
45{% set def_bo_str = 'LITTLE_ENDIAN' if def_bo == barectf_config.ByteOrder.LITTLE_ENDIAN else 'BIG_ENDIAN' %}
46#define {{ ucprefix }}BYTE_ORDER {{ def_bo_str }}
47
48
49/* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
50#define _{{ prefix }}bt_piecewise_rshift(_vtype, _v, _shift) \
51do { \
52 unsigned long ___shift = (_shift); \
53 unsigned long sb = (___shift) / (sizeof(_v) * CHAR_BIT - 1); \
54 unsigned long final = (___shift) % (sizeof(_v) * CHAR_BIT - 1); \
55 \
56 for (; sb; sb--) \
57 _v >>= sizeof(_v) * CHAR_BIT - 1; \
58 _v >>= final; \
59} while (0)
60
61/*
62 * {{ prefix }}bt_bitfield_write - write integer to a bitfield in native endianness
63 *
64 * Save integer to the bitfield, which starts at the "start" bit, has "len"
65 * bits.
66 * The inside of a bitfield is from high bits to low bits.
67 * Uses native endianness.
68 * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
69 * For signed "v", sign-extend v if bitfield is larger than v.
70 *
71 * On little endian, bytes are placed from the less significant to the most
72 * significant. Also, consecutive bitfields are placed from lower bits to higher
73 * bits.
74 *
75 * On big endian, bytes are places from most significant to less significant.
76 * Also, consecutive bitfields are placed from higher to lower bits.
77 */
78
79#define _{{ prefix }}bt_bitfield_write_le(_ptr, type, _start, _length, _vtype, _v) \
80do { \
81 _vtype __v = (_v); \
a0b64802 82 type *__ptr = {{ ucprefix }}CAST_PTR(type *, _ptr); \
75bae33c
PP
83 unsigned long __start = (_start), __length = (_length); \
84 type mask, cmask; \
85 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \
86 unsigned long start_unit, end_unit, this_unit; \
87 unsigned long end, cshift; /* cshift is "complement shift" */ \
88 \
89 if (!__length) \
90 break; \
91 \
92 end = __start + __length; \
93 start_unit = __start / ts; \
94 end_unit = (end + (ts - 1)) / ts; \
95 \
96 /* Trim v high bits */ \
97 if (__length < sizeof(__v) * CHAR_BIT) \
98 __v &= ~((~(_vtype) 0) << __length); \
99 \
100 /* We can now append v with a simple "or", shift it piece-wise */ \
101 this_unit = start_unit; \
102 if (start_unit == end_unit - 1) { \
103 mask = ~((~(type) 0) << (__start % ts)); \
104 if (end % ts) \
105 mask |= (~(type) 0) << (end % ts); \
106 cmask = (type) __v << (__start % ts); \
107 cmask &= ~mask; \
108 __ptr[this_unit] &= mask; \
109 __ptr[this_unit] |= cmask; \
110 break; \
111 } \
112 if (__start % ts) { \
113 cshift = __start % ts; \
114 mask = ~((~(type) 0) << cshift); \
115 cmask = (type) __v << cshift; \
116 cmask &= ~mask; \
117 __ptr[this_unit] &= mask; \
118 __ptr[this_unit] |= cmask; \
119 _{{ prefix }}bt_piecewise_rshift(_vtype, __v, ts - cshift); \
120 __start += ts - cshift; \
121 this_unit++; \
122 } \
123 for (; this_unit < end_unit - 1; this_unit++) { \
124 __ptr[this_unit] = (type) __v; \
125 _{{ prefix }}bt_piecewise_rshift(_vtype, __v, ts); \
126 __start += ts; \
127 } \
128 if (end % ts) { \
129 mask = (~(type) 0) << (end % ts); \
130 cmask = (type) __v; \
131 cmask &= ~mask; \
132 __ptr[this_unit] &= mask; \
133 __ptr[this_unit] |= cmask; \
134 } else \
135 __ptr[this_unit] = (type) __v; \
136} while (0)
137
138#define _{{ prefix }}bt_bitfield_write_be(_ptr, type, _start, _length, _vtype, _v) \
139do { \
140 _vtype __v = (_v); \
a0b64802 141 type *__ptr = {{ ucprefix }}CAST_PTR(type *, _ptr); \
75bae33c
PP
142 unsigned long __start = (_start), __length = (_length); \
143 type mask, cmask; \
144 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \
145 unsigned long start_unit, end_unit, this_unit; \
146 unsigned long end, cshift; /* cshift is "complement shift" */ \
147 \
148 if (!__length) \
149 break; \
150 \
151 end = __start + __length; \
152 start_unit = __start / ts; \
153 end_unit = (end + (ts - 1)) / ts; \
154 \
155 /* Trim v high bits */ \
156 if (__length < sizeof(__v) * CHAR_BIT) \
157 __v &= ~((~(_vtype) 0) << __length); \
158 \
159 /* We can now append v with a simple "or", shift it piece-wise */ \
160 this_unit = end_unit - 1; \
161 if (start_unit == end_unit - 1) { \
162 mask = ~((~(type) 0) << ((ts - (end % ts)) % ts)); \
163 if (__start % ts) \
164 mask |= (~((type) 0)) << (ts - (__start % ts)); \
165 cmask = (type) __v << ((ts - (end % ts)) % ts); \
166 cmask &= ~mask; \
167 __ptr[this_unit] &= mask; \
168 __ptr[this_unit] |= cmask; \
169 break; \
170 } \
171 if (end % ts) { \
172 cshift = end % ts; \
173 mask = ~((~(type) 0) << (ts - cshift)); \
174 cmask = (type) __v << (ts - cshift); \
175 cmask &= ~mask; \
176 __ptr[this_unit] &= mask; \
177 __ptr[this_unit] |= cmask; \
178 _{{ prefix }}bt_piecewise_rshift(_vtype, __v, cshift); \
179 end -= cshift; \
180 this_unit--; \
181 } \
182 for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \
183 __ptr[this_unit] = (type) __v; \
184 _{{ prefix }}bt_piecewise_rshift(_vtype, __v, ts); \
185 end -= ts; \
186 } \
187 if (__start % ts) { \
188 mask = (~(type) 0) << (ts - (__start % ts)); \
189 cmask = (type) __v; \
190 cmask &= ~mask; \
191 __ptr[this_unit] &= mask; \
192 __ptr[this_unit] |= cmask; \
193 } else \
194 __ptr[this_unit] = (type) __v; \
195} while (0)
196
197/*
198 * {{ prefix }}bt_bitfield_write_le - write integer to a bitfield in little endian
199 * {{ prefix }}bt_bitfield_write_be - write integer to a bitfield in big endian
200 */
201
202#if ({{ ucprefix }}BYTE_ORDER == LITTLE_ENDIAN)
203
204#define {{ prefix }}bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \
205 _{{ prefix }}bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v)
206
207#define {{ prefix }}bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \
208 _{{ prefix }}bt_bitfield_write_be(ptr, unsigned char, _start, _length, _vtype, _v)
209
210#elif ({{ ucprefix }}BYTE_ORDER == BIG_ENDIAN)
211
212#define {{ prefix }}bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \
213 _{{ prefix }}bt_bitfield_write_le(ptr, unsigned char, _start, _length, _vtype, _v)
214
215#define {{ prefix }}bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \
216 _{{ prefix }}bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v)
217
218#else /* ({{ ucprefix }}BYTE_ORDER == PDP_ENDIAN) */
219
220#error "Byte order not supported"
221
222#endif
223
224#endif /* _{{ ucprefix }}BITFIELD_H */
This page took 0.030318 seconds and 4 git commands to generate.