Commit 29ad1ec9 authored by Owen Yamauchi's avatar Owen Yamauchi Committed by Sara Golemon

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
parent ce4dec4c
...@@ -65,11 +65,15 @@ ...@@ -65,11 +65,15 @@
#error GCC required #error GCC required
#endif #endif
#include "folly/folly-config.h"
#include "folly/detail/BitsDetail.h" #include "folly/detail/BitsDetail.h"
#include "folly/detail/BitIteratorDetail.h" #include "folly/detail/BitIteratorDetail.h"
#include "folly/Likely.h" #include "folly/Likely.h"
#include <byteswap.h> #if FOLLY_HAVE_BYTESWAP_H
# include <byteswap.h>
#endif
#include <cassert> #include <cassert>
#include <cinttypes> #include <cinttypes>
#include <endian.h> #include <endian.h>
...@@ -230,19 +234,37 @@ struct EndianIntBase { ...@@ -230,19 +234,37 @@ struct EndianIntBase {
static T swap(T x); 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<class Int16>
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) \ #define FB_GEN(t, fn) \
template<> inline t EndianIntBase<t>::swap(t x) { return fn(x); } template<> inline t EndianIntBase<t>::swap(t x) { return fn(x); }
// fn(x) expands to (x) if the second argument is empty, which is exactly // 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( int8_t,)
FB_GEN(uint8_t,) FB_GEN(uint8_t,)
FB_GEN( int64_t, bswap_64) FB_GEN( int64_t, __builtin_bswap64)
FB_GEN(uint64_t, bswap_64) FB_GEN(uint64_t, __builtin_bswap64)
FB_GEN( int32_t, bswap_32) FB_GEN( int32_t, __builtin_bswap32)
FB_GEN(uint32_t, bswap_32) FB_GEN(uint32_t, __builtin_bswap32)
FB_GEN( int16_t, bswap_16) FB_GEN( int16_t, our_bswap16)
FB_GEN(uint16_t, bswap_16) FB_GEN(uint16_t, our_bswap16)
#undef FB_GEN #undef FB_GEN
......
...@@ -38,7 +38,7 @@ AX_BOOST_SYSTEM ...@@ -38,7 +38,7 @@ AX_BOOST_SYSTEM
# Checks for header files. # Checks for header files.
AC_HEADER_STDC 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( AC_CHECK_HEADER(double-conversion.h, [], [AC_MSG_ERROR(
[Couldn't find double-conversion.h, please download from \ [Couldn't find double-conversion.h, please download from \
......
...@@ -22,13 +22,13 @@ using namespace folly; ...@@ -22,13 +22,13 @@ using namespace folly;
TEST(Endian, Basic) { TEST(Endian, Basic) {
uint8_t v8 = 0x12; uint8_t v8 = 0x12;
uint8_t v8s = v8; uint8_t v8s = 0x12;
uint16_t v16 = 0x1234; uint16_t v16 = 0x1234;
uint16_t v16s = bswap_16(v16); uint16_t v16s = 0x3412;
uint32_t v32 = 0x12345678; uint32_t v32 = 0x12345678;
uint32_t v32s = bswap_32(v32); uint32_t v32s = 0x78563412;
uint64_t v64 = 0x123456789abcdef0ULL; uint64_t v64 = 0x123456789abcdef0ULL;
uint64_t v64s = bswap_64(v64); uint64_t v64s = 0xf0debc9a78563412ULL;
#if __BYTE_ORDER == __LITTLE_ENDIAN #if __BYTE_ORDER == __LITTLE_ENDIAN
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment