1 # The MIT License (MIT)
3 # Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
13 # The above copyright notice and this permission notice shall be
14 # included in all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19 # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20 # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 _CLOCK_CB
= '{return_ctype} (*{cname}_clock_get_value)(void *);'
27 _PLATFORM_CALLBACKS_BEGIN
= '''/* barectf platform callbacks */
28 struct {prefix}platform_callbacks {{
29 /* clock callbacks */'''
32 _PLATFORM_CALLBACKS_END
= '''
33 /* is back-end full? */
34 int (*is_backend_full)(void *);
37 void (*open_packet)(void *);
40 void (*close_packet)(void *);
44 _CTX_PARENT
= '''/* common barectf context */
46 /* platform callbacks */
47 struct {prefix}platform_callbacks cbs;
49 /* platform data (passed to callbacks) */
52 /* output buffer (will contain a CTF binary packet) */
55 /* packet size in bits */
58 /* content size in bits */
59 uint32_t content_size;
61 /* current position from beginning of packet in bits */
64 /* packet header + context size (content offset) */
67 /* events discarded */
68 uint32_t events_discarded;
70 /* current packet is opened */
74 volatile int in_tracing_section;
76 /* tracing is enabled */
77 volatile int is_tracing_enabled;
79 /* use current/last event timestamp when opening/closing packets */
80 int use_cur_last_event_ts;
84 _CTX_BEGIN
= '''/* context for stream `{sname}` */
85 struct {prefix}{sname}_ctx {{
87 struct {prefix}ctx parent;
89 /* config-specific members follow */'''
95 _FUNC_INIT_PROTO
= '''/* initialize context */
100 struct {prefix}platform_callbacks cbs,
105 _FUNC_INIT_BODY
= '''{{
106 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
110 ctx->packet_size = _BYTES_TO_BITS(buf_size);
112 ctx->events_discarded = 0;
113 ctx->packet_is_open = 0;
114 ctx->in_tracing_section = 0;
115 ctx->is_tracing_enabled = 1;
116 ctx->use_cur_last_event_ts = 0;
120 _FUNC_OPEN_PROTO_BEGIN
= '''/* open packet for stream `{sname}` */
121 void {prefix}{sname}_open_packet(
122 struct {prefix}{sname}_ctx *ctx'''
125 _FUNC_OPEN_PROTO_END
= ')'
128 _FUNC_OPEN_BODY_BEGIN
= '''{{
130 const int saved_in_tracing_section = ctx->parent.in_tracing_section;
133 * This function is either called by a tracing function, or
134 * directly by the platform.
136 * If it's called by a tracing function, then
137 * ctx->parent.in_tracing_section is 1, so it's safe to open
138 * the packet here (alter the packet), even if tracing was
139 * disabled in the meantime because we're already in a tracing
140 * section (which finishes at the end of the tracing function
143 * If it's called directly by the platform, then if tracing is
144 * disabled, we don't want to alter the packet, and return
147 if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{
148 ctx->parent.in_tracing_section = 0;
152 /* we can modify the packet */
153 ctx->parent.in_tracing_section = 1;
157 _FUNC_OPEN_BODY_END
= '''
158 /* save content beginning's offset */
159 ctx->parent.off_content = ctx->parent.at;
161 /* mark current packet as open */
162 ctx->parent.packet_is_open = 1;
164 /* not tracing anymore */
165 ctx->parent.in_tracing_section = saved_in_tracing_section;
169 _FUNC_CLOSE_PROTO
= '''/* close packet for stream `{sname}` */
170 void {prefix}{sname}_close_packet(struct {prefix}{sname}_ctx *ctx)'''
173 _FUNC_CLOSE_BODY_BEGIN
= '''{{
175 const int saved_in_tracing_section = ctx->parent.in_tracing_section;
178 * This function is either called by a tracing function, or
179 * directly by the platform.
181 * If it's called by a tracing function, then
182 * ctx->parent.in_tracing_section is 1, so it's safe to close
183 * the packet here (alter the packet), even if tracing was
184 * disabled in the meantime, because we're already in a tracing
185 * section (which finishes at the end of the tracing function
188 * If it's called directly by the platform, then if tracing is
189 * disabled, we don't want to alter the packet, and return
192 if (!ctx->parent.is_tracing_enabled && !saved_in_tracing_section) {{
193 ctx->parent.in_tracing_section = 0;
197 /* we can modify the packet */
198 ctx->parent.in_tracing_section = 1;
202 _FUNC_CLOSE_BODY_END
= '''
203 /* go back to end of packet */
204 ctx->parent.at = ctx->parent.packet_size;
206 /* mark packet as closed */
207 ctx->parent.packet_is_open = 0;
209 /* not tracing anymore */
210 ctx->parent.in_tracing_section = saved_in_tracing_section;
214 _DEFINE_DEFAULT_STREAM_TRACE
= '#define {prefix}trace_{evname} {prefix}{sname}_trace_{evname}'
217 _FUNC_TRACE_PROTO_BEGIN
= '''/* trace (stream `{sname}`, event `{evname}`) */
218 void {prefix}{sname}_trace_{evname}(
219 struct {prefix}{sname}_ctx *ctx'''
222 _FUNC_TRACE_PROTO_END
= ')'
225 _FUNC_TRACE_BODY
= '''{{
231 if (!ctx->parent.is_tracing_enabled) {{
235 /* we can modify the packet */
236 ctx->parent.in_tracing_section = 1;
239 ev_size = _get_event_size_{sname}_{evname}(TO_VOID_PTR(ctx){params});
241 /* do we have enough space to serialize? */
242 if (!_reserve_event_space(TO_VOID_PTR(ctx), ev_size)) {{
243 /* no: forget this */
244 ctx->parent.in_tracing_section = 0;
248 /* serialize event */
249 _serialize_event_{sname}_{evname}(TO_VOID_PTR(ctx){params});
252 _commit_event(TO_VOID_PTR(ctx));
254 /* not tracing anymore */
255 ctx->parent.in_tracing_section = 0;
259 _FUNC_GET_EVENT_SIZE_PROTO_BEGIN
= '''static uint32_t _get_event_size_{sname}_{evname}(
263 _FUNC_GET_EVENT_SIZE_PROTO_END
= ')'
266 _FUNC_GET_EVENT_SIZE_BODY_BEGIN
= '''{{
267 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
268 uint32_t at = ctx->at;'''
271 _FUNC_GET_EVENT_SIZE_BODY_END
= ''' return at - ctx->at;
275 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_BEGIN
= '''static void _serialize_stream_event_header_{sname}(
280 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_PROTO_END
= ')'
283 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_BEGIN
= '''{{
284 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
287 _FUNC_SERIALIZE_STREAM_EVENT_HEADER_BODY_END
= '}'
290 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_BEGIN
= '''static void _serialize_stream_event_context_{sname}(
294 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_PROTO_END
= ')'
297 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_BEGIN
= '''{{
298 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
301 _FUNC_SERIALIZE_STREAM_EVENT_CONTEXT_BODY_END
= '}'
304 _FUNC_SERIALIZE_EVENT_PROTO_BEGIN
= '''static void _serialize_event_{sname}_{evname}(
308 _FUNC_SERIALIZE_EVENT_PROTO_END
= ')'
311 _FUNC_SERIALIZE_EVENT_BODY_BEGIN
= '''{{
312 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);'''
315 _FUNC_SERIALIZE_EVENT_BODY_END
= '}'
318 _HEADER_BEGIN
= '''#ifndef _{ucprefix}H
322 * The MIT License (MIT)
324 * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
326 * Permission is hereby granted, free of charge, to any person obtaining
327 * a copy of this software and associated documentation files (the
328 * "Software"), to deal in the Software without restriction, including
329 * without limitation the rights to use, copy, modify, merge, publish,
330 * distribute, sublicense, and/or sell copies of the Software, and to
331 * permit persons to whom the Software is furnished to do so, subject to
332 * the following conditions:
334 * The above copyright notice and this permission notice shall be
335 * included in all copies or substantial portions of the Software.
337 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
338 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
339 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
340 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
341 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
342 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
343 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
346 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
348 * The following C code was generated by barectf {version}
351 * For more details, see <http://barectf.org>.
356 #include "{bitfield_header_filename}"
365 {default_stream_trace_defs}
369 uint32_t {prefix}packet_size(void *ctx);
370 int {prefix}packet_is_full(void *ctx);
371 int {prefix}packet_is_empty(void *ctx);
372 uint32_t {prefix}packet_events_discarded(void *ctx);
373 uint8_t *{prefix}packet_buf(void *ctx);
374 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size);
375 uint32_t {prefix}packet_buf_size(void *ctx);
376 int {prefix}packet_is_open(void *ctx);
377 int {prefix}is_in_tracing_section(void *ctx);
378 volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx);
379 int {prefix}is_tracing_enabled(void *ctx);
380 void {prefix}enable_tracing(void *ctx, int enable);'''
383 _HEADER_END
= '''#ifdef __cplusplus
387 #endif /* _{ucprefix}H */
392 * The MIT License (MIT)
394 * Copyright (c) 2015-2020 Philippe Proulx <pproulx@efficios.com>
396 * Permission is hereby granted, free of charge, to any person obtaining
397 * a copy of this software and associated documentation files (the
398 * "Software"), to deal in the Software without restriction, including
399 * without limitation the rights to use, copy, modify, merge, publish,
400 * distribute, sublicense, and/or sell copies of the Software, and to
401 * permit persons to whom the Software is furnished to do so, subject to
402 * the following conditions:
404 * The above copyright notice and this permission notice shall be
405 * included in all copies or substantial portions of the Software.
407 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
408 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
409 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
410 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
411 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
412 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
413 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
416 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
418 * The following C code was generated by barectf {version}
421 * For more details, see <http://barectf.org>.
428 #include "{header_filename}"
430 #define _ALIGN(_at, _align) \\
432 (_at) = ((_at) + ((_align) - 1)) & -(_align); \\
436 # define TO_VOID_PTR(_value) static_cast<void *>(_value)
437 # define FROM_VOID_PTR(_type, _value) static_cast<_type *>(_value)
439 # define TO_VOID_PTR(_value) ((void *) (_value))
440 # define FROM_VOID_PTR(_type, _value) ((_type *) (_value))
443 #define _BITS_TO_BYTES(_x) ((_x) >> 3)
444 #define _BYTES_TO_BITS(_x) ((_x) << 3)
456 uint32_t {prefix}packet_size(void *ctx)
458 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_size;
461 int {prefix}packet_is_full(void *ctx)
463 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
465 return cctx->at == cctx->packet_size;
468 int {prefix}packet_is_empty(void *ctx)
470 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
472 return cctx->at <= cctx->off_content;
475 uint32_t {prefix}packet_events_discarded(void *ctx)
477 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->events_discarded;
480 uint8_t *{prefix}packet_buf(void *ctx)
482 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->buf;
485 uint32_t {prefix}packet_buf_size(void *ctx)
487 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
489 return _BITS_TO_BYTES(cctx->packet_size);
492 void {prefix}packet_set_buf(void *ctx, uint8_t *buf, uint32_t buf_size)
494 struct {prefix}ctx *cctx = FROM_VOID_PTR(struct {prefix}ctx, ctx);
497 cctx->packet_size = _BYTES_TO_BITS(buf_size);
500 int {prefix}packet_is_open(void *ctx)
502 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->packet_is_open;
505 int {prefix}is_in_tracing_section(void *ctx)
507 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section;
510 volatile const int *{prefix}is_in_tracing_section_ptr(void *ctx)
512 return &FROM_VOID_PTR(struct {prefix}ctx, ctx)->in_tracing_section;
515 int {prefix}is_tracing_enabled(void *ctx)
517 return FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled;
520 void {prefix}enable_tracing(void *ctx, int enable)
522 FROM_VOID_PTR(struct {prefix}ctx, ctx)->is_tracing_enabled = enable;
526 void _write_cstring(struct {prefix}ctx *ctx, const char *src)
528 uint32_t sz = strlen(src) + 1;
530 memcpy(&ctx->buf[_BITS_TO_BYTES(ctx->at)], src, sz);
531 ctx->at += _BYTES_TO_BITS(sz);
535 int _reserve_event_space(void *vctx, uint32_t ev_size)
537 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
539 /* event _cannot_ fit? */
540 if (ev_size > (ctx->packet_size - ctx->off_content)) {{
541 ctx->events_discarded++;
546 /* packet is full? */
547 if ({prefix}packet_is_full(ctx)) {{
548 /* yes: is back-end full? */
549 if (ctx->cbs.is_backend_full(ctx->data)) {{
550 /* yes: discard event */
551 ctx->events_discarded++;
556 /* back-end is not full: open new packet */
557 ctx->use_cur_last_event_ts = 1;
558 ctx->cbs.open_packet(ctx->data);
559 ctx->use_cur_last_event_ts = 0;
562 /* event fits the current packet? */
563 if (ev_size > (ctx->packet_size - ctx->at)) {{
564 /* no: close packet now */
565 ctx->use_cur_last_event_ts = 1;
566 ctx->cbs.close_packet(ctx->data);
567 ctx->use_cur_last_event_ts = 0;
569 /* is back-end full? */
570 if (ctx->cbs.is_backend_full(ctx->data)) {{
571 /* yes: discard event */
572 ctx->events_discarded++;
577 /* back-end is not full: open new packet */
578 ctx->use_cur_last_event_ts = 1;
579 ctx->cbs.open_packet(ctx->data);
580 ctx->use_cur_last_event_ts = 0;
581 assert(ev_size <= (ctx->packet_size - ctx->at));
588 void _commit_event(void *vctx)
590 struct {prefix}ctx *ctx = FROM_VOID_PTR(struct {prefix}ctx, vctx);
592 /* is packet full? */
593 if ({prefix}packet_is_full(ctx)) {{
594 /* yes: close it now */
595 ctx->cbs.close_packet(ctx->data);
600 _BITFIELD
= '''#ifndef _$PREFIX$BITFIELD_H
601 #define _$PREFIX$BITFIELD_H
606 * Bitfields read/write functions.
608 * Copyright (c) 2010-2020 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
610 * Permission is hereby granted, free of charge, to any person obtaining
611 * a copy of this software and associated documentation files (the
612 * "Software"), to deal in the Software without restriction, including
613 * without limitation the rights to use, copy, modify, merge, publish,
614 * distribute, sublicense, and/or sell copies of the Software, and to
615 * permit persons to whom the Software is furnished to do so, subject to
616 * the following conditions:
618 * The above copyright notice and this permission notice shall be
619 * included in all copies or substantial portions of the Software.
621 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
622 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
623 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
624 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
625 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
626 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
627 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
634 # define CAST_PTR(_type, _value) \\
635 static_cast<_type>(static_cast<void *>(_value))
637 # define CAST_PTR(_type, _value) ((void *) (_value))
640 #define $PREFIX$BYTE_ORDER $ENDIAN_DEF$
642 /* We can't shift a int from 32 bit, >> 32 and << 32 on int is undefined */
643 #define _$prefix$bt_piecewise_rshift(_vtype, _v, _shift) \\
645 unsigned long ___shift = (_shift); \\
646 unsigned long sb = (___shift) / (sizeof(_v) * CHAR_BIT - 1); \\
647 unsigned long final = (___shift) % (sizeof(_v) * CHAR_BIT - 1); \\
650 _v >>= sizeof(_v) * CHAR_BIT - 1; \\
655 * $prefix$bt_bitfield_write - write integer to a bitfield in native endianness
657 * Save integer to the bitfield, which starts at the "start" bit, has "len"
659 * The inside of a bitfield is from high bits to low bits.
660 * Uses native endianness.
661 * For unsigned "v", pad MSB with 0 if bitfield is larger than v.
662 * For signed "v", sign-extend v if bitfield is larger than v.
664 * On little endian, bytes are placed from the less significant to the most
665 * significant. Also, consecutive bitfields are placed from lower bits to higher
668 * On big endian, bytes are places from most significant to less significant.
669 * Also, consecutive bitfields are placed from higher to lower bits.
672 #define _$prefix$bt_bitfield_write_le(_ptr, type, _start, _length, _vtype, _v) \\
674 _vtype __v = (_v); \\
675 type *__ptr = CAST_PTR(type *, _ptr); \\
676 unsigned long __start = (_start), __length = (_length); \\
678 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \\
679 unsigned long start_unit, end_unit, this_unit; \\
680 unsigned long end, cshift; /* cshift is "complement shift" */ \\
685 end = __start + __length; \\
686 start_unit = __start / ts; \\
687 end_unit = (end + (ts - 1)) / ts; \\
689 /* Trim v high bits */ \\
690 if (__length < sizeof(__v) * CHAR_BIT) \\
691 __v &= ~((~(_vtype) 0) << __length); \\
693 /* We can now append v with a simple "or", shift it piece-wise */ \\
694 this_unit = start_unit; \\
695 if (start_unit == end_unit - 1) { \\
696 mask = ~((~(type) 0) << (__start % ts)); \\
698 mask |= (~(type) 0) << (end % ts); \\
699 cmask = (type) __v << (__start % ts); \\
701 __ptr[this_unit] &= mask; \\
702 __ptr[this_unit] |= cmask; \\
705 if (__start % ts) { \\
706 cshift = __start % ts; \\
707 mask = ~((~(type) 0) << cshift); \\
708 cmask = (type) __v << cshift; \\
710 __ptr[this_unit] &= mask; \\
711 __ptr[this_unit] |= cmask; \\
712 _$prefix$bt_piecewise_rshift(_vtype, __v, ts - cshift); \\
713 __start += ts - cshift; \\
716 for (; this_unit < end_unit - 1; this_unit++) { \\
717 __ptr[this_unit] = (type) __v; \\
718 _$prefix$bt_piecewise_rshift(_vtype, __v, ts); \\
722 mask = (~(type) 0) << (end % ts); \\
723 cmask = (type) __v; \\
725 __ptr[this_unit] &= mask; \\
726 __ptr[this_unit] |= cmask; \\
728 __ptr[this_unit] = (type) __v; \\
731 #define _$prefix$bt_bitfield_write_be(_ptr, type, _start, _length, _vtype, _v) \\
733 _vtype __v = (_v); \\
734 type *__ptr = CAST_PTR(type *, _ptr); \\
735 unsigned long __start = (_start), __length = (_length); \\
737 unsigned long ts = sizeof(type) * CHAR_BIT; /* type size */ \\
738 unsigned long start_unit, end_unit, this_unit; \\
739 unsigned long end, cshift; /* cshift is "complement shift" */ \\
744 end = __start + __length; \\
745 start_unit = __start / ts; \\
746 end_unit = (end + (ts - 1)) / ts; \\
748 /* Trim v high bits */ \\
749 if (__length < sizeof(__v) * CHAR_BIT) \\
750 __v &= ~((~(_vtype) 0) << __length); \\
752 /* We can now append v with a simple "or", shift it piece-wise */ \\
753 this_unit = end_unit - 1; \\
754 if (start_unit == end_unit - 1) { \\
755 mask = ~((~(type) 0) << ((ts - (end % ts)) % ts)); \\
757 mask |= (~((type) 0)) << (ts - (__start % ts)); \\
758 cmask = (type) __v << ((ts - (end % ts)) % ts); \\
760 __ptr[this_unit] &= mask; \\
761 __ptr[this_unit] |= cmask; \\
765 cshift = end % ts; \\
766 mask = ~((~(type) 0) << (ts - cshift)); \\
767 cmask = (type) __v << (ts - cshift); \\
769 __ptr[this_unit] &= mask; \\
770 __ptr[this_unit] |= cmask; \\
771 _$prefix$bt_piecewise_rshift(_vtype, __v, cshift); \\
775 for (; (long) this_unit >= (long) start_unit + 1; this_unit--) { \\
776 __ptr[this_unit] = (type) __v; \\
777 _$prefix$bt_piecewise_rshift(_vtype, __v, ts); \\
780 if (__start % ts) { \\
781 mask = (~(type) 0) << (ts - (__start % ts)); \\
782 cmask = (type) __v; \\
784 __ptr[this_unit] &= mask; \\
785 __ptr[this_unit] |= cmask; \\
787 __ptr[this_unit] = (type) __v; \\
791 * $prefix$bt_bitfield_write_le - write integer to a bitfield in little endian
792 * $prefix$bt_bitfield_write_be - write integer to a bitfield in big endian
795 #if ($PREFIX$BYTE_ORDER == LITTLE_ENDIAN)
797 #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \\
798 _$prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v)
800 #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \\
801 _$prefix$bt_bitfield_write_be(ptr, unsigned char, _start, _length, _vtype, _v)
803 #elif ($PREFIX$BYTE_ORDER == BIG_ENDIAN)
805 #define $prefix$bt_bitfield_write_le(ptr, type, _start, _length, _vtype, _v) \\
806 _$prefix$bt_bitfield_write_le(ptr, unsigned char, _start, _length, _vtype, _v)
808 #define $prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v) \\
809 _$prefix$bt_bitfield_write_be(ptr, type, _start, _length, _vtype, _v)
811 #else /* ($PREFIX$BYTE_ORDER == PDP_ENDIAN) */
813 #error "Byte order not supported"
817 #endif /* _$PREFIX$BITFIELD_H */