Skip to content

Commit

Permalink
COMMON: Extend endianness intrinsic functions
Browse files Browse the repository at this point in the history
  • Loading branch information
Nostritius authored and DrMcCoy committed Aug 6, 2020
1 parent 833b918 commit a37c6a5
Showing 1 changed file with 34 additions and 7 deletions.
41 changes: 34 additions & 7 deletions src/common/endianness.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@
#error No endianness defined
#endif

// Compatibility with non-clang compilers
// https://www.boost.org/doc/libs/1_61_0/boost/endian/detail/intrinsic.hpp
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif

#define SWAP_CONSTANT_64(a) \
((uint64)((((a) >> 56) & 0x000000FF) | \
(((a) >> 40) & 0x0000FF00) | \
Expand All @@ -78,8 +84,9 @@
((uint16)((((a) >> 8) & 0x00FF) | \
(((a) << 8) & 0xFF00) ))

// Test for GCC >= 4.3.0 as this version added the bswap builtin
#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
// Test for GCC >= 4.3.0 as this version added the bswap32/bswap64 builtin. Also test for availability in Clang.
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) || \
(defined(__clang__) && __has_builtin(__builtin_bswap32) && __has_builtin(__builtin_bswap64))

FORCEINLINE uint64 SWAP_BYTES_64(uint64 a) {
return __builtin_bswap64(a);
Expand All @@ -89,7 +96,7 @@
return __builtin_bswap32(a);
}

// test for MSVC 7 or newer
// Test for MSVC 7 or newer
#elif defined(_MSC_VER) && _MSC_VER >= 1300

#include <cstdlib>
Expand All @@ -102,7 +109,7 @@
return _byteswap_ulong(a);
}

// generic fallback
// Generic fallback
#else

static inline uint64 SWAP_BYTES_64(uint64 a) {
Expand All @@ -125,9 +132,29 @@

#endif

static inline uint16 SWAP_BYTES_16(const uint16 a) {
return (a >> 8) | (a << 8);
}
// Test for GCC >= 4.8 and Clang with bswap16 support
#if (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \
(defined(__clang__) && __has_builtin(__builtin_bswap16))

FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
return __builtin_bswap16(a);
}

// Test for MSVC 7 or newer
#elif defined(_MSC_VER) && _MSC_VER >= 1300

FORCEINLINE uint16 SWAP_BYTES_16(const uint16 a) {
return _byteswap_ushort(a);
}

// Generic fallback
#else

static inline uint16 SWAP_BYTES_16(const uint16 a) {
return (a >> 8) | (a << 8);
}

#endif

/**
* A wrapper macro used around four character constants, like 'DATA', to
Expand Down

0 comments on commit a37c6a5

Please sign in to comment.