Fix: bitfield: shift undefined/implementation defined behaviors
[babeltrace.git] / include / babeltrace / bitfield.h
CommitLineData
d79865b9
MD
1#ifndef _BABELTRACE_BITFIELD_H
2#define _BABELTRACE_BITFIELD_H
6dc2ca62
MD
3
4/*
c15e0603 5 * Copyright 2010-2019 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
6dc2ca62
MD
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
c462e188
MD
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
6dc2ca62
MD
24 */
25
26#include <stdint.h> /* C99 5.2.4.2 Numerical limits */
c15e0603 27#include <babeltrace/compat/limits.h> /* C99 5.2.4.2 Numerical limits */
9b0422a0 28#include <babeltrace/endian.h> /* Non-standard BIG_ENDIAN, LITTLE_ENDIAN, BYTE_ORDER */
6dc2ca62 29
c15e0603
MD
30/*
31 * This header strictly follows the C99 standard, except for use of the
32 * compiler-specific __typeof__.
33 */
34
35/*
36 * This bitfield header requires the compiler representation of signed
37 * integers to be two's complement.
38 */
39#if (-1 != ~0)
40#error "bitfield.h requires the compiler representation of signed integers to be two's complement."
41#endif
08228826 42
cca767be 43#define _bt_is_signed_type(type) ((type) -1 < (type) 0)
08228826 44
c15e0603
MD
45/*
46 * Produce a build-time error if the condition `cond` is non-zero.
47 * Evaluates as a size_t expression.
48 */
49#define _BT_BUILD_ASSERT(cond) \
50 sizeof(struct { int f:(2 * !!(cond) - 1); })
51
52/*
53 * Cast value `v` to an unsigned integer of the same size as `v`.
54 */
55#define _bt_cast_value_to_unsigned(v) \
56 (sizeof(v) == sizeof(uint8_t) ? (uint8_t) (v) : \
57 sizeof(v) == sizeof(uint16_t) ? (uint16_t) (v) : \
58 sizeof(v) == sizeof(uint32_t) ? (uint32_t) (v) : \
59 sizeof(v) == sizeof(uint64_t) ? (uint64_t) (v) : \
60 _BT_BUILD_ASSERT(sizeof(v) <= sizeof(uint64_t)))
61
62/*
63 * Cast value `v` to an unsigned integer type of the size of type `type`
64 * *without* sign-extension.
65 *
66 * The unsigned cast ensures that we're not shifting a negative value,
67 * which is undefined in C. However, this limits the maximum type size
68 * of `type` to 64-bit. Generate a compile-time error if the size of
69 * `type` is larger than 64-bit.
70 */
71#define _bt_cast_value_to_unsigned_type(type, v) \
72 (sizeof(type) == sizeof(uint8_t) ? \
73 (uint8_t) _bt_cast_value_to_unsigned(v) : \
74 sizeof(type) == sizeof(uint16_t) ? \
75 (uint16_t) _bt_cast_value_to_unsigned(v) : \
76 sizeof(type) == sizeof(uint32_t) ? \
77 (uint32_t) _bt_cast_value_to_unsigned(v) : \
78 sizeof(type) == sizeof(uint64_t) ? \
79 (uint64_t) _bt_cast_value_to_unsigned(v) : \
80 _BT_BUILD_ASSERT(sizeof(v) <= sizeof(uint64_t)))
81
82/*
83 * _bt_fill_mask evaluates to a "type" integer with all bits set.
84 */
85#define _bt_fill_mask(type) ((type) ~(type) 0)
86
87/*
88 * Left shift a value `v` of `shift` bits.
89 *
90 * The type of `v` can be signed or unsigned integer.
91 * The value of `shift` must be less than the size of `v` (in bits),
92 * otherwise the behavior is undefined.
93 * Evaluates to the result of the shift operation.
94 *
95 * According to the C99 standard, left shift of a left hand-side signed
96 * type is undefined if it has a negative value or if the result cannot
97 * be represented in the result type. This bitfield header discards the
98 * bits that are left-shifted beyond the result type representation,
99 * which is the behavior of an unsigned type left shift operation.
100 * Therefore, always perform left shift on an unsigned type.
101 *
102 * This macro should not be used if `shift` can be greater or equal than
103 * the bitwidth of `v`. See `_bt_safe_lshift`.
104 */
105#define _bt_lshift(v, shift) \
106 ((__typeof__(v)) (_bt_cast_value_to_unsigned(v) << (shift)))
107
108/*
109 * Generate a mask of type `type` with the `length` least significant bits
110 * cleared, and the most significant bits set.
111 */
112#define _bt_make_mask_complement(type, length) \
113 _bt_lshift(_bt_fill_mask(type), length)
114
115/*
116 * Generate a mask of type `type` with the `length` least significant bits
117 * set, and the most significant bits cleared.
118 */
119#define _bt_make_mask(type, length) \
120 ((type) ~_bt_make_mask_complement(type, length))
121
122/*
123 * Right shift a value `v` of `shift` bits.
124 *
125 * The type of `v` can be signed or unsigned integer.
126 * The value of `shift` must be less than the size of `v` (in bits),
127 * otherwise the behavior is undefined.
128 * Evaluates to the result of the shift operation.
129 *
130 * According to the C99 standard, right shift of a left hand-side signed
131 * type which has a negative value is implementation defined. This
132 * bitfield header relies on the right shift implementation carrying the
133 * sign bit. If the compiler implementation has a different behavior,
134 * emulate carrying the sign bit.
135 *
136 * This macro should not be used if `shift` can be greater or equal than
137 * the bitwidth of `v`. See `_bt_safe_rshift`.
138 */
139#if ((-1 >> 1) == -1)
140#define _bt_rshift(v, shift) ((v) >> (shift))
141#else
142#define _bt_rshift(v, shift) \
143 ((__typeof__(v)) ((_bt_cast_value_to_unsigned(v) >> (shift)) | \
144 ((v) < 0 ? _bt_make_mask_complement(__typeof__(v), \
145 sizeof(v) * CHAR_BIT - (shift)) : 0)))
146#endif
147
148/*
149 * Right shift a signed or unsigned integer with `shift` value being an
150 * arbitrary number of bits. `v` is modified by this macro. The shift
151 * is transformed into a sequence of `_nr_partial_shifts` consecutive
152 * shift operations, each of a number of bits smaller than the bitwidth
153 * of `v`, ending with a shift of the number of left over bits.
154 */
155#define _bt_safe_rshift(v, shift) \
156do { \
157 unsigned long _nr_partial_shifts = (shift) / (sizeof(v) * CHAR_BIT - 1); \
158 unsigned long _leftover_bits = (shift) % (sizeof(v) * CHAR_BIT - 1); \
159 \
160 for (; _nr_partial_shifts; _nr_partial_shifts--) \
161 (v) = _bt_rshift(v, sizeof(v) * CHAR_BIT - 1); \
162 (v) = _bt_rshift(v, _leftover_bits); \
163} while (0)
164
165/*
166 * Left shift a signed or unsigned integer with `shift` value being an
167 * arbitrary number of bits. `v` is modified by this macro. The shift
168 * is transformed into a sequence of `_nr_partial_shifts` consecutive
169 * shift operations, each of a number of bits smaller than the bitwidth
170 * of `v`, ending with a shift of the number of left over bits.
171 */
172#define _bt_safe_lshift(v, shift) \
173do { \
174 unsigned long _nr_partial_shifts = (shift) / (sizeof(v) * CHAR_BIT - 1); \
175 unsigned long _leftover_bits = (shift) % (sizeof(v) * CHAR_BIT - 1); \
176 \
177 for (; _nr_partial_shifts; _nr_partial_shifts--) \
178 (v) = _bt_lshift(v, sizeof(v) * CHAR_BIT - 1); \
179 (v) = _bt_lshift(v, _leftover_bits); \
180} while (0)
08228826 181
6dc2ca62 182/*
d79865b9 183 * bt_bitfield_write - write integer to a bitfield in native endianness
6dc2ca62
MD
184 *
185 * Save integer to the bitfield, which starts at the "start" bit, has "len"
186 * bits.
187 * The inside of a bitfield is from high bits to low bits.
188 * Uses native endianness.
189 * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
190 * For signed "v", sign-extend v if bitfield is larger than v.
191 *
192 * On little endian, bytes are placed from the less significant to the most
193 * significant. Also, consecutive bitfields are placed from lower bits to higher
194 * bits.
195 *
196 * On big endian, bytes are places from most significant to less significant.
197 * Also, consecutive bitfields are placed from higher to lower bits.
198 */
199
5f61bf21 200#define _bt_bitfield_write_le(_ptr, type, _start, _length, _v) \
6dc2ca62 201do { \
c15e0603 202 __typeof__(_v) __v = (_v); \
9128428b 203 type *__ptr = (void *) (_ptr); \
5f61bf21 204 unsigned long __start = (_start), __length = (_length); \
47e0f2e2
MD
205 type mask, cmask; \
206 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \
6dc2ca62
MD
207 unsigned long start_unit, end_unit, this_unit; \
208 unsigned long end, cshift; /* cshift is "complement shift" */ \
6dc2ca62 209 \
5f61bf21 210 if (!__length) \
6dc2ca62
MD
211 break; \
212 \
5f61bf21
MD
213 end = __start + __length; \
214 start_unit = __start / ts; \
6dc2ca62
MD
215 end_unit = (end + (ts - 1)) / ts; \
216 \
217 /* Trim v high bits */ \
5f61bf21 218 if (__length < sizeof(__v) * CHAR_BIT) \
c15e0603 219 __v &= _bt_make_mask(__typeof__(__v), __length); \
6dc2ca62
MD
220 \
221 /* We can now append v with a simple "or", shift it piece-wise */ \
222 this_unit = start_unit; \
223 if (start_unit == end_unit - 1) { \
c15e0603 224 mask = _bt_make_mask(type, __start % ts); \
6dc2ca62 225 if (end % ts) \
c15e0603
MD
226 mask |= _bt_make_mask_complement(type, end % ts); \
227 cmask = _bt_lshift((type) (__v), __start % ts); \
08228826 228 cmask &= ~mask; \
5f61bf21
MD
229 __ptr[this_unit] &= mask; \
230 __ptr[this_unit] |= cmask; \
6dc2ca62
MD
231 break; \
232 } \
5f61bf21
MD
233 if (__start % ts) { \
234 cshift = __start % ts; \
c15e0603
MD
235 mask = _bt_make_mask(type, cshift); \
236 cmask = _bt_lshift((type) (__v), cshift); \
08228826 237 cmask &= ~mask; \
5f61bf21
MD
238 __ptr[this_unit] &= mask; \
239 __ptr[this_unit] |= cmask; \
c15e0603 240 _bt_safe_rshift(__v, ts - cshift); \
5f61bf21 241 __start += ts - cshift; \
6dc2ca62
MD
242 this_unit++; \
243 } \
244 for (; this_unit < end_unit - 1; this_unit++) { \
5f61bf21 245 __ptr[this_unit] = (type) __v; \
c15e0603 246 _bt_safe_rshift(__v, ts); \
5f61bf21 247 __start += ts; \
6dc2ca62
MD
248 } \
249 if (end % ts) { \
c15e0603 250 mask = _bt_make_mask_complement(type, end % ts); \
5f61bf21 251 cmask = (type) __v; \
08228826 252 cmask &= ~mask; \
5f61bf21
MD
253 __ptr[this_unit] &= mask; \
254 __ptr[this_unit] |= cmask; \
6dc2ca62 255 } else \
5f61bf21 256 __ptr[this_unit] = (type) __v; \
6dc2ca62
MD
257} while (0)
258
5f61bf21 259#define _bt_bitfield_write_be(_ptr, type, _start, _length, _v) \
6dc2ca62 260do { \
c15e0603 261 __typeof__(_v) __v = (_v); \
9128428b 262 type *__ptr = (void *) (_ptr); \
5f61bf21 263 unsigned long __start = (_start), __length = (_length); \
47e0f2e2
MD
264 type mask, cmask; \
265 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \
6dc2ca62
MD
266 unsigned long start_unit, end_unit, this_unit; \
267 unsigned long end, cshift; /* cshift is "complement shift" */ \
6dc2ca62 268 \
5f61bf21 269 if (!__length) \
6dc2ca62
MD
270 break; \
271 \
5f61bf21
MD
272 end = __start + __length; \
273 start_unit = __start / ts; \
6dc2ca62
MD
274 end_unit = (end + (ts - 1)) / ts; \
275 \
276 /* Trim v high bits */ \
5f61bf21 277 if (__length < sizeof(__v) * CHAR_BIT) \
c15e0603 278 __v &= _bt_make_mask(__typeof__(__v), __length); \
6dc2ca62
MD
279 \
280 /* We can now append v with a simple "or", shift it piece-wise */ \
281 this_unit = end_unit - 1; \
282 if (start_unit == end_unit - 1) { \
c15e0603 283 mask = _bt_make_mask(type, (ts - (end % ts)) % ts); \
5f61bf21 284 if (__start % ts) \
c15e0603
MD
285 mask |= _bt_make_mask_complement(type, ts - (__start % ts)); \
286 cmask = _bt_lshift((type) (__v), (ts - (end % ts)) % ts); \
08228826 287 cmask &= ~mask; \
5f61bf21
MD
288 __ptr[this_unit] &= mask; \
289 __ptr[this_unit] |= cmask; \
6dc2ca62
MD
290 break; \
291 } \
292 if (end % ts) { \
293 cshift = end % ts; \
c15e0603
MD
294 mask = _bt_make_mask(type, ts - cshift); \
295 cmask = _bt_lshift((type) (__v), ts - cshift); \
08228826 296 cmask &= ~mask; \
5f61bf21
MD
297 __ptr[this_unit] &= mask; \
298 __ptr[this_unit] |= cmask; \
c15e0603 299 _bt_safe_rshift(__v, cshift); \
6dc2ca62
MD
300 end -= cshift; \
301 this_unit--; \
302 } \
08228826 303 for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \
5f61bf21 304 __ptr[this_unit] = (type) __v; \
c15e0603 305 _bt_safe_rshift(__v, ts); \
6dc2ca62
MD
306 end -= ts; \
307 } \
5f61bf21 308 if (__start % ts) { \
c15e0603 309 mask = _bt_make_mask_complement(type, ts - (__start % ts)); \
5f61bf21 310 cmask = (type) __v; \
08228826 311 cmask &= ~mask; \
5f61bf21
MD
312 __ptr[this_unit] &= mask; \
313 __ptr[this_unit] |= cmask; \
6dc2ca62 314 } else \
5f61bf21 315 __ptr[this_unit] = (type) __v; \
6dc2ca62
MD
316} while (0)
317
318/*
d79865b9
MD
319 * bt_bitfield_write - write integer to a bitfield in native endianness
320 * bt_bitfield_write_le - write integer to a bitfield in little endian
321 * bt_bitfield_write_be - write integer to a bitfield in big endian
6dc2ca62
MD
322 */
323
324#if (BYTE_ORDER == LITTLE_ENDIAN)
325
47e0f2e2
MD
326#define bt_bitfield_write(ptr, type, _start, _length, _v) \
327 _bt_bitfield_write_le(ptr, type, _start, _length, _v)
6dc2ca62 328
47e0f2e2
MD
329#define bt_bitfield_write_le(ptr, type, _start, _length, _v) \
330 _bt_bitfield_write_le(ptr, type, _start, _length, _v)
c15e0603 331
47e0f2e2
MD
332#define bt_bitfield_write_be(ptr, type, _start, _length, _v) \
333 _bt_bitfield_write_be(ptr, unsigned char, _start, _length, _v)
6dc2ca62
MD
334
335#elif (BYTE_ORDER == BIG_ENDIAN)
336
47e0f2e2
MD
337#define bt_bitfield_write(ptr, type, _start, _length, _v) \
338 _bt_bitfield_write_be(ptr, type, _start, _length, _v)
6dc2ca62 339
47e0f2e2
MD
340#define bt_bitfield_write_le(ptr, type, _start, _length, _v) \
341 _bt_bitfield_write_le(ptr, unsigned char, _start, _length, _v)
c15e0603 342
47e0f2e2
MD
343#define bt_bitfield_write_be(ptr, type, _start, _length, _v) \
344 _bt_bitfield_write_be(ptr, type, _start, _length, _v)
6dc2ca62
MD
345
346#else /* (BYTE_ORDER == PDP_ENDIAN) */
347
348#error "Byte order not supported"
349
350#endif
351
5f61bf21 352#define _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr) \
6dc2ca62 353do { \
c15e0603
MD
354 __typeof__(*(_vptr)) *__vptr = (_vptr); \
355 __typeof__(*__vptr) __v; \
9128428b 356 type *__ptr = (void *) (_ptr); \
5f61bf21 357 unsigned long __start = (_start), __length = (_length); \
47e0f2e2
MD
358 type mask, cmask; \
359 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \
6dc2ca62
MD
360 unsigned long start_unit, end_unit, this_unit; \
361 unsigned long end, cshift; /* cshift is "complement shift" */ \
08228826 362 \
5f61bf21
MD
363 if (!__length) { \
364 *__vptr = 0; \
08228826
MD
365 break; \
366 } \
367 \
5f61bf21
MD
368 end = __start + __length; \
369 start_unit = __start / ts; \
08228826 370 end_unit = (end + (ts - 1)) / ts; \
6a7b3345
MD
371 \
372 this_unit = end_unit - 1; \
c15e0603
MD
373 if (_bt_is_signed_type(__typeof__(__v)) \
374 && (__ptr[this_unit] & _bt_lshift((type) 1, (end % ts ? end % ts : ts) - 1))) \
375 __v = ~(__typeof__(__v)) 0; \
6a7b3345 376 else \
5f61bf21 377 __v = 0; \
6a7b3345 378 if (start_unit == end_unit - 1) { \
5f61bf21 379 cmask = __ptr[this_unit]; \
c15e0603 380 cmask = _bt_rshift(cmask, __start % ts); \
5f61bf21 381 if ((end - __start) % ts) { \
c15e0603 382 mask = _bt_make_mask(type, end - __start); \
6a7b3345
MD
383 cmask &= mask; \
384 } \
c15e0603
MD
385 _bt_safe_lshift(__v, end - __start); \
386 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), cmask); \
5f61bf21 387 *__vptr = __v; \
6a7b3345
MD
388 break; \
389 } \
390 if (end % ts) { \
391 cshift = end % ts; \
c15e0603 392 mask = _bt_make_mask(type, cshift); \
5f61bf21 393 cmask = __ptr[this_unit]; \
6a7b3345 394 cmask &= mask; \
c15e0603
MD
395 _bt_safe_lshift(__v, cshift); \
396 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), cmask); \
6a7b3345
MD
397 end -= cshift; \
398 this_unit--; \
399 } \
08228826 400 for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \
c15e0603
MD
401 _bt_safe_lshift(__v, ts); \
402 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), __ptr[this_unit]); \
6a7b3345
MD
403 end -= ts; \
404 } \
5f61bf21 405 if (__start % ts) { \
c15e0603 406 mask = _bt_make_mask(type, ts - (__start % ts)); \
5f61bf21 407 cmask = __ptr[this_unit]; \
c15e0603 408 cmask = _bt_rshift(cmask, __start % ts); \
6a7b3345 409 cmask &= mask; \
c15e0603
MD
410 _bt_safe_lshift(__v, ts - (__start % ts)); \
411 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), cmask); \
6a7b3345 412 } else { \
c15e0603
MD
413 _bt_safe_lshift(__v, ts); \
414 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), __ptr[this_unit]); \
6a7b3345 415 } \
5f61bf21 416 *__vptr = __v; \
08228826
MD
417} while (0)
418
5f61bf21 419#define _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr) \
08228826 420do { \
c15e0603
MD
421 __typeof__(*(_vptr)) *__vptr = (_vptr); \
422 __typeof__(*__vptr) __v; \
9128428b 423 type *__ptr = (void *) (_ptr); \
5f61bf21 424 unsigned long __start = (_start), __length = (_length); \
47e0f2e2
MD
425 type mask, cmask; \
426 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \
08228826
MD
427 unsigned long start_unit, end_unit, this_unit; \
428 unsigned long end, cshift; /* cshift is "complement shift" */ \
6dc2ca62 429 \
5f61bf21
MD
430 if (!__length) { \
431 *__vptr = 0; \
6dc2ca62 432 break; \
08228826 433 } \
6dc2ca62 434 \
5f61bf21
MD
435 end = __start + __length; \
436 start_unit = __start / ts; \
6dc2ca62 437 end_unit = (end + (ts - 1)) / ts; \
6a7b3345 438 \
08228826 439 this_unit = start_unit; \
c15e0603
MD
440 if (_bt_is_signed_type(__typeof__(__v)) \
441 && (__ptr[this_unit] & _bt_lshift((type) 1, ts - (__start % ts) - 1))) \
442 __v = ~(__typeof__(__v)) 0; \
6a7b3345 443 else \
5f61bf21 444 __v = 0; \
6a7b3345 445 if (start_unit == end_unit - 1) { \
5f61bf21 446 cmask = __ptr[this_unit]; \
c15e0603 447 cmask = _bt_rshift(cmask, (ts - (end % ts)) % ts); \
5f61bf21 448 if ((end - __start) % ts) { \
c15e0603 449 mask = _bt_make_mask(type, end - __start); \
6a7b3345
MD
450 cmask &= mask; \
451 } \
c15e0603
MD
452 _bt_safe_lshift(__v, end - __start); \
453 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), cmask); \
5f61bf21 454 *__vptr = __v; \
6a7b3345
MD
455 break; \
456 } \
5f61bf21
MD
457 if (__start % ts) { \
458 cshift = __start % ts; \
c15e0603 459 mask = _bt_make_mask(type, ts - cshift); \
5f61bf21 460 cmask = __ptr[this_unit]; \
6a7b3345 461 cmask &= mask; \
c15e0603
MD
462 _bt_safe_lshift(__v, ts - cshift); \
463 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), cmask); \
5f61bf21 464 __start += ts - cshift; \
6a7b3345
MD
465 this_unit++; \
466 } \
467 for (; this_unit < end_unit - 1; this_unit++) { \
c15e0603
MD
468 _bt_safe_lshift(__v, ts); \
469 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), __ptr[this_unit]); \
5f61bf21 470 __start += ts; \
6a7b3345
MD
471 } \
472 if (end % ts) { \
c15e0603 473 mask = _bt_make_mask(type, end % ts); \
5f61bf21 474 cmask = __ptr[this_unit]; \
c15e0603 475 cmask = _bt_rshift(cmask, ts - (end % ts)); \
6a7b3345 476 cmask &= mask; \
c15e0603
MD
477 _bt_safe_lshift(__v, end % ts); \
478 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), cmask); \
6a7b3345 479 } else { \
c15e0603
MD
480 _bt_safe_lshift(__v, ts); \
481 __v |= _bt_cast_value_to_unsigned_type(__typeof__(__v), __ptr[this_unit]); \
6a7b3345 482 } \
5f61bf21 483 *__vptr = __v; \
6dc2ca62
MD
484} while (0)
485
6dc2ca62 486/*
d79865b9
MD
487 * bt_bitfield_read - read integer from a bitfield in native endianness
488 * bt_bitfield_read_le - read integer from a bitfield in little endian
489 * bt_bitfield_read_be - read integer from a bitfield in big endian
6dc2ca62
MD
490 */
491
08228826
MD
492#if (BYTE_ORDER == LITTLE_ENDIAN)
493
5f61bf21
MD
494#define bt_bitfield_read(_ptr, type, _start, _length, _vptr) \
495 _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)
08228826 496
5f61bf21
MD
497#define bt_bitfield_read_le(_ptr, type, _start, _length, _vptr) \
498 _bt_bitfield_read_le(_ptr, type, _start, _length, _vptr)
c15e0603 499
5f61bf21
MD
500#define bt_bitfield_read_be(_ptr, type, _start, _length, _vptr) \
501 _bt_bitfield_read_be(_ptr, unsigned char, _start, _length, _vptr)
08228826
MD
502
503#elif (BYTE_ORDER == BIG_ENDIAN)
504
5f61bf21
MD
505#define bt_bitfield_read(_ptr, type, _start, _length, _vptr) \
506 _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)
08228826 507
5f61bf21
MD
508#define bt_bitfield_read_le(_ptr, type, _start, _length, _vptr) \
509 _bt_bitfield_read_le(_ptr, unsigned char, _start, _length, _vptr)
c15e0603 510
5f61bf21
MD
511#define bt_bitfield_read_be(_ptr, type, _start, _length, _vptr) \
512 _bt_bitfield_read_be(_ptr, type, _start, _length, _vptr)
08228826
MD
513
514#else /* (BYTE_ORDER == PDP_ENDIAN) */
515
516#error "Byte order not supported"
517
518#endif
6dc2ca62 519
d79865b9 520#endif /* _BABELTRACE_BITFIELD_H */
This page took 0.057171 seconds and 4 git commands to generate.