diff --git a/configure.ac b/configure.ac index bf11bd9..7554549 100644 --- a/configure.ac +++ b/configure.ac @@ -72,6 +72,7 @@ AM_CONDITIONAL(OS_QNX, test "$os_qnx" = "true") LT_INIT([disable-static win32-dll pic-only]) AC_CHECK_HEADERS([ \ arpa/inet.h \ + byteswap.h \ errno.h \ fcntl.h \ limits.h \ diff --git a/src/modbus-data.c b/src/modbus-data.c index 134d134..fab4919 100644 --- a/src/modbus-data.c +++ b/src/modbus-data.c @@ -24,10 +24,35 @@ #endif #include #include -#include #include "modbus.h" +#if defined(HAVE_BYTESWAP_H) +# include +#endif + +#if defined(__GNUC__) +# define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__ * 10) +# if GCC_VERSION >= 430 +// Since GCC >= 4.30, GCC provides __builtin_bswapXX() alternatives so we switch to them +# undef bswap_32 +# define bswap_32 __builtin_bswap32 +# endif +#endif + +#if !defined (bswap_16) || !defined (bswap_32) +# warning "Fallback on C functions for bswap_32" +static inline uint16_t bswap_16(uint16_t x) +{ + return (x >> 8) | (x << 8); +} + +static inline uint32_t bswap_32(uint32_t x) +{ + return (bswap_16(x & 0xffff) << 16) | (bswap_16(x >> 16)); +} +#endif + /* Sets many bits from a single byte value (all 8 bits of the byte value are set) */ void modbus_set_bits_from_byte(uint8_t *dest, int index, const uint8_t value)