[Groonga-commit] groonga/grnxx [master] Add grnxx::byte_swap() and its test.

Back to archive index

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 



More information about the Groonga-commit mailing list
Back to archive index