From 969e7308bec2aa6150e3cb174c3e12640f4ea0f6 Mon Sep 17 00:00:00 2001 From: ac-stef Date: Thu, 31 Mar 2016 20:06:54 +0200 Subject: [PATCH] fix generic byteswap code also, make use of builtins --- source/src/tools.h | 42 ++++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/source/src/tools.h b/source/src/tools.h index 796a2f87..29543fb2 100644 --- a/source/src/tools.h +++ b/source/src/tools.h @@ -834,15 +834,21 @@ typedef unsigned long long int uint64_t; #endif const int islittleendian = 1; #ifdef SDL_BYTEORDER -#define endianswap16 SDL_Swap16 -#define endianswap32 SDL_Swap32 -#define endianswap64 SDL_Swap64 + #define endianswap16 SDL_Swap16 + #define endianswap32 SDL_Swap32 + #define endianswap64 SDL_Swap64 #else -inline ushort endianswap16(ushort n) { return (n<<8) | (n>>8); } -inline uint endianswap32(uint n) { return (n<<24) | (n>>24) | ((n>>8)&0xFF00) | ((n<<8)&0xFF0000); } -inline uint64_t endianswap64(uint64_t n) { return ((uint64_t)endianswap32((uint)n) << 32) | ((uint64_t)endianswap32((uint)(n >> 32))); } + #if defined(__GNUC__) && /*!defined(__clang__) && */!defined(__ICL) && __GNUC__ >= 4 && !defined(WIN32) && !defined(__APPLE__) + inline ushort endianswap16(ushort n) { return __builtin_bswap16(n); } + inline uint endianswap32(uint n) { return __builtin_bswap32(n); } + inline uint64_t endianswap64(uint64_t n) { return __builtin_bswap64(n); } + #else + inline ushort endianswap16(ushort n) { return (n<<8) | (n>>8); } + inline uint endianswap32(uint n) { return (n<<24) | (n>>24) | ((n>>8)&0xFF00) | ((n<<8)&0xFF0000); } + inline uint64_t endianswap64(uint64_t n) { return ((uint64_t)endianswap32((uint)n) << 32) | ((uint64_t)endianswap32((uint)(n >> 32))); } + #endif #endif -template inline T endianswap(T n) { union { T t; uint i; } conv; conv.t = n; conv.i = endianswap32(conv.i); return conv.t; } +template inline T endianswap(T n) { union { T t; uchar u[sizeof(T)]; } s, d; s.t = n; loopi(sizeof(T)) d.u[i] = s.u[sizeof(T) - 1 - i]; return d.t; } template<> inline ushort endianswap(ushort n) { return endianswap16(n); } template<> inline short endianswap(short n) { return endianswap16(n); } template<> inline uint endianswap(uint n) { return endianswap32(n); } @@ -852,18 +858,18 @@ template inline void endianswap(T *buf, int len) { for(T *end = &buf[le template inline T endiansame(T n) { return n; } template inline void endiansame(T *buf, int len) {} #ifdef SDL_BYTEORDER -#if SDL_BYTEORDER == SDL_LIL_ENDIAN -#define lilswap endiansame -#define bigswap endianswap + #if SDL_BYTEORDER == SDL_LIL_ENDIAN + #define lilswap endiansame + #define bigswap endianswap + #else + #define lilswap endianswap + #define bigswap endiansame + #endif #else -#define lilswap endianswap -#define bigswap endiansame -#endif -#else -template inline T lilswap(T n) { return *(const uchar *)&islittleendian ? n : endianswap(n); } -template inline void lilswap(T *buf, int len) { if(!*(const uchar *)&islittleendian) endianswap(buf, len); } -template inline T bigswap(T n) { return *(const uchar *)&islittleendian ? endianswap(n) : n; } -template inline void bigswap(T *buf, int len) { if(*(const uchar *)&islittleendian) endianswap(buf, len); } + template inline T lilswap(T n) { return *(const uchar *)&islittleendian ? n : endianswap(n); } + template inline void lilswap(T *buf, int len) { if(!*(const uchar *)&islittleendian) endianswap(buf, len); } + template inline T bigswap(T n) { return *(const uchar *)&islittleendian ? endianswap(n) : n; } + template inline void bigswap(T *buf, int len) { if(*(const uchar *)&islittleendian) endianswap(buf, len); } #endif #define uint2ip(address, ip) uchar ip[4]; \