From: Owen Yamauchi Date: Fri, 3 May 2013 17:43:36 +0000 (-0700) Subject: Break dependency on byteswap.h X-Git-Tag: v0.22.0~983 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=29ad1ec90ccf41d985a69de6c59f0fde1a9e4502;p=folly.git Break dependency on byteswap.h Summary: Unfortunately, this doesn't exist on all platforms. Fortunately, both gcc and clang support builtins that do the same thing as the bswap_* functions we were including byteswap.h for. I changed the test file to hardcode expected results for the swapping functions. Is that OK? It seemed a little silly to be testing the Endian::whatever functions by comparing them against the functions that they're implemented in terms of. Test Plan: fbconfig/fbmake runtests with gcc 4.6 and 4.7. Verified separately that clang supports these builtins. Reviewed By: simpkins@fb.com FB internal diff: D799244 --- diff --git a/folly/Bits.h b/folly/Bits.h index b206968b..d9bf1ad0 100644 --- a/folly/Bits.h +++ b/folly/Bits.h @@ -65,11 +65,15 @@ #error GCC required #endif +#include "folly/folly-config.h" #include "folly/detail/BitsDetail.h" #include "folly/detail/BitIteratorDetail.h" #include "folly/Likely.h" -#include +#if FOLLY_HAVE_BYTESWAP_H +# include +#endif + #include #include #include @@ -230,19 +234,37 @@ struct EndianIntBase { static T swap(T x); }; +/** + * If we have the bswap_16 macro from byteswap.h, use it; otherwise, provide our + * own definition. + */ +#ifdef bswap_16 +# define our_bswap16 bswap_16 +#else + +template +inline constexpr typename std::enable_if< + sizeof(Int16) == 2, + Int16>::type +our_bswap16(Int16 x) { + return ((x >> 8) & 0xff) | ((x & 0xff) << 8); +} +#endif + #define FB_GEN(t, fn) \ template<> inline t EndianIntBase::swap(t x) { return fn(x); } // fn(x) expands to (x) if the second argument is empty, which is exactly -// what we want for [u]int8_t +// what we want for [u]int8_t. Also, gcc 4.7 on Intel doesn't have +// __builtin_bswap16 for some reason, so we have to provide our own. FB_GEN( int8_t,) FB_GEN(uint8_t,) -FB_GEN( int64_t, bswap_64) -FB_GEN(uint64_t, bswap_64) -FB_GEN( int32_t, bswap_32) -FB_GEN(uint32_t, bswap_32) -FB_GEN( int16_t, bswap_16) -FB_GEN(uint16_t, bswap_16) +FB_GEN( int64_t, __builtin_bswap64) +FB_GEN(uint64_t, __builtin_bswap64) +FB_GEN( int32_t, __builtin_bswap32) +FB_GEN(uint32_t, __builtin_bswap32) +FB_GEN( int16_t, our_bswap16) +FB_GEN(uint16_t, our_bswap16) #undef FB_GEN diff --git a/folly/configure.ac b/folly/configure.ac index 8ec537db..38927fb9 100644 --- a/folly/configure.ac +++ b/folly/configure.ac @@ -38,7 +38,7 @@ AX_BOOST_SYSTEM # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stdint.h stdlib.h string.h sys/time.h unistd.h mutex.h malloc.h emmintrin.h]) +AC_CHECK_HEADERS([fcntl.h inttypes.h limits.h stdint.h stdlib.h string.h sys/time.h unistd.h mutex.h malloc.h emmintrin.h byteswap.h]) AC_CHECK_HEADER(double-conversion.h, [], [AC_MSG_ERROR( [Couldn't find double-conversion.h, please download from \ diff --git a/folly/test/EndianTest.cpp b/folly/test/EndianTest.cpp index e2e5cd81..cc65d803 100644 --- a/folly/test/EndianTest.cpp +++ b/folly/test/EndianTest.cpp @@ -22,13 +22,13 @@ using namespace folly; TEST(Endian, Basic) { uint8_t v8 = 0x12; - uint8_t v8s = v8; + uint8_t v8s = 0x12; uint16_t v16 = 0x1234; - uint16_t v16s = bswap_16(v16); + uint16_t v16s = 0x3412; uint32_t v32 = 0x12345678; - uint32_t v32s = bswap_32(v32); + uint32_t v32s = 0x78563412; uint64_t v64 = 0x123456789abcdef0ULL; - uint64_t v64s = bswap_64(v64); + uint64_t v64s = 0xf0debc9a78563412ULL; #if __BYTE_ORDER == __LITTLE_ENDIAN