4 * This header defines the following endian macros as defined here:
5 * http://austingroupbugs.net/view.php?id=162
7 * BYTE_ORDER this macro shall have a value equal to one
8 * of the *_ENDIAN macros in this header.
9 * LITTLE_ENDIAN if BYTE_ORDER == LITTLE_ENDIAN, the host
10 * byte order is from least significant to
12 * BIG_ENDIAN if BYTE_ORDER == BIG_ENDIAN, the host byte
13 * order is from most significant to least
16 * The following are defined as macros:
18 * uint16_t bswap16(uint16_t x);
19 * uint32_t bswap32(uint32_t x);
20 * uint64_t bswap64(uint64_t x);
22 * uint16_t htobe16(uint16_t x);
23 * uint16_t htole16(uint16_t x);
24 * uint16_t be16toh(uint16_t x);
25 * uint16_t le16toh(uint16_t x);
27 * uint32_t htobe32(uint32_t x);
28 * uint32_t htole32(uint32_t x);
29 * uint32_t be32toh(uint32_t x);
30 * uint32_t le32toh(uint32_t x);
32 * uint64_t htobe64(uint64_t x);
33 * uint64_t htole64(uint64_t x);
34 * uint64_t be64toh(uint64_t x);
35 * uint64_t le64toh(uint64_t x);
37 * The header defines the following macro for OpenCL compatibility
39 https://www.khronos.org/registry/cl/sdk/2.0/docs/man/xhtml/preprocessorDirectives.html
41 * __ENDIAN_LITTLE__ if BYTE_ORDER == LITTLE_ENDIAN then this
42 * macro is present for OpenCL compatibility
44 * The implementation provides a uniform interface to endian macros using only
45 * system headers on recent Linux, Darwin, FreeBSD, Solaris and Windows
48 * This approach is intended to avoid the need for preflight configure
50 * An alternative approach would be to test compiler CPU architecture marcros.
52 * This header has had *limited* testing on recent C11/C++11 compilers and is
53 * based on the austin bug tracker interface, manpages, and headers present in
54 * Linux, FreeBSD, Windows, Solaris and Darwin.
56 * The header uses __builtin_bswapXX intrinsic with GCC/Clang (__GNUC__) on
57 * platforms that do not provide bswap16, bswap32, bswap64 (Darwin)
67 #if defined(__linux__) || defined(__GLIBC__)
70 #define __ENDIAN_DEFINED 1
71 #define __BSWAP_DEFINED 1
72 #define __HOSTSWAP_DEFINED 1
73 #define _BYTE_ORDER __BYTE_ORDER
74 #define _LITTLE_ENDIAN __LITTLE_ENDIAN
75 #define _BIG_ENDIAN __BIG_ENDIAN
76 #define bswap16(x) bswap_16(x)
77 #define bswap32(x) bswap_32(x)
78 #define bswap64(x) bswap_64(x)
79 #endif /* __linux__ || __GLIBC__ */
82 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
84 #include <sys/endian.h>
85 #define __ENDIAN_DEFINED 1
86 #define __BSWAP_DEFINED 1
87 #define __HOSTSWAP_DEFINED 1
92 #include <sys/byteorder.h>
93 #include <sys/isa_defs.h>
94 #define bswap16(x) BSWAP_16(x)
95 #define bswap32(x) BSWAP_32(x)
96 #define bswap64(x) BSWAP_64(x)
97 /* sun headers don't set a value for _LITTLE_ENDIAN or _BIG_ENDIAN */
98 #if defined(_LITTLE_ENDIAN)
100 #define _LITTLE_ENDIAN 1234
101 #define _BIG_ENDIAN 4321
102 #define _BYTE_ORDER _LITTLE_ENDIAN
103 #elif defined(_BIG_ENDIAN)
105 #define _LITTLE_ENDIAN 1234
106 #define _BIG_ENDIAN 4321
107 #define _BYTE_ORDER _BIG_ENDIAN
109 #define __ENDIAN_DEFINED 1
113 #if defined(_WIN32) || defined(_MSC_VER)
114 /* assumes all Microsoft targets are little endian */
115 #define _LITTLE_ENDIAN 1234
116 #define _BIG_ENDIAN 4321
117 #define _BYTE_ORDER _LITTLE_ENDIAN
118 #define __ENDIAN_DEFINED 1
119 #endif /* _MSC_VER */
122 #if defined(__APPLE__)
123 #include <machine/endian.h>
124 #define _BYTE_ORDER BYTE_ORDER
125 #define _LITTLE_ENDIAN LITTLE_ENDIAN
126 #define _BIG_ENDIAN BIG_ENDIAN
127 #define __ENDIAN_DEFINED 1
128 #endif /* __APPLE__ */
131 #if defined(__OPENCL_VERSION__)
132 #define _LITTLE_ENDIAN 1234
133 #define __BIG_ENDIAN 4321
134 #if defined(__ENDIAN_LITTLE__)
135 #define _BYTE_ORDER _LITTLE_ENDIAN
137 #define _BYTE_ORDER _BIG_ENDIAN
139 #define bswap16(x) as_ushort(as_uchar2(ushort(x)).s1s0)
140 #define bswap32(x) as_uint(as_uchar4(uint(x)).s3s2s1s0)
141 #define bswap64(x) as_ulong(as_uchar8(ulong(x)).s7s6s5s4s3s2s1s0)
142 #define __ENDIAN_DEFINED 1
143 #define __BSWAP_DEFINED 1
147 #if !__ENDIAN_DEFINED
148 #error Could not determine CPU byte order
151 /* POSIX - http://austingroupbugs.net/view.php?id=162 */
153 #define BYTE_ORDER _BYTE_ORDER
155 #ifndef LITTLE_ENDIAN
156 #define LITTLE_ENDIAN _LITTLE_ENDIAN
159 #define BIG_ENDIAN _BIG_ENDIAN
162 /* OpenCL compatibility - define __ENDIAN_LITTLE__ on little endian systems */
163 #if _BYTE_ORDER == _LITTLE_ENDIAN
164 #if !defined(__ENDIAN_LITTLE__)
165 #define __ENDIAN_LITTLE__ 1
169 /* Byte swap macros */
173 /* handle missing __builtin_bswap16
174 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 */
176 #define bswap16(x) __builtin_bswap16(x)
179 ((uint16_t)((((uint16_t)(x)&0xff00) >> 8) | (((uint16_t)(x)&0x00ff) << 8)))
185 #define bswap32(x) __builtin_bswap32(x)
189 (((uint32_t)(x)&0xff000000) >> 24) | (((uint32_t)(x)&0x00ff0000) >> 8) | \
190 (((uint32_t)(x)&0x0000ff00) << 8) | (((uint32_t)(x)&0x000000ff) << 24)))
196 #define bswap64(x) __builtin_bswap64(x)
199 ((uint64_t)((((uint64_t)(x)&0xff00000000000000ull) >> 56) | \
200 (((uint64_t)(x)&0x00ff000000000000ull) >> 40) | \
201 (((uint64_t)(x)&0x0000ff0000000000ull) >> 24) | \
202 (((uint64_t)(x)&0x000000ff00000000ull) >> 8) | \
203 (((uint64_t)(x)&0x00000000ff000000ull) << 8) | \
204 (((uint64_t)(x)&0x0000000000ff0000ull) << 24) | \
205 (((uint64_t)(x)&0x000000000000ff00ull) << 40) | \
206 (((uint64_t)(x)&0x00000000000000ffull) << 56)))
212 /* Host swap macros */
213 #ifndef __HOSTSWAP_DEFINED
214 #if _BYTE_ORDER == _LITTLE_ENDIAN
215 #define htobe16(x) bswap16((x))
216 #define htole16(x) ((uint16_t)(x))
217 #define be16toh(x) bswap16((x))
218 #define le16toh(x) ((uint16_t)(x))
220 #define htobe32(x) bswap32((x))
221 #define htole32(x) ((uint32_t)(x))
222 #define be32toh(x) bswap32((x))
223 #define le32toh(x) ((uint32_t)(x))
225 #define htobe64(x) bswap64((x))
226 #define htole64(x) ((uint64_t)(x))
227 #define be64toh(x) bswap64((x))
228 #define le64toh(x) ((uint64_t)(x))
229 #elif _BYTE_ORDER == _BIG_ENDIAN
230 #define htobe16(x) ((uint16_t)(x))
231 #define htole16(x) bswap16((x))
232 #define be16toh(x) ((uint16_t)(x))
233 #define le16toh(x) bswap16((x))
235 #define htobe32(x) ((uint32_t)(x))
236 #define htole32(x) bswap32((x))
237 #define be32toh(x) ((uint32_t)(x))
238 #define le64toh(x) bswap64((x))
240 #define htobe64(x) ((uint64_t)(x))
241 #define htole64(x) bswap64((x))
242 #define be64toh(x) ((uint64_t)(x))
243 #define le32toh(x) bswap32((x))