Optimize some macros
[hashcat.git] / OpenCL / types_ocl.c
index 17e3d69..8104039 100644 (file)
@@ -18,7 +18,7 @@ typedef ulong  u64;
 #define VECT_SIZE 1
 #endif
 
-#define CONCAT(a, b)        a##b
+#define CONCAT(a, b)       a##b
 #define VTYPE(type, width) CONCAT(type, width)
 
 #if VECT_SIZE == 1
@@ -33,17 +33,14 @@ typedef VTYPE(uint,   VECT_SIZE) u32x;
 typedef VTYPE(ulong,  VECT_SIZE) u64x;
 #endif
 
-// this one needs to die
-#define allx(r) r
-
-static inline u32 l32_from_64_S (u64 a)
+inline u32 l32_from_64_S (u64 a)
 {
   const u32 r = (u32) (a);
 
   return r;
 }
 
-static inline u32 h32_from_64_S (u64 a)
+inline u32 h32_from_64_S (u64 a)
 {
   a >>= 32;
 
@@ -52,12 +49,12 @@ static inline u32 h32_from_64_S (u64 a)
   return r;
 }
 
-static inline u64 hl32_to_64_S (const u32 a, const u32 b)
+inline u64 hl32_to_64_S (const u32 a, const u32 b)
 {
   return as_ulong ((uint2) (b, a));
 }
 
-static inline u32x l32_from_64 (u64x a)
+inline u32x l32_from_64 (u64x a)
 {
   u32x r;
 
@@ -96,7 +93,7 @@ static inline u32x l32_from_64 (u64x a)
   return r;
 }
 
-static inline u32x h32_from_64 (u64x a)
+inline u32x h32_from_64 (u64x a)
 {
   a >>= 32;
 
@@ -137,7 +134,7 @@ static inline u32x h32_from_64 (u64x a)
   return r;
 }
 
-static inline u64x hl32_to_64 (const u32x a, const u32x b)
+inline u64x hl32_to_64 (const u32x a, const u32x b)
 {
   u64x r;
 
@@ -177,34 +174,28 @@ static inline u64x hl32_to_64 (const u32x a, const u32x b)
 }
 
 #ifdef IS_AMD
-static inline u32 swap32_S (const u32 v)
+inline u32 swap32_S (const u32 v)
 {
   return (as_uint (as_uchar4 (v).s3210));
 }
 
-static inline u64 swap64_S (const u64 v)
+inline u64 swap64_S (const u64 v)
 {
   return (as_ulong (as_uchar8 (v).s76543210));
 }
 
-static inline u32 rotr32_S (const u32 a, const u32 n)
+inline u32 rotr32_S (const u32 a, const u32 n)
 {
   return rotate (a, 32 - n);
 }
 
-static inline u32 rotl32_S (const u32 a, const u32 n)
+inline u32 rotl32_S (const u32 a, const u32 n)
 {
   return rotate (a, n);
 }
 
-static inline u64 rotr64_S (const u64 a, const u32 n)
+inline u64 rotr64_S (const u64 a, const u32 n)
 {
-  #if DEVICE_TYPE == DEVICE_TYPE_CPU
-
-  const u64 r = rotate (a, (u64) 64 - n);
-
-  #else
-
   const u32 a0 = h32_from_64_S (a);
   const u32 a1 = l32_from_64_S (a);
 
@@ -213,17 +204,15 @@ static inline u64 rotr64_S (const u64 a, const u32 n)
 
   const u64 r = hl32_to_64_S (t0, t1);
 
-  #endif
-
   return r;
 }
 
-static inline u64 rotl64_S (const u64 a, const u32 n)
+inline u64 rotl64_S (const u64 a, const u32 n)
 {
   return rotr64_S (a, 64 - n);
 }
 
-static inline u32x swap32 (const u32x v)
+inline u32x swap32 (const u32x v)
 {
   return ((v >> 24) & 0x000000ff)
        | ((v >>  8) & 0x0000ff00)
@@ -231,7 +220,7 @@ static inline u32x swap32 (const u32x v)
        | ((v << 24) & 0xff000000);
 }
 
-static inline u64x swap64 (const u64x v)
+inline u64x swap64 (const u64x v)
 {
   return ((v >> 56) & 0x00000000000000ff)
        | ((v >> 40) & 0x000000000000ff00)
@@ -243,24 +232,18 @@ static inline u64x swap64 (const u64x v)
        | ((v << 56) & 0xff00000000000000);
 }
 
-static inline u32x rotr32 (const u32x a, const u32 n)
+inline u32x rotr32 (const u32x a, const u32 n)
 {
   return rotate (a, 32 - n);
 }
 
-static inline u32x rotl32 (const u32x a, const u32 n)
+inline u32x rotl32 (const u32x a, const u32 n)
 {
   return rotate (a, n);
 }
 
-static inline u64x rotr64 (const u64x a, const u32 n)
+inline u64x rotr64 (const u64x a, const u32 n)
 {
-  #if DEVICE_TYPE == DEVICE_TYPE_CPU
-
-  const u64x r = rotate (a, (u64) 64 - n);
-
-  #else
-
   const u32x a0 = h32_from_64 (a);
   const u32x a1 = l32_from_64 (a);
 
@@ -269,29 +252,27 @@ static inline u64x rotr64 (const u64x a, const u32 n)
 
   const u64x r = hl32_to_64 (t0, t1);
 
-  #endif
-
   return r;
 }
 
-static inline u64x rotl64 (const u64x a, const u32 n)
+inline u64x rotl64 (const u64x a, const u32 n)
 {
   return rotr64 (a, 64 - n);
 }
 
-static inline u32 __bfe (const u32 a, const u32 b, const u32 c)
+inline u32 __bfe (const u32 a, const u32 b, const u32 c)
 {
   return amd_bfe (a, b, c);
 }
 
-static inline u32 amd_bytealign_S (const u32 a, const u32 b, const u32 c)
+inline u32 amd_bytealign_S (const u32 a, const u32 b, const u32 c)
 {
   return amd_bytealign (a, b, c);
 }
 #endif
 
 #ifdef IS_NV
-static inline u32 swap32_S (const u32 v)
+inline u32 swap32_S (const u32 v)
 {
   u32 r;
 
@@ -300,7 +281,7 @@ static inline u32 swap32_S (const u32 v)
   return r;
 }
 
-static inline u64 swap64_S (const u64 v)
+inline u64 swap64_S (const u64 v)
 {
   u32 il;
   u32 ir;
@@ -320,122 +301,27 @@ static inline u64 swap64_S (const u64 v)
   return r;
 }
 
-static inline u32 rotr32_S (const u32 a, const u32 n)
+inline u32 rotr32_S (const u32 a, const u32 n)
 {
   return rotate (a, 32 - n);
 }
 
-static inline u32 rotl32_S (const u32 a, const u32 n)
+inline u32 rotl32_S (const u32 a, const u32 n)
 {
   return rotate (a, n);
 }
 
-#if CUDA_ARCH >= 350
-static inline u64 rotr64_S (const u64 a, const u32 n)
-{
-  u32 il;
-  u32 ir;
-
-  asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a));
-
-  u32 tl;
-  u32 tr;
-
-  if (n >= 32)
-  {
-    asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-    asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-  }
-  else
-  {
-    asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-    asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-  }
-
-  u64 r;
-
-  asm ("mov.b64 %0, {%1, %2};" : "=l"(r) : "r"(tl), "r"(tr));
-
-  return r;
-}
-#else
-static inline u64 rotr64_S (const u64 a, const u32 n)
+inline u64 rotr64_S (const u64 a, const u32 n)
 {
   return rotate (a, (u64) 64 - n);
 }
-#endif
 
-static inline u64 rotl64_S (const u64 a, const u32 n)
+inline u64 rotl64_S (const u64 a, const u32 n)
 {
   return rotr64_S (a, 64 - n);
 }
 
-#if CUDA_ARCH >= 500
-static inline u32 lut3_2d_S (const u32 a, const u32 b, const u32 c)
-{
-  u32 r;
-
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-
-  return r;
-}
-
-static inline u32 lut3_39_S (const u32 a, const u32 b, const u32 c)
-{
-  u32 r;
-
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-
-  return r;
-}
-
-static inline u32 lut3_59_S (const u32 a, const u32 b, const u32 c)
-{
-  u32 r;
-
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-
-  return r;
-}
-
-static inline u32 lut3_96_S (const u32 a, const u32 b, const u32 c)
-{
-  u32 r;
-
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-
-  return r;
-}
-
-static inline u32 lut3_e4_S (const u32 a, const u32 b, const u32 c)
-{
-  u32 r;
-
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-
-  return r;
-}
-
-static inline u32 lut3_e8_S (const u32 a, const u32 b, const u32 c)
-{
-  u32 r;
-
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-
-  return r;
-}
-
-static inline u32 lut3_ca_S (const u32 a, const u32 b, const u32 c)
-{
-  u32 r;
-
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-
-  return r;
-}
-#endif
-
-static inline u32 __byte_perm_S (const u32 a, const u32 b, const u32 c)
+inline u32 __byte_perm_S (const u32 a, const u32 b, const u32 c)
 {
   u32 r;
 
@@ -444,7 +330,7 @@ static inline u32 __byte_perm_S (const u32 a, const u32 b, const u32 c)
   return r;
 }
 
-static inline u32x swap32 (const u32x v)
+inline u32x swap32 (const u32x v)
 {
   return ((v >> 24) & 0x000000ff)
        | ((v >>  8) & 0x0000ff00)
@@ -452,7 +338,7 @@ static inline u32x swap32 (const u32x v)
        | ((v << 24) & 0xff000000);
 }
 
-static inline u64x swap64 (const u64x v)
+inline u64x swap64 (const u64x v)
 {
   return ((v >> 56) & 0x00000000000000ff)
        | ((v >> 40) & 0x000000000000ff00)
@@ -464,348 +350,27 @@ static inline u64x swap64 (const u64x v)
        | ((v << 56) & 0xff00000000000000);
 }
 
-static inline u32x rotr32 (const u32x a, const u32 n)
+inline u32x rotr32 (const u32x a, const u32 n)
 {
   return rotate (a, 32 - n);
 }
 
-static inline u32x rotl32 (const u32x a, const u32 n)
+inline u32x rotl32 (const u32x a, const u32 n)
 {
   return rotate (a, n);
 }
 
-#if CUDA_ARCH >= 350
-static inline u64x rotr64 (const u64x a, const u32 n)
-{
-  u64x r;
-
-  u32 il;
-  u32 ir;
-  u32 tl;
-  u32 tr;
-
-  #if VECT_SIZE == 1
-
-  asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a));
-
-  if (n >= 32)
-  {
-    asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-    asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-  }
-  else
-  {
-    asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-    asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-  }
-
-  asm ("mov.b64 %0, {%1, %2};" : "=l"(r) : "r"(tl), "r"(tr));
-
-  #endif
-
-  #if VECT_SIZE >= 2
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s0));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s0) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s1));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s1) : "r"(tl), "r"(tr));
-  }
-
-  #endif
-
-  #if VECT_SIZE >= 4
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s2));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s2) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s3));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s3) : "r"(tl), "r"(tr));
-  }
-
-  #endif
-
-  #if VECT_SIZE >= 8
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s4));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s4) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s5));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s5) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s6));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s6) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s7));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s7) : "r"(tl), "r"(tr));
-  }
-
-  #endif
-
-  #if VECT_SIZE >= 16
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s8));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s8) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.s9));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.s9) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.sa));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.sa) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.sb));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.sb) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.sc));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.sc) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.sd));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.sd) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.se));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.se) : "r"(tl), "r"(tr));
-  }
-
-  {
-    asm ("mov.b64 {%0, %1}, %2;" : "=r"(il), "=r"(ir) : "l"(a.sf));
-
-    if (n >= 32)
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(ir), "r"(il), "r"(n - 32));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(il), "r"(ir), "r"(n - 32));
-    }
-    else
-    {
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tl) : "r"(il), "r"(ir), "r"(n));
-      asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(tr) : "r"(ir), "r"(il), "r"(n));
-    }
-
-    asm ("mov.b64 %0, {%1, %2};" : "=l"(r.sf) : "r"(tl), "r"(tr));
-  }
-
-  #endif
-
-  return r;
-}
-#else
-static inline u64x rotr64 (const u64x a, const u32 n)
+inline u64x rotr64 (const u64x a, const u32 n)
 {
   return rotate (a, (u64) 64 - n);
 }
-#endif
 
-static inline u64x rotl64 (const u64x a, const u32 n)
+inline u64x rotl64 (const u64x a, const u32 n)
 {
-  return rotr64 (a, (u64) 64 - n);
+  return rotate (a, (u64) n);
 }
 
-static inline u32x __byte_perm (const u32x a, const u32x b, const u32x c)
+inline u32x __byte_perm (const u32x a, const u32x b, const u32x c)
 {
   u32x r;
 
@@ -844,7 +409,7 @@ static inline u32x __byte_perm (const u32x a, const u32x b, const u32x c)
   return r;
 }
 
-static inline u32 __bfe (const u32 a, const u32 b, const u32 c)
+inline u32 __bfe (const u32 a, const u32 b, const u32 c)
 {
   u32 r;
 
@@ -853,338 +418,63 @@ static inline u32 __bfe (const u32 a, const u32 b, const u32 c)
   return r;
 }
 
-#if CUDA_ARCH >= 350
-static inline u32 amd_bytealign (const u32 a, const u32 b, const u32 c)
+inline u32 amd_bytealign (const u32 a, const u32 b, const u32 c)
 {
   u32 r;
 
-  asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(r) : "r"(b), "r"(a), "r"((c & 3) * 8));
+  #if CUDA_ARCH >= 350
 
-  return r;
-}
-#else
-static inline u32 amd_bytealign (const u32 a, const u32 b, const u32 c)
-{
-  return __byte_perm_S (b, a, (0x76543210 >> ((c & 3) * 4)) & 0xffff);
-}
-#endif
-
-#if CUDA_ARCH >= 500
-static inline u32x lut3_2d (const u32x a, const u32x b, const u32x c)
-{
-  u32x r;
-
-  #if VECT_SIZE == 1
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-  #endif
-
-  #if VECT_SIZE >= 2
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s0) : "r" (a.s0), "r" (b.s0), "r" (c.s0));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s1) : "r" (a.s1), "r" (b.s1), "r" (c.s1));
-  #endif
-
-  #if VECT_SIZE >= 4
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s2) : "r" (a.s2), "r" (b.s2), "r" (c.s2));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s3) : "r" (a.s3), "r" (b.s3), "r" (c.s3));
-  #endif
-
-  #if VECT_SIZE >= 8
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s4) : "r" (a.s4), "r" (b.s4), "r" (c.s4));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s5) : "r" (a.s5), "r" (b.s5), "r" (c.s5));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s6) : "r" (a.s6), "r" (b.s6), "r" (c.s6));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s7) : "r" (a.s7), "r" (b.s7), "r" (c.s7));
-  #endif
-
-  #if VECT_SIZE >= 16
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s8) : "r" (a.s8), "r" (b.s8), "r" (c.s8));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.s9) : "r" (a.s9), "r" (b.s9), "r" (c.s9));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.sa) : "r" (a.sa), "r" (b.sa), "r" (c.sa));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.sb) : "r" (a.sb), "r" (b.sb), "r" (c.sb));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.sc) : "r" (a.sc), "r" (b.sc), "r" (c.sc));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.sd) : "r" (a.sd), "r" (b.sd), "r" (c.sd));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.se) : "r" (a.se), "r" (b.se), "r" (c.se));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x2d;" : "=r" (r.sf) : "r" (a.sf), "r" (b.sf), "r" (c.sf));
-  #endif
-
-  return r;
-}
-
-static inline u32x lut3_39 (const u32x a, const u32x b, const u32x c)
-{
-  u32x r;
-
-  #if VECT_SIZE == 1
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-  #endif
-
-  #if VECT_SIZE >= 2
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s0) : "r" (a.s0), "r" (b.s0), "r" (c.s0));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s1) : "r" (a.s1), "r" (b.s1), "r" (c.s1));
-  #endif
-
-  #if VECT_SIZE >= 4
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s2) : "r" (a.s2), "r" (b.s2), "r" (c.s2));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s3) : "r" (a.s3), "r" (b.s3), "r" (c.s3));
-  #endif
-
-  #if VECT_SIZE >= 8
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s4) : "r" (a.s4), "r" (b.s4), "r" (c.s4));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s5) : "r" (a.s5), "r" (b.s5), "r" (c.s5));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s6) : "r" (a.s6), "r" (b.s6), "r" (c.s6));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s7) : "r" (a.s7), "r" (b.s7), "r" (c.s7));
-  #endif
-
-  #if VECT_SIZE >= 16
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s8) : "r" (a.s8), "r" (b.s8), "r" (c.s8));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.s9) : "r" (a.s9), "r" (b.s9), "r" (c.s9));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.sa) : "r" (a.sa), "r" (b.sa), "r" (c.sa));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.sb) : "r" (a.sb), "r" (b.sb), "r" (c.sb));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.sc) : "r" (a.sc), "r" (b.sc), "r" (c.sc));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.sd) : "r" (a.sd), "r" (b.sd), "r" (c.sd));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.se) : "r" (a.se), "r" (b.se), "r" (c.se));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x39;" : "=r" (r.sf) : "r" (a.sf), "r" (b.sf), "r" (c.sf));
-  #endif
-
-  return r;
-}
-
-static inline u32x lut3_59 (const u32x a, const u32x b, const u32x c)
-{
-  u32x r;
-
-  #if VECT_SIZE == 1
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r) : "r" (a), "r" (b), "r" (c));
-  #endif
-
-  #if VECT_SIZE >= 2
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s0) : "r" (a.s0), "r" (b.s0), "r" (c.s0));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s1) : "r" (a.s1), "r" (b.s1), "r" (c.s1));
-  #endif
-
-  #if VECT_SIZE >= 4
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s2) : "r" (a.s2), "r" (b.s2), "r" (c.s2));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s3) : "r" (a.s3), "r" (b.s3), "r" (c.s3));
-  #endif
-
-  #if VECT_SIZE >= 8
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s4) : "r" (a.s4), "r" (b.s4), "r" (c.s4));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s5) : "r" (a.s5), "r" (b.s5), "r" (c.s5));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s6) : "r" (a.s6), "r" (b.s6), "r" (c.s6));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s7) : "r" (a.s7), "r" (b.s7), "r" (c.s7));
-  #endif
-
-  #if VECT_SIZE >= 16
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s8) : "r" (a.s8), "r" (b.s8), "r" (c.s8));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.s9) : "r" (a.s9), "r" (b.s9), "r" (c.s9));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.sa) : "r" (a.sa), "r" (b.sa), "r" (c.sa));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.sb) : "r" (a.sb), "r" (b.sb), "r" (c.sb));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.sc) : "r" (a.sc), "r" (b.sc), "r" (c.sc));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.sd) : "r" (a.sd), "r" (b.sd), "r" (c.sd));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.se) : "r" (a.se), "r" (b.se), "r" (c.se));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x59;" : "=r" (r.sf) : "r" (a.sf), "r" (b.sf), "r" (c.sf));
-  #endif
-
-  return r;
-}
-
-static inline u32x lut3_96 (const u32x a, const u32x b, const u32x c)
-{
-  u32x r;
-
-  #if VECT_SIZE == 1
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r)    : "r" (a),    "r" (b),    "r" (c));
-  #endif
-
-  #if VECT_SIZE >= 2
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s0) : "r" (a.s0), "r" (b.s0), "r" (c.s0));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s1) : "r" (a.s1), "r" (b.s1), "r" (c.s1));
-  #endif
-
-  #if VECT_SIZE >= 4
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s2) : "r" (a.s2), "r" (b.s2), "r" (c.s2));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s3) : "r" (a.s3), "r" (b.s3), "r" (c.s3));
-  #endif
-
-  #if VECT_SIZE >= 8
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s4) : "r" (a.s4), "r" (b.s4), "r" (c.s4));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s5) : "r" (a.s5), "r" (b.s5), "r" (c.s5));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s6) : "r" (a.s6), "r" (b.s6), "r" (c.s6));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s7) : "r" (a.s7), "r" (b.s7), "r" (c.s7));
-  #endif
-
-  #if VECT_SIZE >= 16
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s8) : "r" (a.s8), "r" (b.s8), "r" (c.s8));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.s9) : "r" (a.s9), "r" (b.s9), "r" (c.s9));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.sa) : "r" (a.sa), "r" (b.sa), "r" (c.sa));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.sb) : "r" (a.sb), "r" (b.sb), "r" (c.sb));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.sc) : "r" (a.sc), "r" (b.sc), "r" (c.sc));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.sd) : "r" (a.sd), "r" (b.sd), "r" (c.sd));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.se) : "r" (a.se), "r" (b.se), "r" (c.se));
-  asm ("lop3.b32 %0, %1, %2, %3, 0x96;" : "=r" (r.sf) : "r" (a.sf), "r" (b.sf), "r" (c.sf));
-  #endif
-
-  return r;
-}
-
-static inline u32x lut3_e4 (const u32x a, const u32x b, const u32x c)
-{
-  u32x r;
-
-  #if VECT_SIZE == 1
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r)    : "r" (a),    "r" (b),    "r" (c));
-  #endif
-
-  #if VECT_SIZE >= 2
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s0) : "r" (a.s0), "r" (b.s0), "r" (c.s0));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s1) : "r" (a.s1), "r" (b.s1), "r" (c.s1));
-  #endif
-
-  #if VECT_SIZE >= 4
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s2) : "r" (a.s2), "r" (b.s2), "r" (c.s2));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s3) : "r" (a.s3), "r" (b.s3), "r" (c.s3));
-  #endif
-
-  #if VECT_SIZE >= 8
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s4) : "r" (a.s4), "r" (b.s4), "r" (c.s4));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s5) : "r" (a.s5), "r" (b.s5), "r" (c.s5));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s6) : "r" (a.s6), "r" (b.s6), "r" (c.s6));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s7) : "r" (a.s7), "r" (b.s7), "r" (c.s7));
-  #endif
-
-  #if VECT_SIZE >= 16
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s8) : "r" (a.s8), "r" (b.s8), "r" (c.s8));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.s9) : "r" (a.s9), "r" (b.s9), "r" (c.s9));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.sa) : "r" (a.sa), "r" (b.sa), "r" (c.sa));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.sb) : "r" (a.sb), "r" (b.sb), "r" (c.sb));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.sc) : "r" (a.sc), "r" (b.sc), "r" (c.sc));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.sd) : "r" (a.sd), "r" (b.sd), "r" (c.sd));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.se) : "r" (a.se), "r" (b.se), "r" (c.se));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe4;" : "=r" (r.sf) : "r" (a.sf), "r" (b.sf), "r" (c.sf));
-  #endif
-
-  return r;
-}
-
-static inline u32x lut3_e8 (const u32x a, const u32x b, const u32x c)
-{
-  u32x r;
-
-  #if VECT_SIZE == 1
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r)    : "r" (a),    "r" (b),    "r" (c));
-  #endif
-
-  #if VECT_SIZE >= 2
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s0) : "r" (a.s0), "r" (b.s0), "r" (c.s0));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s1) : "r" (a.s1), "r" (b.s1), "r" (c.s1));
-  #endif
-
-  #if VECT_SIZE >= 4
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s2) : "r" (a.s2), "r" (b.s2), "r" (c.s2));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s3) : "r" (a.s3), "r" (b.s3), "r" (c.s3));
-  #endif
-
-  #if VECT_SIZE >= 8
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s4) : "r" (a.s4), "r" (b.s4), "r" (c.s4));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s5) : "r" (a.s5), "r" (b.s5), "r" (c.s5));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s6) : "r" (a.s6), "r" (b.s6), "r" (c.s6));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s7) : "r" (a.s7), "r" (b.s7), "r" (c.s7));
-  #endif
-
-  #if VECT_SIZE >= 16
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s8) : "r" (a.s8), "r" (b.s8), "r" (c.s8));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.s9) : "r" (a.s9), "r" (b.s9), "r" (c.s9));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.sa) : "r" (a.sa), "r" (b.sa), "r" (c.sa));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.sb) : "r" (a.sb), "r" (b.sb), "r" (c.sb));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.sc) : "r" (a.sc), "r" (b.sc), "r" (c.sc));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.sd) : "r" (a.sd), "r" (b.sd), "r" (c.sd));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.se) : "r" (a.se), "r" (b.se), "r" (c.se));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xe8;" : "=r" (r.sf) : "r" (a.sf), "r" (b.sf), "r" (c.sf));
-  #endif
-
-  return r;
-}
-
-static inline u32x lut3_ca (const u32x a, const u32x b, const u32x c)
-{
-  u32x r;
-
-  #if VECT_SIZE == 1
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r)    : "r" (a),    "r" (b),    "r" (c));
-  #endif
-
-  #if VECT_SIZE >= 2
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s0) : "r" (a.s0), "r" (b.s0), "r" (c.s0));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s1) : "r" (a.s1), "r" (b.s1), "r" (c.s1));
-  #endif
+  asm ("shf.r.wrap.b32 %0, %1, %2, %3;" : "=r"(r) : "r"(b), "r"(a), "r"((c & 3) * 8));
 
-  #if VECT_SIZE >= 4
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s2) : "r" (a.s2), "r" (b.s2), "r" (c.s2));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s3) : "r" (a.s3), "r" (b.s3), "r" (c.s3));
-  #endif
+  #else
 
-  #if VECT_SIZE >= 8
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s4) : "r" (a.s4), "r" (b.s4), "r" (c.s4));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s5) : "r" (a.s5), "r" (b.s5), "r" (c.s5));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s6) : "r" (a.s6), "r" (b.s6), "r" (c.s6));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s7) : "r" (a.s7), "r" (b.s7), "r" (c.s7));
-  #endif
+  r = __byte_perm_S (b, a, (0x76543210 >> ((c & 3) * 4)) & 0xffff);
 
-  #if VECT_SIZE >= 16
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s8) : "r" (a.s8), "r" (b.s8), "r" (c.s8));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.s9) : "r" (a.s9), "r" (b.s9), "r" (c.s9));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.sa) : "r" (a.sa), "r" (b.sa), "r" (c.sa));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.sb) : "r" (a.sb), "r" (b.sb), "r" (c.sb));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.sc) : "r" (a.sc), "r" (b.sc), "r" (c.sc));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.sd) : "r" (a.sd), "r" (b.sd), "r" (c.sd));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.se) : "r" (a.se), "r" (b.se), "r" (c.se));
-  asm ("lop3.b32 %0, %1, %2, %3, 0xca;" : "=r" (r.sf) : "r" (a.sf), "r" (b.sf), "r" (c.sf));
   #endif
 
   return r;
 }
-
-#endif
 #endif
 
 #ifdef IS_GENERIC
-static inline u32 swap32_S (const u32 v)
+inline u32 swap32_S (const u32 v)
 {
   return (as_uint (as_uchar4 (v).s3210));
 }
 
-static inline u64 swap64_S (const u64 v)
+inline u64 swap64_S (const u64 v)
 {
   return (as_ulong (as_uchar8 (v).s76543210));
 }
 
-static inline u32 rotr32_S (const u32 a, const u32 n)
+inline u32 rotr32_S (const u32 a, const u32 n)
 {
   return rotate (a, 32 - n);
 }
 
-static inline u32 rotl32_S (const u32 a, const u32 n)
+inline u32 rotl32_S (const u32 a, const u32 n)
 {
   return rotate (a, n);
 }
 
-static inline u64 rotr64_S (const u64 a, const u32 n)
+inline u64 rotr64_S (const u64 a, const u32 n)
 {
   return rotate (a, (u64) 64 - n);
 }
 
-static inline u64 rotl64_S (const u64 a, const u32 n)
+inline u64 rotl64_S (const u64 a, const u32 n)
 {
   return rotate (a, (u64) n);
 }
 
-static inline u32 amd_bytealign_S (const u32 a, const u32 b, const u32 c)
+inline u32 amd_bytealign_S (const u32 a, const u32 b, const u32 c)
 {
   const u64 tmp = ((((u64) a) << 32) | ((u64) b)) >> ((c & 3) * 8);
 
   return (u32) (tmp);
 }
 
-static inline u32x swap32 (const u32x v)
+inline u32x swap32 (const u32x v)
 {
   return ((v >> 24) & 0x000000ff)
        | ((v >>  8) & 0x0000ff00)
@@ -1192,7 +482,7 @@ static inline u32x swap32 (const u32x v)
        | ((v << 24) & 0xff000000);
 }
 
-static inline u64x swap64 (const u64x v)
+inline u64x swap64 (const u64x v)
 {
   return ((v >> 56) & 0x00000000000000ff)
        | ((v >> 40) & 0x000000000000ff00)
@@ -1204,27 +494,27 @@ static inline u64x swap64 (const u64x v)
        | ((v << 56) & 0xff00000000000000);
 }
 
-static inline u32x rotr32 (const u32x a, const u32 n)
+inline u32x rotr32 (const u32x a, const u32 n)
 {
   return rotate (a, 32 - n);
 }
 
-static inline u32x rotl32 (const u32x a, const u32 n)
+inline u32x rotl32 (const u32x a, const u32 n)
 {
   return rotate (a, n);
 }
 
-static inline u64x rotr64 (const u64x a, const u32 n)
+inline u64x rotr64 (const u64x a, const u32 n)
 {
   return rotate (a, (u64) 64 - n);
 }
 
-static inline u64x rotl64 (const u64x a, const u32 n)
+inline u64x rotl64 (const u64x a, const u32 n)
 {
   return rotate (a, (u64) n);
 }
 
-static inline u32 __bfe (const u32 a, const u32 b, const u32 c)
+inline u32 __bfe (const u32 a, const u32 b, const u32 c)
 {
   #define BIT(x)      (1 << (x))
   #define BIT_MASK(x) (BIT (x) - 1)
@@ -1233,7 +523,7 @@ static inline u32 __bfe (const u32 a, const u32 b, const u32 c)
   return BFE (a, b, c);
 }
 
-static inline u32x amd_bytealign (const u32x a, const u32x b, const u32 c)
+inline u32x amd_bytealign (const u32x a, const u32x b, const u32 c)
 {
   #if VECT_SIZE == 1
   const u64x tmp = ((((u64x) (a)) << 32) | ((u64x) (b))) >> ((c & 3) * 8);
@@ -1596,6 +886,16 @@ typedef struct
 
 } oldoffice34_t;
 
+typedef struct
+{
+  u32 salt_buf[128];
+  u32 salt_len;
+
+  u32 pc_digest[5];
+  u32 pc_offset;
+
+} pstoken_t;
+
 typedef struct
 {
   u32 version;