Update generate_varint_tables to support MSVC
authorChristopher Dykes <cdykes@fb.com>
Tue, 24 May 2016 20:57:25 +0000 (13:57 -0700)
committerFacebook Github Bot 4 <facebook-github-bot-4-bot@fb.com>
Tue, 24 May 2016 21:08:38 +0000 (14:08 -0700)
Summary: MSVC is a massive pain in this respect, and, after testing many workarounds, and only ending up with it just emitting a dynamic initializer for them, it's easier to just generate the table as a `uint64_t` and load it explicitly.

Reviewed By: yfeldblum

Differential Revision: D3270226

fbshipit-source-id: 77bc84e58d393373de05a28a30dcb80b66c09c9f

folly/GroupVarint.h
folly/build/generate_varint_tables.py

index b17d15f7f331625de0deb41feca30f2922b5e5ac..2dfb09b6e4b964258abaf283fedb50d9c0eaeb07 100644 (file)
@@ -37,7 +37,7 @@
 #include <nmmintrin.h>
 namespace folly {
 namespace detail {
-extern const __m128i groupVarintSSEMasks[];
+alignas(16) extern const uint64_t groupVarintSSEMasks[];
 }  // namespace detail
 }  // namespace folly
 #endif
@@ -196,7 +196,8 @@ class GroupVarint<uint32_t> : public detail::GroupVarintBase<uint32_t> {
   static const char* decode(const char* p, uint32_t* dest) {
     uint8_t key = p[0];
     __m128i val = _mm_loadu_si128((const __m128i*)(p+1));
-    __m128i mask = detail::groupVarintSSEMasks[key];
+    __m128i mask =
+        _mm_load_si128((const __m128i*)&detail::groupVarintSSEMasks[key * 2]);
     __m128i r = _mm_shuffle_epi8(val, mask);
     _mm_storeu_si128((__m128i*)dest, r);
     return p + detail::groupVarintLengths[key];
@@ -210,7 +211,8 @@ class GroupVarint<uint32_t> : public detail::GroupVarintBase<uint32_t> {
                             uint32_t* c, uint32_t* d) {
     uint8_t key = p[0];
     __m128i val = _mm_loadu_si128((const __m128i*)(p+1));
-    __m128i mask = detail::groupVarintSSEMasks[key];
+    __m128i mask =
+        _mm_load_si128((const __m128i*)&detail::groupVarintSSEMasks[key * 2]);
     __m128i r = _mm_shuffle_epi8(val, mask);
 
     // Extracting 32 bits at a time out of an XMM register is a SSE4 feature
index 96bfd1d13d080237e522fd6e9ee36bc759172419..bf082d99df3bc11374bf48e65930af1b3ae70b88 100755 (executable)
@@ -56,15 +56,11 @@ def generate(f):
 
 #include <stdint.h>
 
-#if (FOLLY_X64 || defined(__i386__)) && (FOLLY_SSE >= 2)
-#include <x86intrin.h>
-#endif
-
 namespace folly {
 namespace detail {
 
 #if (FOLLY_X64 || defined(__i386__)) && (FOLLY_SSE >= 2)
-extern const __m128i groupVarintSSEMasks[] = {
+alignas(16) extern const uint64_t groupVarintSSEMasks[512] = {
 """)
 
     # Compute SSE masks
@@ -81,8 +77,8 @@ extern const __m128i groupVarintSSEMasks[] = {
             # 0xff: set corresponding byte in result to 0
             for k in range(d, 4):
                 vals[j] |= 0xff << (8 * k)
-        f.write("  {{static_cast<int64_t>(0x{1:08x}{0:08x}), "
-            "static_cast<int64_t>(0x{3:08x}{2:08x})}},\n".format(*vals))
+        f.write("  0x{1:08x}{0:08x}ULL, "
+            "0x{3:08x}{2:08x}ULL,\n".format(*vals))
 
     f.write("};\n"
         "#endif /*#if (FOLLY_X64 || defined(__i386__)) && (FOLLY_SSE >= 2)*/\n"