 +install(EXPORT ${targetsFile} DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake ${nameSpace})
 +install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
 +install(DIRECTORY python DESTINATION ${CMAKE_INSTALL_PREFIX} ${optionalInstall})
+diff --git a/WirehairCodec.cpp b/WirehairCodec.cpp
+index c1ec664..6523aa0 100644
+--- a/WirehairCodec.cpp
++++ b/WirehairCodec.cpp
+@@ -1149,26 +1149,30 @@ bool Codec::TriangleNonHeavy()
+ 
+ #if defined(CAT_HEAVY_WIN_MULT)
+ 
+-#if defined(CAT_ENDIAN_BIG)
+-
++  namespace
++  {
++    bool isLittleEndian()
++    {
++      short int number = 0x1;
++      char* numPtr = (char*)&number;
++      return (numPtr[0] == 1);
++    }
++  }
+ // Flip endianness at compile time if possible
+-static uint32_t GF256_MULT_LOOKUP[16] = {
++  static uint32_t GF256_MULT_LOOKUP_BIG[16] = {
+     0x00000000, 0x01000000, 0x00010000, 0x01010000, 
+     0x00000100, 0x01000100, 0x00010100, 0x01010100, 
+     0x00000001, 0x01000001, 0x00010001, 0x01010001, 
+     0x00000101, 0x01000101, 0x00010101, 0x01010101, 
+ };
+ 
+-#else
+-
+ // Little-endian or unknown bit order:
+-static uint32_t GF256_MULT_LOOKUP[16] = {
++  static uint32_t GF256_MULT_LOOKUP_LITTLE[16] = {
+     0x00000000, 0x00000001, 0x00000100, 0x00000101, 
+     0x00010000, 0x00010001, 0x00010100, 0x00010101, 
+     0x01000000, 0x01000001, 0x01000100, 0x01000101, 
+     0x01010000, 0x01010001, 0x01010100, 0x01010101, 
+ };
+-#endif
+ 
+ #endif // CAT_HEAVY_WIN_MULT
+ 
+@@ -1178,7 +1182,8 @@ bool Codec::Triangle()
+     CAT_IF_DUMP(cout << endl << "---- Triangle ----" << endl << endl;)
+ 
+     const unsigned first_heavy_column = _first_heavy_column;
+-
++    uint32_t* GF256_MULT_LOOKUP =
++      isLittleEndian() ? GF256_MULT_LOOKUP_LITTLE : GF256_MULT_LOOKUP_BIG;
+     // If next pivot is not heavy:
+     if (_next_pivot < first_heavy_column &&
+         !TriangleNonHeavy())
+@@ -1281,7 +1286,7 @@ bool Codec::Triangle()
+                         rem_row[ge_column_i - first_heavy_column] ^= code_value;
+                     }
+                 }
+-#else // CAT_HEAVY_WIN_MULT
++#else  // CAT_HEAVY_WIN_MULT
+                 const unsigned odd_count = pivot_i & 3;
+                 unsigned ge_column_i = pivot_i + 1;
+                 uint64_t temp_mask = ge_mask;
+@@ -1329,11 +1334,8 @@ bool Codec::Triangle()
+                 {
+                     // Look up 4 bit window
+                     const uint32_t bits = (uint32_t)(pivot_row[ge_column_i >> 6] >> (ge_column_i & 63)) & 15;
+-#if defined(CAT_ENDIAN_UNKNOWN)
+-                    const uint32_t window = getLE(GF256_MULT_LOOKUP[bits]);
+-#else
++
+                     const uint32_t window = GF256_MULT_LOOKUP[bits];
+-#endif
+ 
+                     CAT_IF_DUMP(cout << " " << ge_column_i << "x" << hex << setw(8) << setfill('0') << window << dec;)
+ 
+@@ -2523,7 +2525,9 @@ void Codec::BackSubstituteAboveDiagonal()
+             } // end if contains heavy
+ 
+             // Only add window table entries for rows under this limit
+-            const uint16_t window_row_limit = (pivot_i >= first_heavy_column) ? first_heavy_row : 0x7fff;
++          const uint16_t window_row_limit = (pivot_i >= first_heavy_column)
++                                              ? first_heavy_row
++                                              : uint16_t(0x7fff);
+ 
+             const uint32_t first_word = backsub_i >> 6;
+             const uint32_t shift0 = backsub_i & 63;
+@@ -2709,7 +2713,7 @@ void Codec::BackSubstituteAboveDiagonal()
+             }
+         } // next pivot above
+ 
+-        if (pivot_i <= 0) {
++      if (pivot_i == 0) {
+             break;
+         }
+         --pivot_i;
+diff --git a/WirehairTools.cpp b/WirehairTools.cpp
+index dfd6585..84ccb24 100644
+--- a/WirehairTools.cpp
++++ b/WirehairTools.cpp
+@@ -331,7 +331,7 @@ void AddInvertibleGF2Matrix(
+         target -= written0;
+         prev = word0;
+ 
+-        if (target <= 0) {
++      if (target == 0) {
+             continue;
+         }
+ 
+@@ -388,9 +388,8 @@ void ShuffleDeck16(
+             uint32_t jj, rv = prng.Next();
+ 
+             // 8-bit unroll
+-            switch (count - ii)
++        if (count - ii == 3)
+             {
+-            default:
+                 jj = (uint8_t)rv % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+@@ -402,29 +401,48 @@ void ShuffleDeck16(
+                 jj = (uint8_t)(rv >> 16) % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+-                ++ii;
+-                jj = (uint8_t)(rv >> 24) % ii;
++          return;
++        }
++        else if (count - ii == 2)
++        {
++          jj = (uint8_t)(rv >> 8) % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+                 ++ii;
+-                break;
+-
+-            case 3:
++          jj = (uint8_t)(rv >> 16) % ii;
++          deck[ii] = deck[jj];
++          deck[jj] = (uint16_t)ii;
++          return;
++        }
++        else if (count - ii == 1)
++        {
++          jj = (uint8_t)(rv >> 16) % ii;
++          deck[ii] = deck[jj];
++          deck[jj] = (uint16_t)ii;
++          return;
++        }
++        else if (count - ii == 0)
++        {
++          return;
++        }
++        else
++        {
+                 jj = (uint8_t)rv % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+                 ++ii;
+-            case 2:
+                 jj = (uint8_t)(rv >> 8) % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+                 ++ii;
+-            case 1:
+                 jj = (uint8_t)(rv >> 16) % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+-            case 0:
+-                return;
++          ++ii;
++          jj = (uint8_t)(rv >> 24) % ii;
++          deck[ii] = deck[jj];
++          deck[jj] = (uint16_t)ii;
++          ++ii;
+             }
+         }
+     }
+@@ -436,25 +454,27 @@ void ShuffleDeck16(
+             uint32_t jj, rv = prng.Next();
+ 
+             // 16-bit unroll
+-            switch (count - ii)
++        if (count - ii == 1)
+             {
+-            default:
+                 jj = (uint16_t)rv % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+-                ++ii;
+-                jj = (uint16_t)(rv >> 16) % ii;
++          return;
++        }
++        else if (count - ii == 0)
++        {
++          return;
++        }
++        else
++        {
++          jj = (uint16_t)rv % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+                 ++ii;
+-                break;
+-
+-            case 1:
+-                jj = (uint16_t)rv % ii;
++          jj = (uint16_t)(rv >> 16) % ii;
+                 deck[ii] = deck[jj];
+                 deck[jj] = (uint16_t)ii;
+-            case 0:
+-                return;
++          ++ii;
+             }
+         }
+     }
 diff --git a/WirehairTools.h b/WirehairTools.h
 index 8340df5..f8b3251 100644
 --- a/WirehairTools.h

 // Compiler-specific debug break
diff --git a/cm256.cpp b/cm256.cpp
new file mode 100644
index 0000000..b51ff8f
--- /dev/null
+++ b/cm256.cpp
@@ -0,0 +1,603 @@
+/*
+	Copyright (c) 2015 Christopher A. Taylor.  All rights reserved.
+

+
+#endif // CM256_H
diff --git a/gf256.h b/include/wirehair/gf256.h
similarity index 87%
rename from gf256.h
rename to include/wirehair/gf256.h
index c618c0d..1fbd7dd 100644
--- a/gf256.h
+++ b/include/wirehair/gf256.h
@@ -53,51 +53,20 @@
 //------------------------------------------------------------------------------
 // Platform/Architecture
 
-#if defined(ANDROID) || defined(IOS) || defined(LINUX_ARM) || defined(__powerpc__) || defined(__s390__)
-    #define GF256_TARGET_MOBILE
-#endif // ANDROID
-
-#if defined(__AVX2__) || (defined (_MSC_VER) && _MSC_VER >= 1900)
-    #define GF256_TRY_AVX2 /* 256-bit */
-    #include <immintrin.h>
-    #define GF256_ALIGN_BYTES 32
-#else // __AVX2__
+//#define GF256_TRY_AVX2 /* 256-bit */
+//#include <immintrin.h>
+//#define GF256_ALIGN_BYTES 32
     #define GF256_ALIGN_BYTES 16
-#endif // __AVX2__
 
-#if !defined(GF256_TARGET_MOBILE)
     // Note: MSVC currently only supports SSSE3 but not AVX2
     #include <tmmintrin.h> // SSSE3: _mm_shuffle_epi8
     #include <emmintrin.h> // SSE2
-#endif // GF256_TARGET_MOBILE
-
-#if defined(HAVE_ARM_NEON_H)
-    #include <arm_neon.h>
-#endif // HAVE_ARM_NEON_H
-
-#if defined(GF256_TARGET_MOBILE)
-
-    #define GF256_ALIGNED_ACCESSES /* Inputs must be aligned to GF256_ALIGN_BYTES */
-
-# if defined(HAVE_ARM_NEON_H)
-    // Compiler-specific 128-bit SIMD register keyword
-    #define GF256_M128 uint8x16_t
-    #define GF256_TRY_NEON
-#else
-    #define GF256_M128 uint64_t
-# endif
-
-#else // GF256_TARGET_MOBILE
 
     // Compiler-specific 128-bit SIMD register keyword
     #define GF256_M128 __m128i
 
-#endif // GF256_TARGET_MOBILE
-
-#ifdef GF256_TRY_AVX2
     // Compiler-specific 256-bit SIMD register keyword
     #define GF256_M256 __m256i
-#endif
 
 // Compiler-specific C++11 restrict keyword
 #define GF256_RESTRICT __restrict
@@ -110,7 +79,6 @@
 #endif
 
 // Compiler-specific alignment keyword
-// Note: Alignment only matters for ARM NEON where it should be 16
 #ifdef _MSC_VER
     #define GF256_ALIGNED __declspec(align(GF256_ALIGN_BYTES))
 #else // _MSC_VER
@@ -147,13 +115,11 @@ struct gf256_ctx
         GF256_ALIGNED GF256_M128 TABLE_LO_Y[256];
         GF256_ALIGNED GF256_M128 TABLE_HI_Y[256];
     } MM128;
-#ifdef GF256_TRY_AVX2
-    struct
+  /*struct
     {
-        GF256_ALIGNED GF256_M256 TABLE_LO_Y[256];
-        GF256_ALIGNED GF256_M256 TABLE_HI_Y[256];
-    } MM256;
-#endif // GF256_TRY_AVX2
+  GF256_ALIGNED GF256_M256 TABLE_LO_Y[256];
+  GF256_ALIGNED GF256_M256 TABLE_HI_Y[256];
+  } MM256;*/
 
     /// Mul/Div/Inv/Sqr tables
     uint8_t GF256_MUL_TABLE[256 * 256];
diff --git a/include/wirehair/wirehair.h b/include/wirehair/wirehair.h
index 451368a..165a657 100644
--- a/include/wirehair/wirehair.h
+++ b/include/wirehair/wirehair.h
@@ -46,23 +46,7 @@
 
 #define WIREHAIR_VERSION 2
 
-// Tweak if the functions are exported or statically linked
-//#define WIREHAIR_DLL /* Defined when building/linking as DLL */
-//#define WIREHAIR_BUILDING /* Defined by the library makefile */
-
-#if defined(WIREHAIR_BUILDING)
-# if defined(WIREHAIR_DLL) && defined(_WIN32)
-    #define WIREHAIR_EXPORT __declspec(dllexport)
-# else
-    #define WIREHAIR_EXPORT
-# endif
-#else
-# if defined(WIREHAIR_DLL) && defined(_WIN32)
-    #define WIREHAIR_EXPORT __declspec(dllimport)
-# else
     #define WIREHAIR_EXPORT extern
-# endif
-#endif
 
 #include <stdint.h>
 
diff --git a/tables/HeavyRowGenerator.cpp b/tables/HeavyRowGenerator.cpp
index c8ec0c8..c3050a6 100644
--- a/tables/HeavyRowGenerator.cpp
