Fixed __builtin_bswap16 not being available on GCC <4.8

See e.g. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624

Change-Id: Idae99196c47e015a2ba2416aaf1526f77498ce5d
parent c96fc7fc
...@@ -153,32 +153,34 @@ inline void EndianCheck() { ...@@ -153,32 +153,34 @@ inline void EndianCheck() {
template<typename T> T EndianSwap(T t) { template<typename T> T EndianSwap(T t) {
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma push_macro("__builtin_bswap16") #define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
#pragma push_macro("__builtin_bswap32") #define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
#pragma push_macro("__builtin_bswap64") #define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
#define __builtin_bswap16 _byteswap_ushort #else
#define __builtin_bswap32 _byteswap_ulong #if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408
#define __builtin_bswap64 _byteswap_uint64 // __builtin_bswap16 was missing prior to GCC 4.8.
#define FLATBUFFERS_BYTESWAP16(x) \
static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16))
#else
#define FLATBUFFERS_BYTESWAP16 __builtin_bswap16
#endif
#define FLATBUFFERS_BYTESWAP32 __builtin_bswap32
#define FLATBUFFERS_BYTESWAP64 __builtin_bswap64
#endif #endif
if (sizeof(T) == 1) { // Compile-time if-then's. if (sizeof(T) == 1) { // Compile-time if-then's.
return t; return t;
} else if (sizeof(T) == 2) { } else if (sizeof(T) == 2) {
auto r = __builtin_bswap16(*reinterpret_cast<uint16_t *>(&t)); auto r = FLATBUFFERS_BYTESWAP16(*reinterpret_cast<uint16_t *>(&t));
return *reinterpret_cast<T *>(&r); return *reinterpret_cast<T *>(&r);
} else if (sizeof(T) == 4) { } else if (sizeof(T) == 4) {
auto r = __builtin_bswap32(*reinterpret_cast<uint32_t *>(&t)); auto r = FLATBUFFERS_BYTESWAP32(*reinterpret_cast<uint32_t *>(&t));
return *reinterpret_cast<T *>(&r); return *reinterpret_cast<T *>(&r);
} else if (sizeof(T) == 8) { } else if (sizeof(T) == 8) {
auto r = __builtin_bswap64(*reinterpret_cast<uint64_t *>(&t)); auto r = FLATBUFFERS_BYTESWAP64(*reinterpret_cast<uint64_t *>(&t));
return *reinterpret_cast<T *>(&r); return *reinterpret_cast<T *>(&r);
} else { } else {
assert(0); assert(0);
} }
#if defined(_MSC_VER)
#pragma pop_macro("__builtin_bswap16")
#pragma pop_macro("__builtin_bswap32")
#pragma pop_macro("__builtin_bswap64")
#endif
} }
template<typename T> T EndianScalar(T t) { template<typename T> T EndianScalar(T t) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment