susumu.yata
null+****@clear*****
Mon Apr 15 22:56:09 JST 2013
susumu.yata 2013-04-15 22:56:09 +0900 (Mon, 15 Apr 2013) New Revision: c667359be2a969a1a2e778ec4d5a2bc23481fe20 https://github.com/groonga/grnxx/commit/c667359be2a969a1a2e778ec4d5a2bc23481fe20 Message: Add grnxx::byte_swap() and its test. Modified files: lib/grnxx/features.hpp lib/grnxx/intrinsic.hpp test/test_intrinsic.cpp Modified: lib/grnxx/features.hpp (+4 -0) =================================================================== --- lib/grnxx/features.hpp 2013-04-15 17:14:01 +0900 (f6414f8) +++ lib/grnxx/features.hpp 2013-04-15 22:56:09 +0900 (606dc5c) @@ -106,6 +106,9 @@ #endif // GRNXX_CLANG #ifdef GRNXX_CLANG +# if GRNXX_CLANG_HAS(__builtin_bswap16) +# define GRNXX_HAS_GNUC_BUILTIN_BSWAP +# endif // GRNXX_CLANG_HAS(__builtin_clz) # if GRNXX_CLANG_HAS(__builtin_clz) # define GRNXX_HAS_GNUC_BUILTIN_CLZ # endif // GRNXX_CLANG_HAS(__builtin_clz) @@ -122,6 +125,7 @@ # define GRNXX_HAS_GNUC_BUILTIN_CLZ # if GRNXX_GNUC_VERSION >= GRNXX_GNUC_MAKE_VERSION(4, 2, 0) # define GRNXX_HAS_GNUC_BUILTIN_SYNC +# define GRNXX_HAS_GNUC_BUILTIN_BSWAP # endif // GRNXX_GNUC_VERSION >= GRNXX_GNUC_MAKE_VERSION(4, 2, 0) # if GRNXX_GNUC_VERSION >= GRNXX_GNUC_MAKE_VERSION(4, 7, 0) # define GRNXX_HAS_GNUC_BUILTIN_ATOMIC Modified: lib/grnxx/intrinsic.hpp (+53 -0) =================================================================== --- lib/grnxx/intrinsic.hpp 2013-04-15 17:14:01 +0900 (6d92a2b) +++ lib/grnxx/intrinsic.hpp 2013-04-15 22:56:09 +0900 (18f1cc1) @@ -54,6 +54,13 @@ inline uint8_t bit_scan_reverse(Value value); template <typename Value> inline uint8_t bit_scan_forward(Value value); +// byte_swap() returns the byte-swapped value. +// For example, byte_swap(0x12345678U) returns 0x78564312U. +inline uint8_t byte_swap(uint8_t value); +inline uint16_t byte_swap(uint16_t value); +inline uint32_t byte_swap(uint32_t value); +inline uint64_t byte_swap(uint64_t value); + // atomic_compare_and_swap() atomically performs the following. // if (*value == expected) { // *value = desired; @@ -248,6 +255,52 @@ class Intrinsic { typedef volatile InternalValue *InternalPointer; }; +// Implementation of byte_swap. + +inline uint8_t byte_swap(uint8_t value) { + return value; +} + +inline uint16_t byte_swap(uint16_t value) { +#ifdef GRNXX_MSC + return ::_byteswap_ushort(value); +#elif defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) + return ::__builtin_bswap16(value); +#else // defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) + return (value << 8) | (value >> 8); +#endif // defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) +} + +inline uint32_t byte_swap(uint32_t value) { +#ifdef GRNXX_MSC + return ::_byteswap_ulong(value); +#elif defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) + return ::__builtin_bswap32(value); +#else // defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) + return (value << 24) | + ((value & (0xFF << 8)) << 8) | + ((value & (0xFF << 16)) >> 8) | + (value >> 24); +#endif // defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) +} + +inline uint64_t byte_swap(uint64_t value) { +#ifdef GRNXX_MSC + return ::_byteswap_uint64(value); +#elif defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) + return ::__builtin_bswap64(value); +#else // defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) + return (value << 56) | + ((value & (0xFFULL << 8)) << 40) | + ((value & (0xFFULL << 16)) << 24) | + ((value & (0xFFULL << 24)) << 8) | + ((value & (0xFFULL << 32)) >> 8) | + ((value & (0xFFULL << 40)) >> 24) | + ((value & (0xFFULL << 48)) >> 40) | + (value >> 56); +#endif // defined(GRNXX_HAS_GNUC_BUILTIN_BSWAP) +} + // Implementation of atomic_compare_and_swap. #ifdef GRNXX_MSC Modified: test/test_intrinsic.cpp (+9 -0) =================================================================== --- test/test_intrinsic.cpp 2013-04-15 17:14:01 +0900 (4b4a715) +++ test/test_intrinsic.cpp 2013-04-15 22:56:09 +0900 (19c04b2) @@ -32,6 +32,15 @@ void test_basics() { assert(grnxx::bit_scan_forward(std::uint32_t(1) << 30) == 30); assert(grnxx::bit_scan_forward(std::uint64_t(1) << 63) == 63); + assert(grnxx::byte_swap(static_cast<std::uint8_t>(0x12)) == + static_cast<std::uint8_t>(0x12)); + assert(grnxx::byte_swap(static_cast<std::uint16_t>(0x1234)) == + static_cast<std::uint16_t>(0x3412)); + assert(grnxx::byte_swap(static_cast<std::uint32_t>(0x12345678U)) == + static_cast<std::uint32_t>(0x78563412U)); + assert(grnxx::byte_swap(static_cast<std::uint64_t>(0x123456789ABCDEF0ULL)) == + static_cast<std::uint64_t>(0xF0DEBC9A78563412ULL)); + volatile std::int32_t value_32 = 0; assert(grnxx::atomic_fetch_and_add(5, &value_32) == 0); assert(grnxx::atomic_fetch_and_add(-10, &value_32) == 5); -------------- next part -------------- HTML����������������������������...Download