1 /*
2 Copyright Rene Rivera 2013-2015
3 Distributed under the Boost Software License, Version 1.0.
4 (See accompanying file LICENSE_1_0.txt or copy at
5 http://www.boost.org/LICENSE_1_0.txt)
6 */
7 
8 #ifndef BOOST_PREDEF_ENDIAN_H
9 #define BOOST_PREDEF_ENDIAN_H
10 
11 #include <boost/predef/version_number.h>
12 #include <boost/predef/make.h>
13 #include <boost/predef/library/c/gnu.h>
14 #include <boost/predef/os/macos.h>
15 #include <boost/predef/os/bsd.h>
16 #include <boost/predef/platform/android.h>
17 
18 /* tag::reference[]
19 = `BOOST_ENDIAN_*`
20 
21 Detection of endian memory ordering. There are four defined macros
22 in this header that define the various generally possible endian
23 memory orderings:
24 
25 * `BOOST_ENDIAN_BIG_BYTE`, byte-swapped big-endian.
26 * `BOOST_ENDIAN_BIG_WORD`, word-swapped big-endian.
27 * `BOOST_ENDIAN_LITTLE_BYTE`, byte-swapped little-endian.
28 * `BOOST_ENDIAN_LITTLE_WORD`, word-swapped little-endian.
29 
30 The detection is conservative in that it only identifies endianness
31 that it knows for certain. In particular bi-endianness is not
32 indicated as is it not practically possible to determine the
33 endianness from anything but an operating system provided
34 header. And the currently known headers do not define that
35 programatic bi-endianness is available.
36 
37 This implementation is a compilation of various publicly available
38 information and acquired knowledge:
39 
40 . The indispensable documentation of "Pre-defined Compiler Macros"
41   http://sourceforge.net/p/predef/wiki/Endianness[Endianness].
42 . The various endian specifications available in the
43   http://wikipedia.org/[Wikipedia] computer architecture pages.
44 . Generally available searches for headers that define endianness.
45 */ // end::reference[]
46 
47 #define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE
48 #define BOOST_ENDIAN_BIG_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE
49 #define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_NOT_AVAILABLE
50 #define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_NOT_AVAILABLE
51 
52 /* GNU libc provides a header defining __BYTE_ORDER, or _BYTE_ORDER.
53  * And some OSs provide some for of endian header also.
54  */
55 #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
56     !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
57 #   if BOOST_LIB_C_GNU || BOOST_PLAT_ANDROID || BOOST_OS_BSD_OPEN
58 #       include <endian.h>
59 #   else
60 #       if BOOST_OS_MACOS
61 #           include <machine/endian.h>
62 #       else
63 #           if BOOST_OS_BSD
64 #               include <sys/endian.h>
65 #           endif
66 #       endif
67 #   endif
68 #   if defined(__BYTE_ORDER)
69 #       if defined(__BIG_ENDIAN) && (__BYTE_ORDER == __BIG_ENDIAN)
70 #           undef BOOST_ENDIAN_BIG_BYTE
71 #           define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
72 #       endif
73 #       if defined(__LITTLE_ENDIAN) && (__BYTE_ORDER == __LITTLE_ENDIAN)
74 #           undef BOOST_ENDIAN_LITTLE_BYTE
75 #           define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
76 #       endif
77 #       if defined(__PDP_ENDIAN) && (__BYTE_ORDER == __PDP_ENDIAN)
78 #           undef BOOST_ENDIAN_LITTLE_WORD
79 #           define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE
80 #       endif
81 #   endif
82 #   if !defined(__BYTE_ORDER) && defined(_BYTE_ORDER)
83 #       if defined(_BIG_ENDIAN) && (_BYTE_ORDER == _BIG_ENDIAN)
84 #           undef BOOST_ENDIAN_BIG_BYTE
85 #           define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
86 #       endif
87 #       if defined(_LITTLE_ENDIAN) && (_BYTE_ORDER == _LITTLE_ENDIAN)
88 #           undef BOOST_ENDIAN_LITTLE_BYTE
89 #           define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
90 #       endif
91 #       if defined(_PDP_ENDIAN) && (_BYTE_ORDER == _PDP_ENDIAN)
92 #           undef BOOST_ENDIAN_LITTLE_WORD
93 #           define BOOST_ENDIAN_LITTLE_WORD BOOST_VERSION_NUMBER_AVAILABLE
94 #       endif
95 #   endif
96 #endif
97 
98 /* Built-in byte-swapped big-endian macros.
99  */
100 #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
101     !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
102 #   if (defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__)) || \
103        (defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN)) || \
104         defined(__ARMEB__) || \
105         defined(__THUMBEB__) || \
106         defined(__AARCH64EB__) || \
107         defined(_MIPSEB) || \
108         defined(__MIPSEB) || \
109         defined(__MIPSEB__)
110 #       undef BOOST_ENDIAN_BIG_BYTE
111 #       define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
112 #   endif
113 #endif
114 
115 /* Built-in byte-swapped little-endian macros.
116  */
117 #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
118     !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
119 #   if (defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)) || \
120        (defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)) || \
121         defined(__ARMEL__) || \
122         defined(__THUMBEL__) || \
123         defined(__AARCH64EL__) || \
124         defined(_MIPSEL) || \
125         defined(__MIPSEL) || \
126         defined(__MIPSEL__) || \
127         defined(__riscv) || \
128         defined(__e2k__)
129 #       undef BOOST_ENDIAN_LITTLE_BYTE
130 #       define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
131 #   endif
132 #endif
133 
134 /* Some architectures are strictly one endianess (as opposed
135  * the current common bi-endianess).
136  */
137 #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
138     !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
139 #   include <boost/predef/architecture.h>
140 #   if BOOST_ARCH_M68K || \
141         BOOST_ARCH_PARISC || \
142         BOOST_ARCH_SPARC || \
143         BOOST_ARCH_SYS370 || \
144         BOOST_ARCH_SYS390 || \
145         BOOST_ARCH_Z
146 #       undef BOOST_ENDIAN_BIG_BYTE
147 #       define BOOST_ENDIAN_BIG_BYTE BOOST_VERSION_NUMBER_AVAILABLE
148 #   endif
149 #   if BOOST_ARCH_IA64 || \
150         BOOST_ARCH_X86 || \
151         BOOST_ARCH_BLACKFIN
152 #       undef BOOST_ENDIAN_LITTLE_BYTE
153 #       define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
154 #   endif
155 #endif
156 
157 /* Windows on ARM, if not otherwise detected/specified, is always
158  * byte-swapped little-endian.
159  */
160 #if !BOOST_ENDIAN_BIG_BYTE && !BOOST_ENDIAN_BIG_WORD && \
161     !BOOST_ENDIAN_LITTLE_BYTE && !BOOST_ENDIAN_LITTLE_WORD
162 #   if BOOST_ARCH_ARM
163 #       include <boost/predef/os/windows.h>
164 #       if BOOST_OS_WINDOWS
165 #           undef BOOST_ENDIAN_LITTLE_BYTE
166 #           define BOOST_ENDIAN_LITTLE_BYTE BOOST_VERSION_NUMBER_AVAILABLE
167 #       endif
168 #   endif
169 #endif
170 
171 #if BOOST_ENDIAN_BIG_BYTE
172 #   define BOOST_ENDIAN_BIG_BYTE_AVAILABLE
173 #endif
174 #if BOOST_ENDIAN_BIG_WORD
175 #   define BOOST_ENDIAN_BIG_WORD_BYTE_AVAILABLE
176 #endif
177 #if BOOST_ENDIAN_LITTLE_BYTE
178 #   define BOOST_ENDIAN_LITTLE_BYTE_AVAILABLE
179 #endif
180 #if BOOST_ENDIAN_LITTLE_WORD
181 #   define BOOST_ENDIAN_LITTLE_WORD_BYTE_AVAILABLE
182 #endif
183 
184 #define BOOST_ENDIAN_BIG_BYTE_NAME "Byte-Swapped Big-Endian"
185 #define BOOST_ENDIAN_BIG_WORD_NAME "Word-Swapped Big-Endian"
186 #define BOOST_ENDIAN_LITTLE_BYTE_NAME "Byte-Swapped Little-Endian"
187 #define BOOST_ENDIAN_LITTLE_WORD_NAME "Word-Swapped Little-Endian"
188 
189 #endif
190 
191 #include <boost/predef/detail/test.h>
192 BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_BYTE,BOOST_ENDIAN_BIG_BYTE_NAME)
193 
194 #include <boost/predef/detail/test.h>
195 BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_BIG_WORD,BOOST_ENDIAN_BIG_WORD_NAME)
196 
197 #include <boost/predef/detail/test.h>
198 BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_BYTE,BOOST_ENDIAN_LITTLE_BYTE_NAME)
199 
200 #include <boost/predef/detail/test.h>
201 BOOST_PREDEF_DECLARE_TEST(BOOST_ENDIAN_LITTLE_WORD,BOOST_ENDIAN_LITTLE_WORD_NAME)
202