ohmu
·
2026-10-15
1#pragma once
2
3#include <stdint.h>
4
5// `__BIG_ENDIAN__` alone is not enough: GCC does not define it, it documents only `__BYTE_ORDER__`
6// and the `__ORDER_*_ENDIAN__` values. Testing the former silently selected the little-endian
7// branch on s390x, where `FF_READ_BE` then byte-swapped values that were already big-endian.
8// `defined(__BIG_ENDIAN__)` alone would not do either: a macro that is defined as 0 is not a
9// big-endian platform.
10#if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || (defined(__BIG_ENDIAN__) && __BIG_ENDIAN__)
11 #define FF_READ_LE(x) _Generic((x), \
12 uint16_t: __builtin_bswap16(x), \
13 uint32_t: __builtin_bswap32(x), \
14 uint64_t: __builtin_bswap64(x))
15 #define FF_READ_BE(x) (x)
16#else
17 #define FF_READ_LE(x) (x)
18 #define FF_READ_BE(x) _Generic((x), \
19 uint16_t: __builtin_bswap16(x), \
20 uint32_t: __builtin_bswap32(x), \
21 uint64_t: __builtin_bswap64(x))
22#endif