From fe25608edd6fc531b5c865dd511cd438bea2e897 Mon Sep 17 00:00:00 2001 From: Cedric Bail Date: Fri, 4 Oct 2013 12:49:02 +0900 Subject: [PATCH] eina: handle more compiler strangeness for bswap. So current order is : - __builtin_bswap*() for compiler that provide it - _byteswap_*() for MSVC - bswap_*() for older Linux and some BSD - own C code when everything else fall appart. The reason for this order is that the builtin will always generate the best assembly possible. On my system bswap_*() are not changing in all version to the best solution as they are almost equivalent to the C macro. --- configure.ac | 4 ++++ src/lib/eina/eina_config.h.in | 5 +++++ src/lib/eina/eina_inline_cpu.x | 26 +++++++++++++++++++++++++- 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 6ca409e086..77972b8997 100644 --- a/configure.ac +++ b/configure.ac @@ -792,6 +792,10 @@ AC_DEFINE_IF([HAVE_DIRENT_H], [test "x${have_dirent}" = "xyes"], ### Checks for structures ### Checks for compiler characteristics +AC_CHECK_HEADER([byteswap.h], [have_byteswap="yes"], [have_byteswap="no"]) + +EINA_CONFIG([HAVE_BYTESWAP_H], [test "x${have_byteswap}" = "xyes"]) + EFL_CHECK_GCC_BUILTIN([bswap16], [HAVE_BSWAP16]) EFL_CHECK_GCC_BUILTIN([bswap32], [HAVE_BSWAP32]) EFL_CHECK_GCC_BUILTIN([bswap64], [HAVE_BSWAP64]) diff --git a/src/lib/eina/eina_config.h.in b/src/lib/eina/eina_config.h.in index eb0869cf40..27acdf72b6 100644 --- a/src/lib/eina/eina_config.h.in +++ b/src/lib/eina/eina_config.h.in @@ -87,4 +87,9 @@ #endif @EINA_CONFIGURE_HAVE_BSWAP64@ +#ifdef EINA_HAVE_BYTESWAP_H +# undef EINA_HAVE_BYTESWAP_H +#endif +@EINA_CONFIGURE_HAVE_BYTESWAP_H@ + #endif /* EINA_CONFIG_H_ */ diff --git a/src/lib/eina/eina_inline_cpu.x b/src/lib/eina/eina_inline_cpu.x index bdfb4a4b13..18310f7347 100644 --- a/src/lib/eina/eina_inline_cpu.x +++ b/src/lib/eina/eina_inline_cpu.x @@ -23,11 +23,27 @@ #ifndef EINA_INLINE_CPU_X_ #define EINA_INLINE_CPU_X_ +#ifdef EINA_HAVE_BYTESWAP_H +# include +#endif + +#ifdef __has_builtin +# define EINA_HAS_BUILTIN(x) __has_builtin(x) +#elif (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) +# define EINA_HAS_BUILTIN(x) 1 +#else +# define EINA_HAS_BUILTIN(x) 0 // Compatibility for the rest of the world +#endif + static inline unsigned short eina_swap16(unsigned short x) { -#ifdef EINA_HAVE_BSWAP16 +#if defined EINA_HAVE_BSWAP16 && EINA_HAS_BUILTIN(__builtin_bswap16) return __builtin_bswap16(x); +#elif defined _MSC_VER /* Windows. Apparently in . */ + return _byteswap_ushort(x); +#elif defined EINA_HAVE_BYTESWAP_H + return bswap_16(x); #else return (((x & 0xff00) >> 8) | ((x & 0x00ff) << 8)); @@ -39,6 +55,10 @@ eina_swap32(unsigned int x) { #ifdef EINA_HAVE_BSWAP32 return __builtin_bswap32(x); +#elif defined _MSC_VER /* Windows. Apparently in . */ + return _byteswap_ulong(x); +#elif defined EINA_HAVE_BYTESWAP_H + return bswap_32(x); #else return (x >> 24) | ((x >> 8) & 0x0000FF00) | @@ -52,6 +72,10 @@ eina_swap64(unsigned long long x) { #ifdef EINA_HAVE_BSWAP64 return __builtin_bswap64(x); +#elif defined _MSC_VER /* Windows. Apparently in . */ + return _byteswap_uint64(x); +#elif defined EINA_HAVE_BYTESWAP_H + return bswap_64(x); #else return (((x & 0xff00000000000000ull) >> 56) | ((x & 0x00ff000000000000ull) >> 40) |