1 #ifndef _BABELTRACE_BITFIELD_H
2 #define _BABELTRACE_BITFIELD_H
3 
4 /*
5  * Copyright 2010-2019 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
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.
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.
24  */
25 
26 #include <stdint.h>	/* C99 5.2.4.2 Numerical limits */
27 #include <stdbool.h>	/* C99 7.16 bool type */
28 #include <babeltrace/compat/limits.h>	/* C99 5.2.4.2 Numerical limits */
29 #include <babeltrace/endian.h>	/* Non-standard BIG_ENDIAN, LITTLE_ENDIAN, BYTE_ORDER */
30 
31 /*
32  * This header strictly follows the C99 standard, except for use of the
33  * compiler-specific __typeof__.
34  */
35 
36 /*
37  * This bitfield header requires the compiler representation of signed
38  * integers to be two's complement.
39  */
40 #if (-1 != ~0)
41 #error "bitfield.h requires the compiler representation of signed integers to be two's complement."
42 #endif
43 
44 /*
45  * _bt_is_signed_type() willingly generates comparison of unsigned
46  * expression < 0, which is always false. Silence compiler warnings.
47  */
48 #ifdef __GNUC__
49 # define _BT_DIAG_PUSH			_Pragma("GCC diagnostic push")
50 # define _BT_DIAG_POP			_Pragma("GCC diagnostic pop")
51 
52 # define _BT_DIAG_STRINGIFY_1(x)	#x
53 # define _BT_DIAG_STRINGIFY(x)		_BT_DIAG_STRINGIFY_1(x)
54 
55 # define _BT_DIAG_IGNORE(option)	\
56 	_Pragma(_BT_DIAG_STRINGIFY(GCC diagnostic ignored option))
57 # define _BT_DIAG_IGNORE_TYPE_LIMITS	_BT_DIAG_IGNORE("-Wtype-limits")
58 #else
59 # define _BT_DIAG_PUSH
60 # define _BT_DIAG_POP
61 # define _BT_DIAG_IGNORE
62 #endif
63 
64 #define _bt_is_signed_type(type)	((type) -1 < (type) 0)
65 
66 /*
67  * Produce a build-time error if the condition `cond` is non-zero.
68  * Evaluates as a size_t expression.
69  */
70 #define _BT_BUILD_ASSERT(cond)					\
71 	sizeof(struct { int f:(2 * !!(cond) - 1); })
72 
73 /*
74  * Cast value `v` to an unsigned integer of the same size as `v`.
75  */
76 #define _bt_cast_value_to_unsigned(v)					\
77 	(sizeof(v) == sizeof(uint8_t) ? (uint8_t) (v) :			\
78 	sizeof(v) == sizeof(uint16_t) ? (uint16_t) (v) :		\
79 	sizeof(v) == sizeof(uint32_t) ? (uint32_t) (v) :		\
80 	sizeof(v) == sizeof(uint64_t) ? (uint64_t) (v) :		\
81 	_BT_BUILD_ASSERT(sizeof(v) <= sizeof(uint64_t)))
82 
83 /*
84  * Cast value `v` to an unsigned integer type of the size of type `type`
85  * *without* sign-extension.
86  *
87  * The unsigned cast ensures that we're not shifting a negative value,
88  * which is undefined in C. However, this limits the maximum type size
89  * of `type` to 64-bit. Generate a compile-time error if the size of
90  * `type` is larger than 64-bit.
91  */
92 #define _bt_cast_value_to_unsigned_type(type, v)			\
93 	(sizeof(type) == sizeof(uint8_t) ?				\
94 		(uint8_t) _bt_cast_value_to_unsigned(v) :		\
95 	sizeof(type) == sizeof(uint16_t) ?				\
96 		(uint16_t) _bt_cast_value_to_unsigned(v) :		\
97 	sizeof(type) == sizeof(uint32_t) ?				\
98 		(uint32_t) _bt_cast_value_to_unsigned(v) :		\
99 	sizeof(type) == sizeof(uint64_t) ?				\
100 		(uint64_t) _bt_cast_value_to_unsigned(v) :		\
101 	_BT_BUILD_ASSERT(sizeof(v) <= sizeof(uint64_t)))
102 
103 /*
104  * _bt_fill_mask evaluates to a "type" integer with all bits set.
105  */
106 #define _bt_fill_mask(type)	((type) ~(type) 0)
107 
108 /*
109  * Left shift a value `v` of `shift` bits.
110  *
111  * The type of `v` can be signed or unsigned integer.
112  * The value of `shift` must be less than the size of `v` (in bits),
113  * otherwise the behavior is undefined.
114  * Evaluates to the result of the shift operation.
115  *
116  * According to the C99 standard, left shift of a left hand-side signed
117  * type is undefined if it has a negative value or if the result cannot
118  * be represented in the result type. This bitfield header discards the
119  * bits that are left-shifted beyond the result type representation,
120  * which is the behavior of an unsigned type left shift operation.
121  * Therefore, always perform left shift on an unsigned type.
122  *
123  * This macro should not be used if `shift` can be greater or equal than
124  * the bitwidth of `v`. See `_bt_safe_lshift`.
125  */
126 #define _bt_lshift(v, shift)						\
127 	((__typeof__(v)) (_bt_cast_value_to_unsigned(v) << (shift)))
128 
129 /*
130  * Generate a mask of type `type` with the `length` least significant bits
131  * cleared, and the most significant bits set.
132  */
133 #define _bt_make_mask_complement(type, length)				\
134 	_bt_lshift(_bt_fill_mask(type), length)
135 
136 /*
137  * Generate a mask of type `type` with the `length` least significant bits
138  * set, and the most significant bits cleared.
139  */
140 #define _bt_make_mask(type, length)					\
141 	((type) ~_bt_make_mask_complement(type, length))
142 
143 /*
144  * Right shift a value `v` of `shift` bits.
145  *
146  * The type of `v` can be signed or unsigned integer.
147  * The value of `shift` must be less than the size of `v` (in bits),
148  * otherwise the behavior is undefined.
149  * Evaluates to the result of the shift operation.
150  *
151  * According to the C99 standard, right shift of a left hand-side signed
152  * type which has a negative value is implementation defined. This
153  * bitfield header relies on the right shift implementation carrying the
154  * sign bit. If the compiler implementation has a different behavior,
155  * emulate carrying the sign bit.
156  *
157  * This macro should not be used if `shift` can be greater or equal than
158  * the bitwidth of `v`. See `_bt_safe_rshift`.
159  */
160 #if ((-1 >> 1) == -1)
161 #define _bt_rshift(v, shift)	((v) >> (shift))
162 #else
163 #define _bt_rshift(v, shift)						\
164 	((__typeof__(v)) ((_bt_cast_value_to_unsigned(v) >> (shift)) |	\
165 		((v) < 0 ? _bt_make_mask_complement(__typeof__(v),	\
166 			sizeof(v) * CHAR_BIT - (shift)) : 0)))
167 #endif
168 
169 /*
170  * Right shift a signed or unsigned integer with `shift` value being an
171  * arbitrary number of bits. `v` is modified by this macro. The shift
172  * is transformed into a sequence of `_nr_partial_shifts` consecutive
173  * shift operations, each of a number of bits smaller than the bitwidth
174  * of `v`, ending with a shift of the number of left over bits.
175  */
176 #define _bt_safe_rshift(v, shift)					\
177 do {									\
178 	unsigned long _nr_partial_shifts = (shift) / (sizeof(v) * CHAR_BIT - 1); \
179 	unsigned long _leftover_bits = (shift) % (sizeof(v) * CHAR_BIT - 1); \
180 									\
181 	for (; _nr_partial_shifts; _nr_partial_shifts--)		\
182 		(v) = _bt_rshift(v, sizeof(v) * CHAR_BIT - 1);		\
183 	(v) = _bt_rshift(v, _leftover_bits);				\
184 } while (0)
185 
186 /*
187  * Left shift a signed or unsigned integer with `shift` value being an
188  * arbitrary number of bits. `v` is modified by this macro. The shift
189  * is transformed into a sequence of `_nr_partial_shifts` consecutive
190  * shift operations, each of a number of bits smaller than the bitwidth
191  * of `v`, ending with a shift of the number of left over bits.
192  */
193 #define _bt_safe_lshift(v, shift)					\
194 do {									\
195 	unsigned long _nr_partial_shifts = (shift) / (sizeof(v) * CHAR_BIT - 1); \
196 	unsigned long _leftover_bits = (shift) % (sizeof(v) * CHAR_BIT - 1); \
197 									\
198 	for (; _nr_partial_shifts; _nr_partial_shifts--)		\
199 		(v) = _bt_lshift(v, sizeof(v) * CHAR_BIT - 1);		\
200 	(v) = _bt_lshift(v, _leftover_bits);				\
201 } while (0)
202 
203 /*
204  * bt_bitfield_write - write integer to a bitfield in native endianness
205  *
206  * Save integer to the bitfield, which starts at the "start" bit, has "len"
207  * bits.
208  * The inside of a bitfield is from high bits to low bits.
209  * Uses native endianness.
210  * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
211  * For signed "v", sign-extend v if bitfield is larger than v.
212  *
213  * On little endian, bytes are placed from the less significant to the most
214  * significant. Also, consecutive bitfields are placed from lower bits to higher
215  * bits.
216  *
217  * On big endian, bytes are places from most significant to less significant.
218  * Also, consecutive bitfields are placed from higher to lower bits.
219  */
220 
221 #define _bt_bitfield_write_le(ptr, type, start, length, v)		\
222 do {									\
223 	__typeof__(v) _v = (v);					\
224 	type *_ptr = (void *) (ptr);					\
225 	unsigned long _start = (start), _length = (length);		\
226 	type _mask, _cmask;						\
227 	unsigned long _ts = sizeof(type) * CHAR_BIT; /* type size */	\
228 	unsigned long _start_unit, _end_unit, _this_unit;		\
229 	unsigned long _end, _cshift; /* _cshift is "complement shift" */ \
230 									\
231 	if (!_length)							\
232 		break;							\
233 									\
234 	_end = _start + _length;					\
235 	_start_unit = _start / _ts;					\
236 	_end_unit = (_end + (_ts - 1)) / _ts;				\
237 									\
238 	/* Trim v high bits */						\
239 	if (_length < sizeof(_v) * CHAR_BIT)				\
240 		_v &= _bt_make_mask(__typeof__(_v), _length);		\
241 									\
242 	/* We can now append v with a simple "or", shift it piece-wise */ \
243 	_this_unit = _start_unit;					\
244 	if (_start_unit == _end_unit - 1) {				\
245 		_mask = _bt_make_mask(type, _start % _ts);		\
246 		if (_end % _ts)						\
247 			_mask |= _bt_make_mask_complement(type, _end % _ts); \
248 		_cmask = _bt_lshift((type) (_v), _start % _ts);		\
249 		_cmask &= ~_mask;					\
250 		_ptr[_this_unit] &= _mask;				\
251 		_ptr[_this_unit] |= _cmask;				\
252 		break;							\
253 	}								\
254 	if (_start % _ts) {						\
255 		_cshift = _start % _ts;					\
256 		_mask = _bt_make_mask(type, _cshift);			\
257 		_cmask = _bt_lshift((type) (_v), _cshift);		\
258 		_cmask &= ~_mask;					\
259 		_ptr[_this_unit] &= _mask;				\
260 		_ptr[_this_unit] |= _cmask;				\
261 		_bt_safe_rshift(_v, _ts - _cshift);			\
262 		_start += _ts - _cshift;				\
263 		_this_unit++;						\
264 	}								\
265 	for (; _this_unit < _end_unit - 1; _this_unit++) {		\
266 		_ptr[_this_unit] = (type) _v;				\
267 		_bt_safe_rshift(_v, _ts);				\
268 		_start += _ts;						\
269 	}								\
270 	if (_end % _ts) {						\
271 		_mask = _bt_make_mask_complement(type, _end % _ts);	\
272 		_cmask = (type) _v;					\
273 		_cmask &= ~_mask;					\
274 		_ptr[_this_unit] &= _mask;				\
275 		_ptr[_this_unit] |= _cmask;				\
276 	} else								\
277 		_ptr[_this_unit] = (type) _v;				\
278 } while (0)
279 
280 #define _bt_bitfield_write_be(ptr, type, start, length, v)		\
281 do {									\
282 	__typeof__(v) _v = (v);						\
283 	type *_ptr = (void *) (ptr);					\
284 	unsigned long _start = (start), _length = (length);		\
285 	type _mask, _cmask;						\
286 	unsigned long _ts = sizeof(type) * CHAR_BIT; /* type size */	\
287 	unsigned long _start_unit, _end_unit, _this_unit;		\
288 	unsigned long _end, _cshift; /* _cshift is "complement shift" */ \
289 									\
290 	if (!_length)							\
291 		break;							\
292 									\
293 	_end = _start + _length;					\
294 	_start_unit = _start / _ts;					\
295 	_end_unit = (_end + (_ts - 1)) / _ts;				\
296 									\
297 	/* Trim v high bits */						\
298 	if (_length < sizeof(_v) * CHAR_BIT)				\
299 		_v &= _bt_make_mask(__typeof__(_v), _length);		\
300 									\
301 	/* We can now append v with a simple "or", shift it piece-wise */ \
302 	_this_unit = _end_unit - 1;					\
303 	if (_start_unit == _end_unit - 1) {				\
304 		_mask = _bt_make_mask(type, (_ts - (_end % _ts)) % _ts); \
305 		if (_start % _ts)					\
306 			_mask |= _bt_make_mask_complement(type, _ts - (_start % _ts)); \
307 		_cmask = _bt_lshift((type) (_v), (_ts - (_end % _ts)) % _ts); \
308 		_cmask &= ~_mask;					\
309 		_ptr[_this_unit] &= _mask;				\
310 		_ptr[_this_unit] |= _cmask;				\
311 		break;							\
312 	}								\
313 	if (_end % _ts) {						\
314 		_cshift = _end % _ts;					\
315 		_mask = _bt_make_mask(type, _ts - _cshift);		\
316 		_cmask = _bt_lshift((type) (_v), _ts - _cshift);	\
317 		_cmask &= ~_mask;					\
318 		_ptr[_this_unit] &= _mask;				\
319 		_ptr[_this_unit] |= _cmask;				\
320 		_bt_safe_rshift(_v, _cshift);				\
321 		_end -= _cshift;					\
322 		_this_unit--;						\
323 	}								\
324 	for (; (long) _this_unit >= (long) _start_unit + 1; _this_unit--) { \
325 		_ptr[_this_unit] = (type) _v;				\
326 		_bt_safe_rshift(_v, _ts);				\
327 		_end -= _ts;						\
328 	}								\
329 	if (_start % _ts) {						\
330 		_mask = _bt_make_mask_complement(type, _ts - (_start % _ts)); \
331 		_cmask = (type) _v;					\
332 		_cmask &= ~_mask;					\
333 		_ptr[_this_unit] &= _mask;				\
334 		_ptr[_this_unit] |= _cmask;				\
335 	} else								\
336 		_ptr[_this_unit] = (type) _v;				\
337 } while (0)
338 
339 /*
340  * bt_bitfield_write - write integer to a bitfield in native endianness
341  * bt_bitfield_write_le - write integer to a bitfield in little endian
342  * bt_bitfield_write_be - write integer to a bitfield in big endian
343  */
344 
345 #if (BYTE_ORDER == LITTLE_ENDIAN)
346 
347 #define bt_bitfield_write(ptr, type, start, length, v)			\
348 	_bt_bitfield_write_le(ptr, type, start, length, v)
349 
350 #define bt_bitfield_write_le(ptr, type, start, length, v)		\
351 	_bt_bitfield_write_le(ptr, type, start, length, v)
352 
353 #define bt_bitfield_write_be(ptr, type, start, length, v)		\
354 	_bt_bitfield_write_be(ptr, unsigned char, start, length, v)
355 
356 #elif (BYTE_ORDER == BIG_ENDIAN)
357 
358 #define bt_bitfield_write(ptr, type, start, length, v)			\
359 	_bt_bitfield_write_be(ptr, type, start, length, v)
360 
361 #define bt_bitfield_write_le(ptr, type, start, length, v)		\
362 	_bt_bitfield_write_le(ptr, unsigned char, start, length, v)
363 
364 #define bt_bitfield_write_be(ptr, type, start, length, v)		\
365 	_bt_bitfield_write_be(ptr, type, start, length, v)
366 
367 #else /* (BYTE_ORDER == PDP_ENDIAN) */
368 
369 #error "Byte order not supported"
370 
371 #endif
372 
373 #define _bt_bitfield_read_le(ptr, type, start, length, vptr)		\
374 do {									\
375 	__typeof__(*(vptr)) *_vptr = (vptr);				\
376 	__typeof__(*_vptr) _v;						\
377 	type *_ptr = (void *) (ptr);					\
378 	unsigned long _start = (start), _length = (length);		\
379 	type _mask, _cmask;						\
380 	unsigned long _ts = sizeof(type) * CHAR_BIT; /* type size */	\
381 	unsigned long _start_unit, _end_unit, _this_unit;		\
382 	unsigned long _end, _cshift; /* _cshift is "complement shift" */ \
383 	bool _is_signed_type;						\
384 									\
385 	if (!_length) {							\
386 		*_vptr = 0;						\
387 		break;							\
388 	}								\
389 									\
390 	_end = _start + _length;					\
391 	_start_unit = _start / _ts;					\
392 	_end_unit = (_end + (_ts - 1)) / _ts;				\
393 									\
394 	_this_unit = _end_unit - 1;					\
395 	_BT_DIAG_PUSH							\
396 	_BT_DIAG_IGNORE_TYPE_LIMITS					\
397 	_is_signed_type = _bt_is_signed_type(__typeof__(_v));		\
398 	_BT_DIAG_POP							\
399 	if (_is_signed_type						\
400 	    && (_ptr[_this_unit] & _bt_lshift((type) 1, (_end % _ts ? _end % _ts : _ts) - 1))) \
401 		_v = ~(__typeof__(_v)) 0;				\
402 	else								\
403 		_v = 0;							\
404 	if (_start_unit == _end_unit - 1) {				\
405 		_cmask = _ptr[_this_unit];				\
406 		_cmask = _bt_rshift(_cmask, _start % _ts);		\
407 		if ((_end - _start) % _ts) {				\
408 			_mask = _bt_make_mask(type, _end - _start);	\
409 			_cmask &= _mask;				\
410 		}							\
411 		_bt_safe_lshift(_v, _end - _start);			\
412 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _cmask); \
413 		*_vptr = _v;						\
414 		break;							\
415 	}								\
416 	if (_end % _ts) {						\
417 		_cshift = _end % _ts;					\
418 		_mask = _bt_make_mask(type, _cshift);			\
419 		_cmask = _ptr[_this_unit];				\
420 		_cmask &= _mask;					\
421 		_bt_safe_lshift(_v, _cshift);				\
422 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _cmask); \
423 		_end -= _cshift;					\
424 		_this_unit--;						\
425 	}								\
426 	for (; (long) _this_unit >= (long) _start_unit + 1; _this_unit--) { \
427 		_bt_safe_lshift(_v, _ts);				\
428 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _ptr[_this_unit]); \
429 		_end -= _ts;						\
430 	}								\
431 	if (_start % _ts) {						\
432 		_mask = _bt_make_mask(type, _ts - (_start % _ts));	\
433 		_cmask = _ptr[_this_unit];				\
434 		_cmask = _bt_rshift(_cmask, _start % _ts);		\
435 		_cmask &= _mask;					\
436 		_bt_safe_lshift(_v, _ts - (_start % _ts));		\
437 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _cmask); \
438 	} else {							\
439 		_bt_safe_lshift(_v, _ts);				\
440 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _ptr[_this_unit]); \
441 	}								\
442 	*_vptr = _v;							\
443 } while (0)
444 
445 #define _bt_bitfield_read_be(ptr, type, start, length, vptr)		\
446 do {									\
447 	__typeof__(*(vptr)) *_vptr = (vptr);				\
448 	__typeof__(*_vptr) _v;						\
449 	type *_ptr = (void *) (ptr);					\
450 	unsigned long _start = (start), _length = (length);		\
451 	type _mask, _cmask;						\
452 	unsigned long _ts = sizeof(type) * CHAR_BIT; /* type size */	\
453 	unsigned long _start_unit, _end_unit, _this_unit;		\
454 	unsigned long _end, _cshift; /* _cshift is "complement shift" */ \
455 	bool _is_signed_type;						\
456 									\
457 	if (!_length) {							\
458 		*_vptr = 0;						\
459 		break;							\
460 	}								\
461 									\
462 	_end = _start + _length;					\
463 	_start_unit = _start / _ts;					\
464 	_end_unit = (_end + (_ts - 1)) / _ts;				\
465 									\
466 	_this_unit = _start_unit;					\
467 	_BT_DIAG_PUSH							\
468 	_BT_DIAG_IGNORE_TYPE_LIMITS					\
469 	_is_signed_type = _bt_is_signed_type(__typeof__(_v));		\
470 	_BT_DIAG_POP							\
471 	if (_is_signed_type						\
472 	    && (_ptr[_this_unit] & _bt_lshift((type) 1, _ts - (_start % _ts) - 1))) \
473 		_v = ~(__typeof__(_v)) 0;				\
474 	else								\
475 		_v = 0;							\
476 	if (_start_unit == _end_unit - 1) {				\
477 		_cmask = _ptr[_this_unit];				\
478 		_cmask = _bt_rshift(_cmask, (_ts - (_end % _ts)) % _ts); \
479 		if ((_end - _start) % _ts) {				\
480 			_mask = _bt_make_mask(type, _end - _start);	\
481 			_cmask &= _mask;				\
482 		}							\
483 		_bt_safe_lshift(_v, _end - _start);			\
484 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _cmask); \
485 		*_vptr = _v;						\
486 		break;							\
487 	}								\
488 	if (_start % _ts) {						\
489 		_cshift = _start % _ts;					\
490 		_mask = _bt_make_mask(type, _ts - _cshift);		\
491 		_cmask = _ptr[_this_unit];				\
492 		_cmask &= _mask;					\
493 		_bt_safe_lshift(_v, _ts - _cshift);			\
494 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _cmask); \
495 		_start += _ts - _cshift;				\
496 		_this_unit++;						\
497 	}								\
498 	for (; _this_unit < _end_unit - 1; _this_unit++) {		\
499 		_bt_safe_lshift(_v, _ts);				\
500 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _ptr[_this_unit]); \
501 		_start += _ts;						\
502 	}								\
503 	if (_end % _ts) {						\
504 		_mask = _bt_make_mask(type, _end % _ts);		\
505 		_cmask = _ptr[_this_unit];				\
506 		_cmask = _bt_rshift(_cmask, _ts - (_end % _ts));	\
507 		_cmask &= _mask;					\
508 		_bt_safe_lshift(_v, _end % _ts);			\
509 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _cmask); \
510 	} else {							\
511 		_bt_safe_lshift(_v, _ts);				\
512 		_v |= _bt_cast_value_to_unsigned_type(__typeof__(_v), _ptr[_this_unit]); \
513 	}								\
514 	*_vptr = _v;							\
515 } while (0)
516 
517 /*
518  * bt_bitfield_read - read integer from a bitfield in native endianness
519  * bt_bitfield_read_le - read integer from a bitfield in little endian
520  * bt_bitfield_read_be - read integer from a bitfield in big endian
521  */
522 
523 #if (BYTE_ORDER == LITTLE_ENDIAN)
524 
525 #define bt_bitfield_read(ptr, type, start, length, vptr)		\
526 	_bt_bitfield_read_le(ptr, type, start, length, vptr)
527 
528 #define bt_bitfield_read_le(ptr, type, start, length, vptr)		\
529 	_bt_bitfield_read_le(ptr, type, start, length, vptr)
530 
531 #define bt_bitfield_read_be(ptr, type, start, length, vptr)		\
532 	_bt_bitfield_read_be(ptr, unsigned char, start, length, vptr)
533 
534 #elif (BYTE_ORDER == BIG_ENDIAN)
535 
536 #define bt_bitfield_read(ptr, type, start, length, vptr)		\
537 	_bt_bitfield_read_be(ptr, type, start, length, vptr)
538 
539 #define bt_bitfield_read_le(ptr, type, start, length, vptr)		\
540 	_bt_bitfield_read_le(ptr, unsigned char, start, length, vptr)
541 
542 #define bt_bitfield_read_be(ptr, type, start, length, vptr)		\
543 	_bt_bitfield_read_be(ptr, type, start, length, vptr)
544 
545 #else /* (BYTE_ORDER == PDP_ENDIAN) */
546 
547 #error "Byte order not supported"
548 
549 #endif
550 
551 #endif /* _BABELTRACE_BITFIELD_H */
552