xref: /aosp_15_r20/external/emboss/runtime/cpp/emboss_defines.h (revision 99e0aae7469b87d12f0ad23e61142c2d74c1ef70)
1*99e0aae7SDavid Rees // Copyright 2019 Google LLC
2*99e0aae7SDavid Rees //
3*99e0aae7SDavid Rees // Licensed under the Apache License, Version 2.0 (the "License");
4*99e0aae7SDavid Rees // you may not use this file except in compliance with the License.
5*99e0aae7SDavid Rees // You may obtain a copy of the License at
6*99e0aae7SDavid Rees //
7*99e0aae7SDavid Rees //     https://www.apache.org/licenses/LICENSE-2.0
8*99e0aae7SDavid Rees //
9*99e0aae7SDavid Rees // Unless required by applicable law or agreed to in writing, software
10*99e0aae7SDavid Rees // distributed under the License is distributed on an "AS IS" BASIS,
11*99e0aae7SDavid Rees // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*99e0aae7SDavid Rees // See the License for the specific language governing permissions and
13*99e0aae7SDavid Rees // limitations under the License.
14*99e0aae7SDavid Rees 
15*99e0aae7SDavid Rees // This header contains #defines that are used to control Emboss's generated
16*99e0aae7SDavid Rees // code.
17*99e0aae7SDavid Rees //
18*99e0aae7SDavid Rees // These #defines are global, and *must* be defined the same way in every
19*99e0aae7SDavid Rees // translation unit.  In particular, if you use `-D` (or your compiler's
20*99e0aae7SDavid Rees // equivalent) to define some of them on the command line, you *must* pass the
21*99e0aae7SDavid Rees // *exact* same definition when compiling *every* file that #includes any
22*99e0aae7SDavid Rees // Emboss-generated or Emboss-related file, directly or indirectly.  Failure to
23*99e0aae7SDavid Rees // do so will lead to ODR violations and strange behavior.
24*99e0aae7SDavid Rees //
25*99e0aae7SDavid Rees // Rather than using the command line, the Emboss authors recommend that you
26*99e0aae7SDavid Rees // insert an #include of a custom site_defines.h between the two markers below.
27*99e0aae7SDavid Rees //
28*99e0aae7SDavid Rees // If you are using [Copybara][1] to import Emboss into your environment, you
29*99e0aae7SDavid Rees // can use a transform like:
30*99e0aae7SDavid Rees //
31*99e0aae7SDavid Rees //     core.replace(
32*99e0aae7SDavid Rees //         before = '${start_of_line}// #include "MY_SITE_DEFINES.h"',
33*99e0aae7SDavid Rees //         after = '${start_of_line}#include "MY_SITE_DEFINES.h"',
34*99e0aae7SDavid Rees //         paths = ['public/emboss_defines.h'],
35*99e0aae7SDavid Rees //         regex_groups = {
36*99e0aae7SDavid Rees //             'start_of_line': '^',
37*99e0aae7SDavid Rees //         },
38*99e0aae7SDavid Rees //     ),
39*99e0aae7SDavid Rees //
40*99e0aae7SDavid Rees // [1]: https://github.com/google/copybara
41*99e0aae7SDavid Rees //
42*99e0aae7SDavid Rees // If you are using [Bazel][2], be sure to add a dependency from the
43*99e0aae7SDavid Rees // //public:cpp_utils target to a target exporting your custom header:
44*99e0aae7SDavid Rees //
45*99e0aae7SDavid Rees //     core.replace(
46*99e0aae7SDavid Rees //         before = '${leading_whitespace}# "//MY_SITE_DEFINES:TARGET",',
47*99e0aae7SDavid Rees //         after = '${leading_whitespace}"//MY_SITE_DEFINES:TARGET",',
48*99e0aae7SDavid Rees //         paths = ['public/BUILD'],
49*99e0aae7SDavid Rees //         regex_groups = {
50*99e0aae7SDavid Rees //             'leading_whitespace': '^ *',
51*99e0aae7SDavid Rees //         },
52*99e0aae7SDavid Rees //     ),
53*99e0aae7SDavid Rees //
54*99e0aae7SDavid Rees // [2]: https://bazel.build
55*99e0aae7SDavid Rees #ifndef EMBOSS_RUNTIME_CPP_EMBOSS_DEFINES_H_
56*99e0aae7SDavid Rees #define EMBOSS_RUNTIME_CPP_EMBOSS_DEFINES_H_
57*99e0aae7SDavid Rees 
58*99e0aae7SDavid Rees #include <cassert>
59*99e0aae7SDavid Rees 
60*99e0aae7SDavid Rees // START INSERT_INCLUDE_SITE_DEFINES_HERE
61*99e0aae7SDavid Rees // #include "MY_SITE_DEFINES.h"
62*99e0aae7SDavid Rees // END INSERT_INCLUDE_SITE_DEFINES_HERE
63*99e0aae7SDavid Rees 
64*99e0aae7SDavid Rees // EMBOSS_CHECK should abort the program if the given expression evaluates to
65*99e0aae7SDavid Rees // false.
66*99e0aae7SDavid Rees //
67*99e0aae7SDavid Rees // By default, checks are only enabled on non-NDEBUG builds.  (Note that all
68*99e0aae7SDavid Rees // translation units MUST be built with the same value of NDEBUG!)
69*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK)
70*99e0aae7SDavid Rees #define EMBOSS_CHECK(x) assert((x))
71*99e0aae7SDavid Rees #define EMBOSS_CHECK_ABORTS (!(NDEBUG))
72*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK)
73*99e0aae7SDavid Rees 
74*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK_ABORTS)
75*99e0aae7SDavid Rees #error "Custom EMBOSS_CHECK without EMBOSS_CHECK_ABORTS."
76*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK_ABORTS)
77*99e0aae7SDavid Rees 
78*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK_LE)
79*99e0aae7SDavid Rees #define EMBOSS_CHECK_LE(x, y) EMBOSS_CHECK((x) <= (y))
80*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK_LE)
81*99e0aae7SDavid Rees 
82*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK_LT)
83*99e0aae7SDavid Rees #define EMBOSS_CHECK_LT(x, y) EMBOSS_CHECK((x) < (y))
84*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK_LT)
85*99e0aae7SDavid Rees 
86*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK_GE)
87*99e0aae7SDavid Rees #define EMBOSS_CHECK_GE(x, y) EMBOSS_CHECK((x) >= (y))
88*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK_GE)
89*99e0aae7SDavid Rees 
90*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK_GT)
91*99e0aae7SDavid Rees #define EMBOSS_CHECK_GT(x, y) EMBOSS_CHECK((x) > (y))
92*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK_GT)
93*99e0aae7SDavid Rees 
94*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK_EQ)
95*99e0aae7SDavid Rees #define EMBOSS_CHECK_EQ(x, y) EMBOSS_CHECK((x) == (y))
96*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK_EQ)
97*99e0aae7SDavid Rees 
98*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK_NE)
99*99e0aae7SDavid Rees #define EMBOSS_CHECK_NE(x, y) EMBOSS_CHECK((x) == (y))
100*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK_NE)
101*99e0aae7SDavid Rees 
102*99e0aae7SDavid Rees // The EMBOSS_DCHECK macros, by default, work the same way as EMBOSS_CHECK;
103*99e0aae7SDavid Rees // EMBOSS_DCHECK is used as an assert() for logic embedded in Emboss, where
104*99e0aae7SDavid Rees // EMBOSS_CHECK is used to check preconditions on application logic.  Depending
105*99e0aae7SDavid Rees // on how much you trust the correctness of Emboss itself, you may wish to
106*99e0aae7SDavid Rees // disable EMBOSS_DCHECK in situations where you do not disable EMBOSS_CHECK.
107*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK)
108*99e0aae7SDavid Rees #define EMBOSS_DCHECK(x) assert((x))
109*99e0aae7SDavid Rees #define EMBOSS_DCHECK_ABORTS (!(NDEBUG))
110*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK)
111*99e0aae7SDavid Rees 
112*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK_ABORTS)
113*99e0aae7SDavid Rees #error "Custom EMBOSS_DCHECK without EMBOSS_DCHECK_ABORTS."
114*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK_ABORTS)
115*99e0aae7SDavid Rees 
116*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK_LE)
117*99e0aae7SDavid Rees #define EMBOSS_DCHECK_LE(x, y) EMBOSS_DCHECK((x) <= (y))
118*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK_LE)
119*99e0aae7SDavid Rees 
120*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK_LT)
121*99e0aae7SDavid Rees #define EMBOSS_DCHECK_LT(x, y) EMBOSS_DCHECK((x) < (y))
122*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK_LT)
123*99e0aae7SDavid Rees 
124*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK_GE)
125*99e0aae7SDavid Rees #define EMBOSS_DCHECK_GE(x, y) EMBOSS_DCHECK((x) >= (y))
126*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK_GE)
127*99e0aae7SDavid Rees 
128*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK_GT)
129*99e0aae7SDavid Rees #define EMBOSS_DCHECK_GT(x, y) EMBOSS_DCHECK((x) > (y))
130*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK_GT)
131*99e0aae7SDavid Rees 
132*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK_EQ)
133*99e0aae7SDavid Rees #define EMBOSS_DCHECK_EQ(x, y) EMBOSS_DCHECK((x) == (y))
134*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK_EQ)
135*99e0aae7SDavid Rees 
136*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK_NE)
137*99e0aae7SDavid Rees #define EMBOSS_DCHECK_NE(x, y) EMBOSS_DCHECK((x) == (y))
138*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK_NE)
139*99e0aae7SDavid Rees 
140*99e0aae7SDavid Rees // Technically, the mapping from pointers to integers is implementation-defined,
141*99e0aae7SDavid Rees // but the standard states "[ Note: It is intended to be unsurprising to those
142*99e0aae7SDavid Rees // who know the addressing structure of the underlying machine. - end note ],"
143*99e0aae7SDavid Rees // so this should be a reasonably safe way to check that a pointer is aligned.
144*99e0aae7SDavid Rees #if !defined(EMBOSS_DCHECK_POINTER_ALIGNMENT)
145*99e0aae7SDavid Rees #define EMBOSS_DCHECK_POINTER_ALIGNMENT(p, align, offset)                  \
146*99e0aae7SDavid Rees   EMBOSS_DCHECK_EQ(reinterpret_cast</**/ ::std::uintptr_t>((p)) % (align), \
147*99e0aae7SDavid Rees                    (static_cast</**/ ::std::uintptr_t>((offset))))
148*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_DCHECK_POINTER_ALIGNMENT)
149*99e0aae7SDavid Rees 
150*99e0aae7SDavid Rees #if !defined(EMBOSS_CHECK_POINTER_ALIGNMENT)
151*99e0aae7SDavid Rees #define EMBOSS_CHECK_POINTER_ALIGNMENT(p, align, offset)                  \
152*99e0aae7SDavid Rees   EMBOSS_CHECK_EQ(reinterpret_cast</**/ ::std::uintptr_t>((p)) % (align), \
153*99e0aae7SDavid Rees                   static_cast</**/ ::std::uintptr_t>((offset)))
154*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_CHECK_POINTER_ALIGNMENT)
155*99e0aae7SDavid Rees 
156*99e0aae7SDavid Rees // EMBOSS_NO_OPTIMIZATIONS is used to turn off all system-specific
157*99e0aae7SDavid Rees // optimizations.  This is mostly intended for testing, but could be used if
158*99e0aae7SDavid Rees // optimizations are causing problems.
159*99e0aae7SDavid Rees #if !defined(EMBOSS_NO_OPTIMIZATIONS)
160*99e0aae7SDavid Rees #if defined(__GNUC__)  // GCC and "compatible" compilers, such as Clang.
161*99e0aae7SDavid Rees 
162*99e0aae7SDavid Rees // GCC, Clang, and ICC only support two's-complement systems, so it is safe to
163*99e0aae7SDavid Rees // assume two's-complement for those systems.  In particular, this means that
164*99e0aae7SDavid Rees // static_cast<int>() will treat its argument as a two's-complement bit pattern,
165*99e0aae7SDavid Rees // which means that it is reasonable to static_cast<int>(some_unsigned_value).
166*99e0aae7SDavid Rees //
167*99e0aae7SDavid Rees // TODO(bolms): Are there actually any non-archaic systems that use any integer
168*99e0aae7SDavid Rees // types other than 2's-complement?
169*99e0aae7SDavid Rees #if !defined(EMBOSS_SYSTEM_IS_TWOS_COMPLEMENT)
170*99e0aae7SDavid Rees #define EMBOSS_SYSTEM_IS_TWOS_COMPLEMENT 1
171*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_SYSTEM_IS_TWOS_COMPLEMENT)
172*99e0aae7SDavid Rees 
173*99e0aae7SDavid Rees #if !defined(__INTEL_COMPILER)
174*99e0aae7SDavid Rees // On systems with known host byte order, Emboss can always use memcpy to safely
175*99e0aae7SDavid Rees // and relatively efficiently read and write values from and to memory.
176*99e0aae7SDavid Rees // However, memcpy cannot assume that its pointers are aligned.  On common
177*99e0aae7SDavid Rees // platforms, particularly x86, this almost never matters; however, on some
178*99e0aae7SDavid Rees // systems this can add considerable overhead, as memcpy must either perform
179*99e0aae7SDavid Rees // byte-by-byte copies or perform tests to determine pointer alignment and then
180*99e0aae7SDavid Rees // dispatch to alignment-specific code.
181*99e0aae7SDavid Rees //
182*99e0aae7SDavid Rees // Platforms with no alignment restrictions:
183*99e0aae7SDavid Rees //
184*99e0aae7SDavid Rees // * x86 (except for a few SSE instructions like movdqa: see
185*99e0aae7SDavid Rees //   http://pzemtsov.github.io/2016/11/06/bug-story-alignment-on-x86.html)
186*99e0aae7SDavid Rees // * ARM systems with ARMv6 and later ISAs
187*99e0aae7SDavid Rees // * High-end POWER-based systems
188*99e0aae7SDavid Rees // * POWER-based systems with an alignment exception handler installed (but note
189*99e0aae7SDavid Rees //   that emulated unaligned reads are *very* slow)
190*99e0aae7SDavid Rees //
191*99e0aae7SDavid Rees // Platforms with alignment restrictions:
192*99e0aae7SDavid Rees //
193*99e0aae7SDavid Rees // * MicroBlaze
194*99e0aae7SDavid Rees // * Emscripten
195*99e0aae7SDavid Rees // * Low-end bare-metal POWER-based systems
196*99e0aae7SDavid Rees // * ARM systems with ARMv5 and earlier ISAs
197*99e0aae7SDavid Rees // * x86 with the AC bit of EEFLAGS enabled (but note that this is never enabled
198*99e0aae7SDavid Rees //   on any normal system, and, e.g., you will get crashes in glibc if you try
199*99e0aae7SDavid Rees //   to enable it)
200*99e0aae7SDavid Rees //
201*99e0aae7SDavid Rees // The naive solution is to reinterpret_cast to a type like uint32_t, then read
202*99e0aae7SDavid Rees // or write through that pointer; however, this can easily run afoul of C++'s
203*99e0aae7SDavid Rees // type aliasing rules and result in undefined behavior.
204*99e0aae7SDavid Rees //
205*99e0aae7SDavid Rees // On GCC, there is a solution to this: use the "__may_alias__" type attribute,
206*99e0aae7SDavid Rees // which essentially forces the type to have the same aliasing rules as char;
207*99e0aae7SDavid Rees // i.e., it is safe to read and write through a pointer derived from
208*99e0aae7SDavid Rees // reinterpret_cast<T __attribute__((__may_alias__)) *>, just as it is safe to
209*99e0aae7SDavid Rees // read and write through a pointer derived from reinterpret_cast<char *>.
210*99e0aae7SDavid Rees //
211*99e0aae7SDavid Rees // Note that even though ICC pretends to be compatible with GCC by defining
212*99e0aae7SDavid Rees // __GNUC__, it does *not* appear to support the __may_alias__ attribute.
213*99e0aae7SDavid Rees // (TODO(bolms): verify this if/when Emboss explicitly supports ICC.)
214*99e0aae7SDavid Rees //
215*99e0aae7SDavid Rees // Note the lack of parentheses around 't' in the expansion: unfortunately,
216*99e0aae7SDavid Rees // GCC's attribute syntax disallows parentheses in that particular position.
217*99e0aae7SDavid Rees #if !defined(EMBOSS_ALIAS_SAFE_POINTER_CAST)
218*99e0aae7SDavid Rees #define EMBOSS_ALIAS_SAFE_POINTER_CAST(t, x) \
219*99e0aae7SDavid Rees   reinterpret_cast<t __attribute__((__may_alias__)) *>((x))
220*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_LITTLE_ENDIAN_TO_NATIVE)
221*99e0aae7SDavid Rees #endif  // !defined(__INTEL_COMPILER)
222*99e0aae7SDavid Rees 
223*99e0aae7SDavid Rees // GCC supports __BYTE_ORDER__ of __ORDER_LITTLE_ENDIAN__, __ORDER_BIG_ENDIAN__,
224*99e0aae7SDavid Rees // and __ORDER_PDP_ENDIAN__.  Since all available test systems are
225*99e0aae7SDavid Rees // __ORDER_LITTLE_ENDIAN__, only little-endian hosts get optimized code paths;
226*99e0aae7SDavid Rees // however, big-endian support ought to be trivial to add.
227*99e0aae7SDavid Rees //
228*99e0aae7SDavid Rees // There are no plans to support PDP-endian systems.
229*99e0aae7SDavid Rees #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
230*99e0aae7SDavid Rees // EMBOSS_LITTLE_ENDIAN_TO_NATIVE and EMBOSS_BIG_ENDIAN_TO_NATIVE can be used to
231*99e0aae7SDavid Rees // fix up integers after a little- or big-endian value has been memcpy'ed into
232*99e0aae7SDavid Rees // them.
233*99e0aae7SDavid Rees //
234*99e0aae7SDavid Rees // On little-endian systems, no fixup is needed for little-endian sources, but
235*99e0aae7SDavid Rees // big-endian sources require a byte swap.
236*99e0aae7SDavid Rees #if !defined(EMBOSS_LITTLE_ENDIAN_TO_NATIVE)
237*99e0aae7SDavid Rees #define EMBOSS_LITTLE_ENDIAN_TO_NATIVE(x) (x)
238*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_LITTLE_ENDIAN_TO_NATIVE)
239*99e0aae7SDavid Rees 
240*99e0aae7SDavid Rees #if !defined(EMBOSS_NATIVE_TO_LITTLE_ENDIAN)
241*99e0aae7SDavid Rees #define EMBOSS_NATIVE_TO_LITTLE_ENDIAN(x) (x)
242*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_NATIVE_TO_LITTLE_ENDIAN)
243*99e0aae7SDavid Rees 
244*99e0aae7SDavid Rees #if !defined(EMBOSS_BIG_ENDIAN_TO_NATIVE)
245*99e0aae7SDavid Rees #define EMBOSS_BIG_ENDIAN_TO_NATIVE(x) (::emboss::support::ByteSwap((x)))
246*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_BIG_ENDIAN_TO_NATIVE)
247*99e0aae7SDavid Rees 
248*99e0aae7SDavid Rees #if !defined(EMBOSS_NATIVE_TO_BIG_ENDIAN)
249*99e0aae7SDavid Rees #define EMBOSS_NATIVE_TO_BIG_ENDIAN(x) (::emboss::support::ByteSwap((x)))
250*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_NATIVE_TO_BIG_ENDIAN)
251*99e0aae7SDavid Rees 
252*99e0aae7SDavid Rees // TODO(bolms): Find a way to test on a big-endian architecture, and add support
253*99e0aae7SDavid Rees // for __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
254*99e0aae7SDavid Rees #endif  // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
255*99e0aae7SDavid Rees 
256*99e0aae7SDavid Rees // Prior to version 4.8, __builtin_bswap16 was not available on all platforms.
257*99e0aae7SDavid Rees // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624
258*99e0aae7SDavid Rees //
259*99e0aae7SDavid Rees // Clang pretends to be an earlier GCC, but does support __builtin_bswap16.
260*99e0aae7SDavid Rees // Clang recommends using __has_builtin(__builtin_bswap16), but unfortunately
261*99e0aae7SDavid Rees // that fails to compile on GCC, even with defined(__has_builtin) &&
262*99e0aae7SDavid Rees // __has_builtin(__builtin_bswap16), so instead Emboss just checks for
263*99e0aae7SDavid Rees // defined(__clang__).
264*99e0aae7SDavid Rees #if !defined(EMBOSS_BYTESWAP16)
265*99e0aae7SDavid Rees #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || defined(__clang__)
266*99e0aae7SDavid Rees #define EMBOSS_BYTESWAP16(x) __builtin_bswap16((x))
267*99e0aae7SDavid Rees #endif  // __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
268*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_BYTESWAP16)
269*99e0aae7SDavid Rees 
270*99e0aae7SDavid Rees #if !defined(EMBOSS_BYTESWAP32)
271*99e0aae7SDavid Rees #define EMBOSS_BYTESWAP32(x) __builtin_bswap32((x))
272*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_BYTESWAP32)
273*99e0aae7SDavid Rees 
274*99e0aae7SDavid Rees #if !defined(EMBOSS_BYTESWAP64)
275*99e0aae7SDavid Rees #define EMBOSS_BYTESWAP64(x) __builtin_bswap64((x))
276*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_BYTESWAP64)
277*99e0aae7SDavid Rees 
278*99e0aae7SDavid Rees #endif  // defined(__GNUC__)
279*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_NO_OPTIMIZATIONS)
280*99e0aae7SDavid Rees 
281*99e0aae7SDavid Rees #if !defined(EMBOSS_SYSTEM_IS_TWOS_COMPLEMENT)
282*99e0aae7SDavid Rees #define EMBOSS_SYSTEM_IS_TWOS_COMPLEMENT 0
283*99e0aae7SDavid Rees #endif  // !defined(EMBOSS_SYSTEM_IS_TWOS_COMPLEMENT)
284*99e0aae7SDavid Rees 
285*99e0aae7SDavid Rees #endif  // EMBOSS_RUNTIME_CPP_EMBOSS_DEFINES_H_
286