From 39f119e28040baca93952f191850df27d9880282 Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Sat, 30 May 2020 01:48:31 +0300 Subject: [PATCH] Auto-detect bswap operations --- source/m3_config_platforms.h | 64 ++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/source/m3_config_platforms.h b/source/m3_config_platforms.h index e4391ea..ac8c359 100644 --- a/source/m3_config_platforms.h +++ b/source/m3_config_platforms.h @@ -191,6 +191,18 @@ * Detect/define features */ +# ifdef __has_feature +# define M3_COMPILER_HAS_FEATURE(x) __has_feature(x) +# else +# define M3_COMPILER_HAS_FEATURE(x) 0 +# endif + +# ifdef __has_builtin +# define M3_COMPILER_HAS_BUILTIN(x) __has_builtin(x) +# else +# define M3_COMPILER_HAS_BUILTIN(x) 0 +# endif + # if defined(M3_COMPILER_MSVC) # include # if UINTPTR_MAX == 0xFFFFFFFF @@ -218,11 +230,57 @@ // Byte swapping (for Big-Endian systems only) +# if defined(_MSC_VER) +# define m3_bswap16(x) _byteswap_ushort((x)) +# define m3_bswap32(x) _byteswap_ulong((x)) +# define m3_bswap64(x) _byteswap_uint64((x)) +# elif defined(__GNUC__) && __GNUC_PREREQ(4, 8) +// __builtin_bswap32/64 added in gcc 4.3, __builtin_bswap16 added in gcc 4.8 +# define m3_bswap16(x) __builtin_bswap16((x)) +# define m3_bswap32(x) __builtin_bswap32((x)) +# define m3_bswap64(x) __builtin_bswap64((x)) +# elif M3_COMPILER_HAS_BUILTIN(__builtin_bswap16) +# define m3_bswap16(x) __builtin_bswap16((x)) +# define m3_bswap32(x) __builtin_bswap32((x)) +# define m3_bswap64(x) __builtin_bswap64((x)) +# else +# include +# if defined(__bswap_16) +# define m3_bswap16(x) __bswap_16((x)) +# define m3_bswap32(x) __bswap_32((x)) +# define m3_bswap64(x) __bswap_64((x)) +# else +# warning "Using naive (probably slow) bswap operations" + static inline + uint16_t m3_bswap16(uint16_t x) { + return ((( x >> 8 ) & 0xffu ) | (( x & 0xffu ) << 8 )); + } + static inline + uint32_t m3_bswap32(uint32_t x) { + return ((( x & 0xff000000u ) >> 24 ) | + (( x & 0x00ff0000u ) >> 8 ) | + (( x & 0x0000ff00u ) << 8 ) | + (( x & 0x000000ffu ) << 24 )); + } + static inline + uint64_t m3_bswap64(uint64_t x) { + return ((( x & 0xff00000000000000ull ) >> 56 ) | + (( x & 0x00ff000000000000ull ) >> 40 ) | + (( x & 0x0000ff0000000000ull ) >> 24 ) | + (( x & 0x000000ff00000000ull ) >> 8 ) | + (( x & 0x00000000ff000000ull ) << 8 ) | + (( x & 0x0000000000ff0000ull ) << 24 ) | + (( x & 0x000000000000ff00ull ) << 40 ) | + (( x & 0x00000000000000ffull ) << 56 )); + } +# endif +# endif + # if defined(M3_BIG_ENDIAN) # define M3_BSWAP_u8(X) {} -# define M3_BSWAP_u16(X) { (X)=__builtin_bswap16((X)); } -# define M3_BSWAP_u32(X) { (X)=__builtin_bswap32((X)); } -# define M3_BSWAP_u64(X) { (X)=__builtin_bswap64((X)); } +# define M3_BSWAP_u16(X) { (X)=m3_bswap16((X)); } +# define M3_BSWAP_u32(X) { (X)=m3_bswap32((X)); } +# define M3_BSWAP_u64(X) { (X)=m3_bswap64((X)); } # define M3_BSWAP_i8(X) {} # define M3_BSWAP_i16(X) M3_BSWAP_u16(X) # define M3_BSWAP_i32(X) M3_BSWAP_u32(X)