about summary refs log tree commit diff
path: root/absl/strings/numbers.h
diff options
context:
space:
mode:
Diffstat (limited to 'absl/strings/numbers.h')
-rw-r--r--absl/strings/numbers.h13
1 files changed, 10 insertions, 3 deletions
diff --git a/absl/strings/numbers.h b/absl/strings/numbers.h
index 745de67ad86d..9b8ec89a8941 100644
--- a/absl/strings/numbers.h
+++ b/absl/strings/numbers.h
@@ -37,7 +37,14 @@
 #include <type_traits>
 
 #include "absl/base/internal/bits.h"
+#ifdef __SSE4_2__
+// TODO(jorg): Remove this when we figure out the right way
+// to swap bytes on SSE 4.2 that works with the compilers
+// we claim to support.  Also, add tests for the compiler
+// that doesn't support the Intel _bswap64 intrinsic but
+// does support all the SSE 4.2 intrinsics
 #include "absl/base/internal/endian.h"
+#endif
 #include "absl/base/macros.h"
 #include "absl/base/port.h"
 #include "absl/numeric/int128.h"
@@ -189,12 +196,12 @@ ABSL_MUST_USE_RESULT bool safe_strtoi_base(absl::string_view s, int_type* out,
 // Returns the number of non-pad digits of the output (it can never be zero
 // since 0 has one digit).
 inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) {
-  uint64_t be = absl::big_endian::FromHost64(val);
 #ifdef __SSE4_2__
+  uint64_t be = absl::big_endian::FromHost64(val);
   const auto kNibbleMask = _mm_set1_epi8(0xf);
   const auto kHexDigits = _mm_setr_epi8('0', '1', '2', '3', '4', '5', '6', '7',
                                         '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
-  auto v = _mm_loadu_si64(reinterpret_cast<__m128i*>(&be));  // load lo dword
+  auto v = _mm_loadl_epi64(reinterpret_cast<__m128i*>(&be));  // load lo dword
   auto v4 = _mm_srli_epi64(v, 4);                            // shift 4 right
   auto il = _mm_unpacklo_epi8(v4, v);                        // interleave bytes
   auto m = _mm_and_si128(il, kNibbleMask);                   // mask out nibbles
@@ -202,7 +209,7 @@ inline size_t FastHexToBufferZeroPad16(uint64_t val, char* out) {
   _mm_storeu_si128(reinterpret_cast<__m128i*>(out), hexchars);
 #else
   for (int i = 0; i < 8; ++i) {
-    auto byte = (be >> (8 * i)) & 0xFF;
+    auto byte = (val >> (56 - 8 * i)) & 0xFF;
     auto* hex = &absl::numbers_internal::kHexTable[byte * 2];
     std::memcpy(out + 2 * i, hex, 2);
   }