-static inline
-uint64_t _ctf_bitfield_read_64(const unsigned char *ptr,
- unsigned long start, unsigned long len,
- int byte_order, int signedness)
-{
- long start_unit, end_unit, this_unit;
- unsigned long end, cshift; /* cshift is "complement shift" */
- unsigned long ts = sizeof(unsigned char) * CHAR_BIT;
- unsigned char mask, cmask;
- uint64_t v = 0;
-
- if (!len)
- return 0;
- end = start + len;
- start_unit = start / ts;
- end_unit = (end + (ts - 1)) / ts;
-
- /*
- * We can now fill v piece-wise, from lower bits to upper bits.
- * We read the bitfield in the opposite direction it was written.
- */
- switch (byte_order) {
- case LITTLE_ENDIAN:
- this_unit = end_unit - 1;
- if (signedness) {
- if (ptr[this_unit] & (1U << ((end % ts ? : ts) - 1)))
- v = ~(uint64_t) 0;
- }
- if (start_unit == end_unit - 1) {
- mask = (~(unsigned char) 0) << (end % ts ? : ts);
- mask |= ~((~(unsigned char) 0) << (start % ts));
- cmask = ptr[this_unit];
- cmask &= ~mask;
- cmask >>= (start % ts);
- v <<= end - start;
- v |= cmask;
- break;
- }
- if (end % ts) {
- cshift = (end % ts ? : ts);
- mask = (~(unsigned char) 0) << cshift;
- cmask = ptr[this_unit];
- cmask &= ~mask;
- v <<= cshift;
- v |= (uint64_t) cmask;
- end -= cshift;
- this_unit--;
- }
- for (; this_unit >= start_unit + 1; this_unit--) {
- v <<= ts;
- v |= (uint64_t) ptr[this_unit];
- end -= ts;
- }
- if (start % ts) {
- cmask = ptr[this_unit] >> (start % ts);
- v <<= ts - (start % ts);
- v |= (uint64_t) cmask;
- } else {
- v <<= ts;
- v |= (uint64_t) ptr[this_unit];
- }
- break;
- case BIG_ENDIAN:
- this_unit = start_unit;
- if (signedness) {
- if (ptr[this_unit] & (1U << (ts - (start % ts) - 1)))
- v = ~(uint64_t) 0;
- }
- if (start_unit == end_unit - 1) {
- mask = (~(unsigned char) 0) << (ts - (start % ts));
- mask |= ~((~(unsigned char) 0) << ((ts - (end % ts)) % ts));
- cmask = ptr[this_unit];
- cmask &= ~mask;
- cmask >>= (ts - (end % ts)) % ts;
- v <<= end - start;
- v |= (uint64_t) cmask;
- break;
- }
- if (start % ts) {
- mask = (~(unsigned char) 0) << (ts - (start % ts));
- cmask = ptr[this_unit];
- cmask &= ~mask;
- v <<= ts - (start % ts);
- v |= (uint64_t) cmask;
- start += ts - (start % ts);
- this_unit++;
- }
- for (; this_unit < end_unit - 1; this_unit++) {
- v <<= ts;
- v |= (uint64_t) ptr[this_unit];
- start += ts;
- }
- if (end % ts) {
- cmask = ptr[this_unit];
- cmask >>= (ts - (end % ts)) % ts;
- v <<= (end % ts);
- v |= (uint64_t) cmask;
- } else {
- v <<= ts;
- v |= (uint64_t) ptr[this_unit];
- }
- break;
- default:
- assert(0); /* TODO: support PDP_ENDIAN */
- }
- return v;
-}
-
-static inline
-uint64_t ctf_bitfield_unsigned_read(const uint8_t *ptr,
- unsigned long start, unsigned long len,
- int byte_order)
-{
- return (uint64_t) _ctf_bitfield_read_64(ptr, start, len, byte_order, 0);
-}
-
-static inline
-int64_t ctf_bitfield_signed_read(const uint8_t *ptr,
- unsigned long start, unsigned long len,
- int byte_order)
-{
- return (int64_t) _ctf_bitfield_read_64(ptr, start, len, byte_order, 1);
-}
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+
+#define ctf_bitfield_read(ptr, _start, _length, _vptr) \
+ _ctf_bitfield_read_le(ptr, _start, _length, _vptr)
+
+#define ctf_bitfield_read_le(ptr, _start, _length, _vptr) \
+ _ctf_bitfield_read_le(ptr, _start, _length, _vptr)
+
+#define ctf_bitfield_read_be(ptr, _start, _length, _vptr) \
+ _ctf_bitfield_read_be((const uint8_t *) (ptr), _start, _length, _vptr)
+
+#elif (BYTE_ORDER == BIG_ENDIAN)
+
+#define ctf_bitfield_read(ptr, _start, _length, _vptr) \
+ _ctf_bitfield_read_be(ptr, _start, _length, _vptr)
+
+#define ctf_bitfield_read_le(ptr, _start, _length, _vptr) \
+ _ctf_bitfield_read_le((const uint8_t *) (ptr), _start, _length, _vptr)
+
+#define ctf_bitfield_read_be(ptr, _start, _length, _vptr) \
+ _ctf_bitfield_read_be(ptr, _start, _length, _vptr)
+
+#else /* (BYTE_ORDER == PDP_ENDIAN) */
+
+#error "Byte order not supported"
+
+#endif