Optimize a few modes for hashcat_tuning.hctab for budget NV cards
[hashcat.git] / OpenCL / common.c
index 7c5d45d..1a36194 100644 (file)
@@ -3,7 +3,11 @@
  * License.....: MIT
  */
 
-static int hash_comp (const u32 d1[4], __global u32 *d2)
+/**
+ * pure scalar functions
+ */
+
+inline int hash_comp (const u32 d1[4], __global u32 *d2)
 {
   if (d1[3] > d2[DGST_R3]) return ( 1);
   if (d1[3] < d2[DGST_R3]) return (-1);
@@ -17,7 +21,7 @@ static int hash_comp (const u32 d1[4], __global u32 *d2)
   return (0);
 }
 
-static int find_hash (const u32 digest[4], const u32 digests_cnt, __global digest_t *digests_buf)
+inline int find_hash (const u32 digest[4], const u32 digests_cnt, __global digest_t *digests_buf)
 {
   for (u32 l = 0, r = digests_cnt; r; r >>= 1)
   {
@@ -40,12 +44,12 @@ static int find_hash (const u32 digest[4], const u32 digests_cnt, __global diges
   return (-1);
 }
 
-static u32 check_bitmap (__global u32 *bitmap, const u32 bitmap_mask, const u32 bitmap_shift, const u32 digest)
+inline u32 check_bitmap (__global u32 *bitmap, const u32 bitmap_mask, const u32 bitmap_shift, const u32 digest)
 {
   return (bitmap[(digest >> bitmap_shift) & bitmap_mask] & (1 << (digest & 0x1f)));
 }
 
-static u32 check (const u32 digest[2], __global u32 *bitmap_s1_a, __global u32 *bitmap_s1_b, __global u32 *bitmap_s1_c, __global u32 *bitmap_s1_d, __global u32 *bitmap_s2_a, __global u32 *bitmap_s2_b, __global u32 *bitmap_s2_c, __global u32 *bitmap_s2_d, const u32 bitmap_mask, const u32 bitmap_shift1, const u32 bitmap_shift2)
+inline u32 check (const u32 digest[2], __global u32 *bitmap_s1_a, __global u32 *bitmap_s1_b, __global u32 *bitmap_s1_c, __global u32 *bitmap_s1_d, __global u32 *bitmap_s2_a, __global u32 *bitmap_s2_b, __global u32 *bitmap_s2_c, __global u32 *bitmap_s2_d, const u32 bitmap_mask, const u32 bitmap_shift1, const u32 bitmap_shift2)
 {
   if (check_bitmap (bitmap_s1_a, bitmap_mask, bitmap_shift1, digest[0]) == 0) return (0);
   if (check_bitmap (bitmap_s1_b, bitmap_mask, bitmap_shift1, digest[1]) == 0) return (0);
@@ -60,7 +64,7 @@ static u32 check (const u32 digest[2], __global u32 *bitmap_s1_a, __global u32 *
   return (1);
 }
 
-static void mark_hash (__global plain_t *plains_buf, __global u32 *hashes_shown, const int hash_pos, const u32 gid, const u32 il_pos)
+inline void mark_hash (__global plain_t *plains_buf, __global u32 *hashes_shown, const int hash_pos, const u32 gid, const u32 il_pos)
 {
   hashes_shown[hash_pos] = 1;
 
@@ -68,7 +72,11 @@ static void mark_hash (__global plain_t *plains_buf, __global u32 *hashes_shown,
   plains_buf[hash_pos].il_pos = il_pos;
 }
 
-static void truncate_block (u32 w[4], const u32 len)
+/**
+ * vector functions
+ */
+
+inline void truncate_block (u32x w[4], const u32 len)
 {
   switch (len)
   {
@@ -131,32 +139,7 @@ static void truncate_block (u32 w[4], const u32 len)
   }
 }
 
-static void make_unicode_S (const u32 in[4], u32 out1[4], u32 out2[4])
-{
-  #ifdef IS_NV
-  out2[3] = __byte_perm_S (in[3], 0, 0x7372);
-  out2[2] = __byte_perm_S (in[3], 0, 0x7170);
-  out2[1] = __byte_perm_S (in[2], 0, 0x7372);
-  out2[0] = __byte_perm_S (in[2], 0, 0x7170);
-  out1[3] = __byte_perm_S (in[1], 0, 0x7372);
-  out1[2] = __byte_perm_S (in[1], 0, 0x7170);
-  out1[1] = __byte_perm_S (in[0], 0, 0x7372);
-  out1[0] = __byte_perm_S (in[0], 0, 0x7170);
-  #endif
-
-  #if defined IS_AMD || defined IS_GENERIC
-  out2[3]  = ((in[3] >> 8) & 0x00FF0000) | ((in[3] >> 16) & 0x000000FF);
-  out2[2]  = ((in[3] << 8) & 0x00FF0000) | ((in[3] >>  0) & 0x000000FF);
-  out2[1]  = ((in[2] >> 8) & 0x00FF0000) | ((in[2] >> 16) & 0x000000FF);
-  out2[0]  = ((in[2] << 8) & 0x00FF0000) | ((in[2] >>  0) & 0x000000FF);
-  out1[3]  = ((in[1] >> 8) & 0x00FF0000) | ((in[1] >> 16) & 0x000000FF);
-  out1[2]  = ((in[1] << 8) & 0x00FF0000) | ((in[1] >>  0) & 0x000000FF);
-  out1[1]  = ((in[0] >> 8) & 0x00FF0000) | ((in[0] >> 16) & 0x000000FF);
-  out1[0]  = ((in[0] << 8) & 0x00FF0000) | ((in[0] >>  0) & 0x000000FF);
-  #endif
-}
-
-static void make_unicode (const u32x in[4], u32x out1[4], u32x out2[4])
+inline void make_unicode (const u32x in[4], u32x out1[4], u32x out2[4])
 {
   #ifdef IS_NV
   out2[3] = __byte_perm (in[3], 0, 0x7372);
@@ -181,28 +164,7 @@ static void make_unicode (const u32x in[4], u32x out1[4], u32x out2[4])
   #endif
 }
 
-static void undo_unicode_S (const u32 in1[4], const u32 in2[4], u32 out[4])
-{
-  #ifdef IS_NV
-  out[0] = __byte_perm_S (in1[0], in1[1], 0x6420);
-  out[1] = __byte_perm_S (in1[2], in1[3], 0x6420);
-  out[2] = __byte_perm_S (in2[0], in2[1], 0x6420);
-  out[3] = __byte_perm_S (in2[2], in2[3], 0x6420);
-  #endif
-
-  #if defined IS_AMD || defined IS_GENERIC
-  out[0] = ((in1[0] & 0x000000ff) >>  0) | ((in1[0] & 0x00ff0000) >>  8)
-         | ((in1[1] & 0x000000ff) << 16) | ((in1[1] & 0x00ff0000) <<  8);
-  out[1] = ((in1[2] & 0x000000ff) >>  0) | ((in1[2] & 0x00ff0000) >>  8)
-         | ((in1[3] & 0x000000ff) << 16) | ((in1[3] & 0x00ff0000) <<  8);
-  out[2] = ((in2[0] & 0x000000ff) >>  0) | ((in2[0] & 0x00ff0000) >>  8)
-         | ((in2[1] & 0x000000ff) << 16) | ((in2[1] & 0x00ff0000) <<  8);
-  out[3] = ((in2[2] & 0x000000ff) >>  0) | ((in2[2] & 0x00ff0000) >>  8)
-         | ((in2[3] & 0x000000ff) << 16) | ((in2[3] & 0x00ff0000) <<  8);
-  #endif
-}
-
-static void undo_unicode (const u32x in1[4], const u32x in2[4], u32x out[4])
+inline void undo_unicode (const u32x in1[4], const u32x in2[4], u32x out[4])
 {
   #ifdef IS_NV
   out[0] = __byte_perm (in1[0], in1[1], 0x6420);
@@ -223,7 +185,7 @@ static void undo_unicode (const u32x in1[4], const u32x in2[4], u32x out[4])
   #endif
 }
 
-static void append_0x01_1x4 (u32 w0[4], const u32 offset)
+inline void append_0x01_1x4 (u32x w0[4], const u32 offset)
 {
   switch (offset)
   {
@@ -293,7 +255,7 @@ static void append_0x01_1x4 (u32 w0[4], const u32 offset)
   }
 }
 
-static void append_0x01_2x4 (u32 w0[4], u32 w1[4], const u32 offset)
+inline void append_0x01_2x4 (u32x w0[4], u32x w1[4], const u32 offset)
 {
   switch (offset)
   {
@@ -427,7 +389,7 @@ static void append_0x01_2x4 (u32 w0[4], u32 w1[4], const u32 offset)
   }
 }
 
-static void append_0x01_3x4 (u32 w0[4], u32 w1[4], u32 w2[4], const u32 offset)
+inline void append_0x01_3x4 (u32x w0[4], u32x w1[4], u32x w2[4], const u32 offset)
 {
   switch (offset)
   {
@@ -625,7 +587,7 @@ static void append_0x01_3x4 (u32 w0[4], u32 w1[4], u32 w2[4], const u32 offset)
   }
 }
 
-static void append_0x01_4x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 offset)
+inline void append_0x01_4x4 (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32 offset)
 {
   switch (offset)
   {
@@ -887,7 +849,7 @@ static void append_0x01_4x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u
   }
 }
 
-static void append_0x01_8x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], u32 w4[4], u32 w5[4], u32 w6[4], u32 w7[4], const u32 offset)
+inline void append_0x01_8x4 (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], u32x w4[4], u32x w5[4], u32x w6[4], u32x w7[4], const u32 offset)
 {
   switch (offset)
   {
@@ -1405,7 +1367,7 @@ static void append_0x01_8x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], u32 w4[
   }
 }
 
-static void append_0x02_1x4 (u32 w0[4], const u32 offset)
+inline void append_0x02_1x4 (u32x w0[4], const u32 offset)
 {
   switch (offset)
   {
@@ -1475,7 +1437,7 @@ static void append_0x02_1x4 (u32 w0[4], const u32 offset)
   }
 }
 
-static void append_0x02_2x4 (u32 w0[4], u32 w1[4], const u32 offset)
+inline void append_0x02_2x4 (u32x w0[4], u32x w1[4], const u32 offset)
 {
   switch (offset)
   {
@@ -1609,7 +1571,7 @@ static void append_0x02_2x4 (u32 w0[4], u32 w1[4], const u32 offset)
   }
 }
 
-static void append_0x02_3x4 (u32 w0[4], u32 w1[4], u32 w2[4], const u32 offset)
+inline void append_0x02_3x4 (u32x w0[4], u32x w1[4], u32x w2[4], const u32 offset)
 {
   switch (offset)
   {
@@ -1807,7 +1769,7 @@ static void append_0x02_3x4 (u32 w0[4], u32 w1[4], u32 w2[4], const u32 offset)
   }
 }
 
-static void append_0x02_4x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 offset)
+inline void append_0x02_4x4 (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32 offset)
 {
   switch (offset)
   {
@@ -2069,7 +2031,7 @@ static void append_0x02_4x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u
   }
 }
 
-static void append_0x02_8x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], u32 w4[4], u32 w5[4], u32 w6[4], u32 w7[4], const u32 offset)
+inline void append_0x02_8x4 (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], u32x w4[4], u32x w5[4], u32x w6[4], u32x w7[4], const u32 offset)
 {
   switch (offset)
   {
@@ -2587,7 +2549,7 @@ static void append_0x02_8x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], u32 w4[
   }
 }
 
-static void append_0x80_1x4 (u32 w0[4], const u32 offset)
+inline void append_0x80_1x4 (u32x w0[4], const u32 offset)
 {
   switch (offset)
   {
@@ -2657,7 +2619,7 @@ static void append_0x80_1x4 (u32 w0[4], const u32 offset)
   }
 }
 
-static void append_0x80_2x4 (u32x w0[4], u32x w1[4], const u32 offset)
+inline void append_0x80_2x4 (u32x w0[4], u32x w1[4], const u32 offset)
 {
   switch (offset)
   {
@@ -2791,7 +2753,7 @@ static void append_0x80_2x4 (u32x w0[4], u32x w1[4], const u32 offset)
   }
 }
 
-static void append_0x80_3x4 (u32 w0[4], u32 w1[4], u32 w2[4], const u32 offset)
+inline void append_0x80_3x4 (u32x w0[4], u32x w1[4], u32x w2[4], const u32 offset)
 {
   switch (offset)
   {
@@ -2989,7 +2951,7 @@ static void append_0x80_3x4 (u32 w0[4], u32 w1[4], u32 w2[4], const u32 offset)
   }
 }
 
-static void append_0x80_4x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 offset)
+inline void append_0x80_4x4 (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32 offset)
 {
   switch (offset)
   {
@@ -3251,7 +3213,7 @@ static void append_0x80_4x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u
   }
 }
 
-static void append_0x80_8x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], u32 w4[4], u32 w5[4], u32 w6[4], u32 w7[4], const u32 offset)
+inline void append_0x80_8x4 (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], u32x w4[4], u32x w5[4], u32x w6[4], u32x w7[4], const u32 offset)
 {
   switch (offset)
   {
@@ -3769,7 +3731,7 @@ static void append_0x80_8x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], u32 w4[
   }
 }
 
-static void append_0x80_1x16 (u32 w[16], const u32 offset)
+inline void append_0x80_1x16 (u32x w[16], const u32 offset)
 {
   switch (offset)
   {
@@ -4031,7 +3993,7 @@ static void append_0x80_1x16 (u32 w[16], const u32 offset)
   }
 }
 
-static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 offset)
+inline void switch_buffer_by_offset_le (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32 offset)
 {
   #if defined IS_AMD || defined IS_GENERIC
   const int offset_mod_4 = offset & 3;
@@ -4041,21 +4003,21 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
   switch (offset / 4)
   {
     case 0:
-      w3[2] = amd_bytealign_S (    0, w3[1], offset_minus_4);
-      w3[1] = amd_bytealign_S (w3[1], w3[0], offset_minus_4);
-      w3[0] = amd_bytealign_S (w3[0], w2[3], offset_minus_4);
-      w2[3] = amd_bytealign_S (w2[3], w2[2], offset_minus_4);
-      w2[2] = amd_bytealign_S (w2[2], w2[1], offset_minus_4);
-      w2[1] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
-      w2[0] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
-      w1[3] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
-      w1[2] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
-      w1[1] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w1[0] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w0[3] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w0[2] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w0[1] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w0[0] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w3[1], offset_minus_4);
+      w3[1] = amd_bytealign (w3[1], w3[0], offset_minus_4);
+      w3[0] = amd_bytealign (w3[0], w2[3], offset_minus_4);
+      w2[3] = amd_bytealign (w2[3], w2[2], offset_minus_4);
+      w2[2] = amd_bytealign (w2[2], w2[1], offset_minus_4);
+      w2[1] = amd_bytealign (w2[1], w2[0], offset_minus_4);
+      w2[0] = amd_bytealign (w2[0], w1[3], offset_minus_4);
+      w1[3] = amd_bytealign (w1[3], w1[2], offset_minus_4);
+      w1[2] = amd_bytealign (w1[2], w1[1], offset_minus_4);
+      w1[1] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w1[0] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w0[3] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w0[2] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w0[1] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w0[0] = amd_bytealign (w0[0],     0, offset_minus_4);
 
       if (offset_mod_4 == 0)
       {
@@ -4079,20 +4041,20 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 1:
-      w3[2] = amd_bytealign_S (    0, w3[0], offset_minus_4);
-      w3[1] = amd_bytealign_S (w3[0], w2[3], offset_minus_4);
-      w3[0] = amd_bytealign_S (w2[3], w2[2], offset_minus_4);
-      w2[3] = amd_bytealign_S (w2[2], w2[1], offset_minus_4);
-      w2[2] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
-      w2[1] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
-      w2[0] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
-      w1[3] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
-      w1[2] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w1[1] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w1[0] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w0[3] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w0[2] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w0[1] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w3[0], offset_minus_4);
+      w3[1] = amd_bytealign (w3[0], w2[3], offset_minus_4);
+      w3[0] = amd_bytealign (w2[3], w2[2], offset_minus_4);
+      w2[3] = amd_bytealign (w2[2], w2[1], offset_minus_4);
+      w2[2] = amd_bytealign (w2[1], w2[0], offset_minus_4);
+      w2[1] = amd_bytealign (w2[0], w1[3], offset_minus_4);
+      w2[0] = amd_bytealign (w1[3], w1[2], offset_minus_4);
+      w1[3] = amd_bytealign (w1[2], w1[1], offset_minus_4);
+      w1[2] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w1[1] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w1[0] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w0[3] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w0[2] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w0[1] = amd_bytealign (w0[0],     0, offset_minus_4);
       w0[0] = 0;
 
       if (offset_mod_4 == 0)
@@ -4116,19 +4078,19 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 2:
-      w3[2] = amd_bytealign_S (    0, w2[3], offset_minus_4);
-      w3[1] = amd_bytealign_S (w2[3], w2[2], offset_minus_4);
-      w3[0] = amd_bytealign_S (w2[2], w2[1], offset_minus_4);
-      w2[3] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
-      w2[2] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
-      w2[1] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
-      w2[0] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
-      w1[3] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w1[2] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w1[1] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w1[0] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w0[3] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w0[2] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w2[3], offset_minus_4);
+      w3[1] = amd_bytealign (w2[3], w2[2], offset_minus_4);
+      w3[0] = amd_bytealign (w2[2], w2[1], offset_minus_4);
+      w2[3] = amd_bytealign (w2[1], w2[0], offset_minus_4);
+      w2[2] = amd_bytealign (w2[0], w1[3], offset_minus_4);
+      w2[1] = amd_bytealign (w1[3], w1[2], offset_minus_4);
+      w2[0] = amd_bytealign (w1[2], w1[1], offset_minus_4);
+      w1[3] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w1[2] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w1[1] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w1[0] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w0[3] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w0[2] = amd_bytealign (w0[0],     0, offset_minus_4);
       w0[1] = 0;
       w0[0] = 0;
 
@@ -4152,18 +4114,18 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 3:
-      w3[2] = amd_bytealign_S (    0, w2[2], offset_minus_4);
-      w3[1] = amd_bytealign_S (w2[2], w2[1], offset_minus_4);
-      w3[0] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
-      w2[3] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
-      w2[2] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
-      w2[1] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
-      w2[0] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w1[3] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w1[2] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w1[1] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w1[0] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w0[3] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w2[2], offset_minus_4);
+      w3[1] = amd_bytealign (w2[2], w2[1], offset_minus_4);
+      w3[0] = amd_bytealign (w2[1], w2[0], offset_minus_4);
+      w2[3] = amd_bytealign (w2[0], w1[3], offset_minus_4);
+      w2[2] = amd_bytealign (w1[3], w1[2], offset_minus_4);
+      w2[1] = amd_bytealign (w1[2], w1[1], offset_minus_4);
+      w2[0] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w1[3] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w1[2] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w1[1] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w1[0] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w0[3] = amd_bytealign (w0[0],     0, offset_minus_4);
       w0[2] = 0;
       w0[1] = 0;
       w0[0] = 0;
@@ -4187,17 +4149,17 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 4:
-      w3[2] = amd_bytealign_S (    0, w2[1], offset_minus_4);
-      w3[1] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
-      w3[0] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
-      w2[3] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
-      w2[2] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
-      w2[1] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w2[0] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w1[3] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w1[2] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w1[1] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w1[0] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w2[1], offset_minus_4);
+      w3[1] = amd_bytealign (w2[1], w2[0], offset_minus_4);
+      w3[0] = amd_bytealign (w2[0], w1[3], offset_minus_4);
+      w2[3] = amd_bytealign (w1[3], w1[2], offset_minus_4);
+      w2[2] = amd_bytealign (w1[2], w1[1], offset_minus_4);
+      w2[1] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w2[0] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w1[3] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w1[2] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w1[1] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w1[0] = amd_bytealign (w0[0],     0, offset_minus_4);
       w0[3] = 0;
       w0[2] = 0;
       w0[1] = 0;
@@ -4221,16 +4183,16 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 5:
-      w3[2] = amd_bytealign_S (    0, w2[0], offset_minus_4);
-      w3[1] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
-      w3[0] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
-      w2[3] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
-      w2[2] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w2[1] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w2[0] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w1[3] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w1[2] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w1[1] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w2[0], offset_minus_4);
+      w3[1] = amd_bytealign (w2[0], w1[3], offset_minus_4);
+      w3[0] = amd_bytealign (w1[3], w1[2], offset_minus_4);
+      w2[3] = amd_bytealign (w1[2], w1[1], offset_minus_4);
+      w2[2] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w2[1] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w2[0] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w1[3] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w1[2] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w1[1] = amd_bytealign (w0[0],     0, offset_minus_4);
       w1[0] = 0;
       w0[3] = 0;
       w0[2] = 0;
@@ -4254,15 +4216,15 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 6:
-      w3[2] = amd_bytealign_S (    0, w1[3], offset_minus_4);
-      w3[1] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
-      w3[0] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
-      w2[3] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w2[2] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w2[1] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w2[0] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w1[3] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w1[2] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w1[3], offset_minus_4);
+      w3[1] = amd_bytealign (w1[3], w1[2], offset_minus_4);
+      w3[0] = amd_bytealign (w1[2], w1[1], offset_minus_4);
+      w2[3] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w2[2] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w2[1] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w2[0] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w1[3] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w1[2] = amd_bytealign (w0[0],     0, offset_minus_4);
       w1[1] = 0;
       w1[0] = 0;
       w0[3] = 0;
@@ -4286,14 +4248,14 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 7:
-      w3[2] = amd_bytealign_S (    0, w1[2], offset_minus_4);
-      w3[1] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
-      w3[0] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w2[3] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w2[2] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w2[1] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w2[0] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w1[3] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w1[2], offset_minus_4);
+      w3[1] = amd_bytealign (w1[2], w1[1], offset_minus_4);
+      w3[0] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w2[3] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w2[2] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w2[1] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w2[0] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w1[3] = amd_bytealign (w0[0],     0, offset_minus_4);
       w1[2] = 0;
       w1[1] = 0;
       w1[0] = 0;
@@ -4317,13 +4279,13 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 8:
-      w3[2] = amd_bytealign_S (    0, w1[1], offset_minus_4);
-      w3[1] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
-      w3[0] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w2[3] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w2[2] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w2[1] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w2[0] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w1[1], offset_minus_4);
+      w3[1] = amd_bytealign (w1[1], w1[0], offset_minus_4);
+      w3[0] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w2[3] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w2[2] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w2[1] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w2[0] = amd_bytealign (w0[0],     0, offset_minus_4);
       w1[3] = 0;
       w1[2] = 0;
       w1[1] = 0;
@@ -4347,14 +4309,14 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 9:
-      w3[2] = amd_bytealign_S (    0, w1[0], offset_minus_4);
-      w3[1] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
-      w3[0] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w2[3] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w2[2] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w2[1] = amd_bytealign_S (w0[0],     0, offset_minus_4);
-      w2[0] = 0;
-      w1[3] = 0;
+      w3[2] = amd_bytealign (    0, w1[0], offset_minus_4);
+      w3[1] = amd_bytealign (w1[0], w0[3], offset_minus_4);
+      w3[0] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w2[3] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w2[2] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w2[1] = amd_bytealign (w0[0],     0, offset_minus_4);
+      w2[0] = 0;
+      w1[3] = 0;
       w1[2] = 0;
       w1[1] = 0;
       w1[0] = 0;
@@ -4376,11 +4338,11 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 10:
-      w3[2] = amd_bytealign_S (    0, w0[3], offset_minus_4);
-      w3[1] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
-      w3[0] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w2[3] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w2[2] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w0[3], offset_minus_4);
+      w3[1] = amd_bytealign (w0[3], w0[2], offset_minus_4);
+      w3[0] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w2[3] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w2[2] = amd_bytealign (w0[0],     0, offset_minus_4);
       w2[1] = 0;
       w2[0] = 0;
       w1[3] = 0;
@@ -4404,10 +4366,10 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 11:
-      w3[2] = amd_bytealign_S (    0, w0[2], offset_minus_4);
-      w3[1] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
-      w3[0] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w2[3] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w0[2], offset_minus_4);
+      w3[1] = amd_bytealign (w0[2], w0[1], offset_minus_4);
+      w3[0] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w2[3] = amd_bytealign (w0[0],     0, offset_minus_4);
       w2[2] = 0;
       w2[1] = 0;
       w2[0] = 0;
@@ -4431,9 +4393,9 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 12:
-      w3[2] = amd_bytealign_S (    0, w0[1], offset_minus_4);
-      w3[1] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
-      w3[0] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w0[1], offset_minus_4);
+      w3[1] = amd_bytealign (w0[1], w0[0], offset_minus_4);
+      w3[0] = amd_bytealign (w0[0],     0, offset_minus_4);
       w2[3] = 0;
       w2[2] = 0;
       w2[1] = 0;
@@ -4457,8 +4419,8 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 13:
-      w3[2] = amd_bytealign_S (    0, w0[0], offset_minus_4);
-      w3[1] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[2] = amd_bytealign (    0, w0[0], offset_minus_4);
+      w3[1] = amd_bytealign (w0[0],     0, offset_minus_4);
       w3[0] = 0;
       w2[3] = 0;
       w2[2] = 0;
@@ -4491,71 +4453,71 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
   switch (offset / 4)
   {
     case 0:
-      w3[1] = __byte_perm_S (w3[0], w3[1], selector);
-      w3[0] = __byte_perm_S (w2[3], w3[0], selector);
-      w2[3] = __byte_perm_S (w2[2], w2[3], selector);
-      w2[2] = __byte_perm_S (w2[1], w2[2], selector);
-      w2[1] = __byte_perm_S (w2[0], w2[1], selector);
-      w2[0] = __byte_perm_S (w1[3], w2[0], selector);
-      w1[3] = __byte_perm_S (w1[2], w1[3], selector);
-      w1[2] = __byte_perm_S (w1[1], w1[2], selector);
-      w1[1] = __byte_perm_S (w1[0], w1[1], selector);
-      w1[0] = __byte_perm_S (w0[3], w1[0], selector);
-      w0[3] = __byte_perm_S (w0[2], w0[3], selector);
-      w0[2] = __byte_perm_S (w0[1], w0[2], selector);
-      w0[1] = __byte_perm_S (w0[0], w0[1], selector);
-      w0[0] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w3[0], w3[1], selector);
+      w3[0] = __byte_perm (w2[3], w3[0], selector);
+      w2[3] = __byte_perm (w2[2], w2[3], selector);
+      w2[2] = __byte_perm (w2[1], w2[2], selector);
+      w2[1] = __byte_perm (w2[0], w2[1], selector);
+      w2[0] = __byte_perm (w1[3], w2[0], selector);
+      w1[3] = __byte_perm (w1[2], w1[3], selector);
+      w1[2] = __byte_perm (w1[1], w1[2], selector);
+      w1[1] = __byte_perm (w1[0], w1[1], selector);
+      w1[0] = __byte_perm (w0[3], w1[0], selector);
+      w0[3] = __byte_perm (w0[2], w0[3], selector);
+      w0[2] = __byte_perm (w0[1], w0[2], selector);
+      w0[1] = __byte_perm (w0[0], w0[1], selector);
+      w0[0] = __byte_perm (    0, w0[0], selector);
 
       break;
 
     case 1:
-      w3[1] = __byte_perm_S (w2[3], w3[0], selector);
-      w3[0] = __byte_perm_S (w2[2], w2[3], selector);
-      w2[3] = __byte_perm_S (w2[1], w2[2], selector);
-      w2[2] = __byte_perm_S (w2[0], w2[1], selector);
-      w2[1] = __byte_perm_S (w1[3], w2[0], selector);
-      w2[0] = __byte_perm_S (w1[2], w1[3], selector);
-      w1[3] = __byte_perm_S (w1[1], w1[2], selector);
-      w1[2] = __byte_perm_S (w1[0], w1[1], selector);
-      w1[1] = __byte_perm_S (w0[3], w1[0], selector);
-      w1[0] = __byte_perm_S (w0[2], w0[3], selector);
-      w0[3] = __byte_perm_S (w0[1], w0[2], selector);
-      w0[2] = __byte_perm_S (w0[0], w0[1], selector);
-      w0[1] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w2[3], w3[0], selector);
+      w3[0] = __byte_perm (w2[2], w2[3], selector);
+      w2[3] = __byte_perm (w2[1], w2[2], selector);
+      w2[2] = __byte_perm (w2[0], w2[1], selector);
+      w2[1] = __byte_perm (w1[3], w2[0], selector);
+      w2[0] = __byte_perm (w1[2], w1[3], selector);
+      w1[3] = __byte_perm (w1[1], w1[2], selector);
+      w1[2] = __byte_perm (w1[0], w1[1], selector);
+      w1[1] = __byte_perm (w0[3], w1[0], selector);
+      w1[0] = __byte_perm (w0[2], w0[3], selector);
+      w0[3] = __byte_perm (w0[1], w0[2], selector);
+      w0[2] = __byte_perm (w0[0], w0[1], selector);
+      w0[1] = __byte_perm (    0, w0[0], selector);
       w0[0] = 0;
 
       break;
 
     case 2:
-      w3[1] = __byte_perm_S (w2[2], w2[3], selector);
-      w3[0] = __byte_perm_S (w2[1], w2[2], selector);
-      w2[3] = __byte_perm_S (w2[0], w2[1], selector);
-      w2[2] = __byte_perm_S (w1[3], w2[0], selector);
-      w2[1] = __byte_perm_S (w1[2], w1[3], selector);
-      w2[0] = __byte_perm_S (w1[1], w1[2], selector);
-      w1[3] = __byte_perm_S (w1[0], w1[1], selector);
-      w1[2] = __byte_perm_S (w0[3], w1[0], selector);
-      w1[1] = __byte_perm_S (w0[2], w0[3], selector);
-      w1[0] = __byte_perm_S (w0[1], w0[2], selector);
-      w0[3] = __byte_perm_S (w0[0], w0[1], selector);
-      w0[2] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w2[2], w2[3], selector);
+      w3[0] = __byte_perm (w2[1], w2[2], selector);
+      w2[3] = __byte_perm (w2[0], w2[1], selector);
+      w2[2] = __byte_perm (w1[3], w2[0], selector);
+      w2[1] = __byte_perm (w1[2], w1[3], selector);
+      w2[0] = __byte_perm (w1[1], w1[2], selector);
+      w1[3] = __byte_perm (w1[0], w1[1], selector);
+      w1[2] = __byte_perm (w0[3], w1[0], selector);
+      w1[1] = __byte_perm (w0[2], w0[3], selector);
+      w1[0] = __byte_perm (w0[1], w0[2], selector);
+      w0[3] = __byte_perm (w0[0], w0[1], selector);
+      w0[2] = __byte_perm (    0, w0[0], selector);
       w0[1] = 0;
       w0[0] = 0;
 
       break;
 
     case 3:
-      w3[1] = __byte_perm_S (w2[1], w2[2], selector);
-      w3[0] = __byte_perm_S (w2[0], w2[1], selector);
-      w2[3] = __byte_perm_S (w1[3], w2[0], selector);
-      w2[2] = __byte_perm_S (w1[2], w1[3], selector);
-      w2[1] = __byte_perm_S (w1[1], w1[2], selector);
-      w2[0] = __byte_perm_S (w1[0], w1[1], selector);
-      w1[3] = __byte_perm_S (w0[3], w1[0], selector);
-      w1[2] = __byte_perm_S (w0[2], w0[3], selector);
-      w1[1] = __byte_perm_S (w0[1], w0[2], selector);
-      w1[0] = __byte_perm_S (w0[0], w0[1], selector);
-      w0[3] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w2[1], w2[2], selector);
+      w3[0] = __byte_perm (w2[0], w2[1], selector);
+      w2[3] = __byte_perm (w1[3], w2[0], selector);
+      w2[2] = __byte_perm (w1[2], w1[3], selector);
+      w2[1] = __byte_perm (w1[1], w1[2], selector);
+      w2[0] = __byte_perm (w1[0], w1[1], selector);
+      w1[3] = __byte_perm (w0[3], w1[0], selector);
+      w1[2] = __byte_perm (w0[2], w0[3], selector);
+      w1[1] = __byte_perm (w0[1], w0[2], selector);
+      w1[0] = __byte_perm (w0[0], w0[1], selector);
+      w0[3] = __byte_perm (    0, w0[0], selector);
       w0[2] = 0;
       w0[1] = 0;
       w0[0] = 0;
@@ -4563,16 +4525,16 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 4:
-      w3[1] = __byte_perm_S (w2[0], w2[1], selector);
-      w3[0] = __byte_perm_S (w1[3], w2[0], selector);
-      w2[3] = __byte_perm_S (w1[2], w1[3], selector);
-      w2[2] = __byte_perm_S (w1[1], w1[2], selector);
-      w2[1] = __byte_perm_S (w1[0], w1[1], selector);
-      w2[0] = __byte_perm_S (w0[3], w1[0], selector);
-      w1[3] = __byte_perm_S (w0[2], w0[3], selector);
-      w1[2] = __byte_perm_S (w0[1], w0[2], selector);
-      w1[1] = __byte_perm_S (w0[0], w0[1], selector);
-      w1[0] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w2[0], w2[1], selector);
+      w3[0] = __byte_perm (w1[3], w2[0], selector);
+      w2[3] = __byte_perm (w1[2], w1[3], selector);
+      w2[2] = __byte_perm (w1[1], w1[2], selector);
+      w2[1] = __byte_perm (w1[0], w1[1], selector);
+      w2[0] = __byte_perm (w0[3], w1[0], selector);
+      w1[3] = __byte_perm (w0[2], w0[3], selector);
+      w1[2] = __byte_perm (w0[1], w0[2], selector);
+      w1[1] = __byte_perm (w0[0], w0[1], selector);
+      w1[0] = __byte_perm (    0, w0[0], selector);
       w0[3] = 0;
       w0[2] = 0;
       w0[1] = 0;
@@ -4581,15 +4543,15 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 5:
-      w3[1] = __byte_perm_S (w1[3], w2[0], selector);
-      w3[0] = __byte_perm_S (w1[2], w1[3], selector);
-      w2[3] = __byte_perm_S (w1[1], w1[2], selector);
-      w2[2] = __byte_perm_S (w1[0], w1[1], selector);
-      w2[1] = __byte_perm_S (w0[3], w1[0], selector);
-      w2[0] = __byte_perm_S (w0[2], w0[3], selector);
-      w1[3] = __byte_perm_S (w0[1], w0[2], selector);
-      w1[2] = __byte_perm_S (w0[0], w0[1], selector);
-      w1[1] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w1[3], w2[0], selector);
+      w3[0] = __byte_perm (w1[2], w1[3], selector);
+      w2[3] = __byte_perm (w1[1], w1[2], selector);
+      w2[2] = __byte_perm (w1[0], w1[1], selector);
+      w2[1] = __byte_perm (w0[3], w1[0], selector);
+      w2[0] = __byte_perm (w0[2], w0[3], selector);
+      w1[3] = __byte_perm (w0[1], w0[2], selector);
+      w1[2] = __byte_perm (w0[0], w0[1], selector);
+      w1[1] = __byte_perm (    0, w0[0], selector);
       w1[0] = 0;
       w0[3] = 0;
       w0[2] = 0;
@@ -4599,14 +4561,14 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 6:
-      w3[1] = __byte_perm_S (w1[2], w1[3], selector);
-      w3[0] = __byte_perm_S (w1[1], w1[2], selector);
-      w2[3] = __byte_perm_S (w1[0], w1[1], selector);
-      w2[2] = __byte_perm_S (w0[3], w1[0], selector);
-      w2[1] = __byte_perm_S (w0[2], w0[3], selector);
-      w2[0] = __byte_perm_S (w0[1], w0[2], selector);
-      w1[3] = __byte_perm_S (w0[0], w0[1], selector);
-      w1[2] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w1[2], w1[3], selector);
+      w3[0] = __byte_perm (w1[1], w1[2], selector);
+      w2[3] = __byte_perm (w1[0], w1[1], selector);
+      w2[2] = __byte_perm (w0[3], w1[0], selector);
+      w2[1] = __byte_perm (w0[2], w0[3], selector);
+      w2[0] = __byte_perm (w0[1], w0[2], selector);
+      w1[3] = __byte_perm (w0[0], w0[1], selector);
+      w1[2] = __byte_perm (    0, w0[0], selector);
       w1[1] = 0;
       w1[0] = 0;
       w0[3] = 0;
@@ -4617,13 +4579,13 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 7:
-      w3[1] = __byte_perm_S (w1[1], w1[2], selector);
-      w3[0] = __byte_perm_S (w1[0], w1[1], selector);
-      w2[3] = __byte_perm_S (w0[3], w1[0], selector);
-      w2[2] = __byte_perm_S (w0[2], w0[3], selector);
-      w2[1] = __byte_perm_S (w0[1], w0[2], selector);
-      w2[0] = __byte_perm_S (w0[0], w0[1], selector);
-      w1[3] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w1[1], w1[2], selector);
+      w3[0] = __byte_perm (w1[0], w1[1], selector);
+      w2[3] = __byte_perm (w0[3], w1[0], selector);
+      w2[2] = __byte_perm (w0[2], w0[3], selector);
+      w2[1] = __byte_perm (w0[1], w0[2], selector);
+      w2[0] = __byte_perm (w0[0], w0[1], selector);
+      w1[3] = __byte_perm (    0, w0[0], selector);
       w1[2] = 0;
       w1[1] = 0;
       w1[0] = 0;
@@ -4635,12 +4597,12 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 8:
-      w3[1] = __byte_perm_S (w1[0], w1[1], selector);
-      w3[0] = __byte_perm_S (w0[3], w1[0], selector);
-      w2[3] = __byte_perm_S (w0[2], w0[3], selector);
-      w2[2] = __byte_perm_S (w0[1], w0[2], selector);
-      w2[1] = __byte_perm_S (w0[0], w0[1], selector);
-      w2[0] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w1[0], w1[1], selector);
+      w3[0] = __byte_perm (w0[3], w1[0], selector);
+      w2[3] = __byte_perm (w0[2], w0[3], selector);
+      w2[2] = __byte_perm (w0[1], w0[2], selector);
+      w2[1] = __byte_perm (w0[0], w0[1], selector);
+      w2[0] = __byte_perm (    0, w0[0], selector);
       w1[3] = 0;
       w1[2] = 0;
       w1[1] = 0;
@@ -4653,11 +4615,11 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 9:
-      w3[1] = __byte_perm_S (w0[3], w1[0], selector);
-      w3[0] = __byte_perm_S (w0[2], w0[3], selector);
-      w2[3] = __byte_perm_S (w0[1], w0[2], selector);
-      w2[2] = __byte_perm_S (w0[0], w0[1], selector);
-      w2[1] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w0[3], w1[0], selector);
+      w3[0] = __byte_perm (w0[2], w0[3], selector);
+      w2[3] = __byte_perm (w0[1], w0[2], selector);
+      w2[2] = __byte_perm (w0[0], w0[1], selector);
+      w2[1] = __byte_perm (    0, w0[0], selector);
       w2[0] = 0;
       w1[3] = 0;
       w1[2] = 0;
@@ -4671,10 +4633,10 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 10:
-      w3[1] = __byte_perm_S (w0[2], w0[3], selector);
-      w3[0] = __byte_perm_S (w0[1], w0[2], selector);
-      w2[3] = __byte_perm_S (w0[0], w0[1], selector);
-      w2[2] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w0[2], w0[3], selector);
+      w3[0] = __byte_perm (w0[1], w0[2], selector);
+      w2[3] = __byte_perm (w0[0], w0[1], selector);
+      w2[2] = __byte_perm (    0, w0[0], selector);
       w2[1] = 0;
       w2[0] = 0;
       w1[3] = 0;
@@ -4689,9 +4651,9 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 11:
-      w3[1] = __byte_perm_S (w0[1], w0[2], selector);
-      w3[0] = __byte_perm_S (w0[0], w0[1], selector);
-      w2[3] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w0[1], w0[2], selector);
+      w3[0] = __byte_perm (w0[0], w0[1], selector);
+      w2[3] = __byte_perm (    0, w0[0], selector);
       w2[2] = 0;
       w2[1] = 0;
       w2[0] = 0;
@@ -4707,8 +4669,8 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 12:
-      w3[1] = __byte_perm_S (w0[0], w0[1], selector);
-      w3[0] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (w0[0], w0[1], selector);
+      w3[0] = __byte_perm (    0, w0[0], selector);
       w2[3] = 0;
       w2[2] = 0;
       w2[1] = 0;
@@ -4725,7 +4687,7 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 13:
-      w3[1] = __byte_perm_S (    0, w0[0], selector);
+      w3[1] = __byte_perm (    0, w0[0], selector);
       w3[0] = 0;
       w2[3] = 0;
       w2[2] = 0;
@@ -4745,95 +4707,95 @@ static void switch_buffer_by_offset_S    (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
   #endif
 }
 
-static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 offset)
+inline void switch_buffer_by_offset_be (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32 offset)
 {
   #if defined IS_AMD || defined IS_GENERIC
   switch (offset / 4)
   {
     case 0:
-      w3[2] = amd_bytealign_S (w3[1],     0, offset);
-      w3[1] = amd_bytealign_S (w3[0], w3[1], offset);
-      w3[0] = amd_bytealign_S (w2[3], w3[0], offset);
-      w2[3] = amd_bytealign_S (w2[2], w2[3], offset);
-      w2[2] = amd_bytealign_S (w2[1], w2[2], offset);
-      w2[1] = amd_bytealign_S (w2[0], w2[1], offset);
-      w2[0] = amd_bytealign_S (w1[3], w2[0], offset);
-      w1[3] = amd_bytealign_S (w1[2], w1[3], offset);
-      w1[2] = amd_bytealign_S (w1[1], w1[2], offset);
-      w1[1] = amd_bytealign_S (w1[0], w1[1], offset);
-      w1[0] = amd_bytealign_S (w0[3], w1[0], offset);
-      w0[3] = amd_bytealign_S (w0[2], w0[3], offset);
-      w0[2] = amd_bytealign_S (w0[1], w0[2], offset);
-      w0[1] = amd_bytealign_S (w0[0], w0[1], offset);
-      w0[0] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w3[1],     0, offset);
+      w3[1] = amd_bytealign (w3[0], w3[1], offset);
+      w3[0] = amd_bytealign (w2[3], w3[0], offset);
+      w2[3] = amd_bytealign (w2[2], w2[3], offset);
+      w2[2] = amd_bytealign (w2[1], w2[2], offset);
+      w2[1] = amd_bytealign (w2[0], w2[1], offset);
+      w2[0] = amd_bytealign (w1[3], w2[0], offset);
+      w1[3] = amd_bytealign (w1[2], w1[3], offset);
+      w1[2] = amd_bytealign (w1[1], w1[2], offset);
+      w1[1] = amd_bytealign (w1[0], w1[1], offset);
+      w1[0] = amd_bytealign (w0[3], w1[0], offset);
+      w0[3] = amd_bytealign (w0[2], w0[3], offset);
+      w0[2] = amd_bytealign (w0[1], w0[2], offset);
+      w0[1] = amd_bytealign (w0[0], w0[1], offset);
+      w0[0] = amd_bytealign (    0, w0[0], offset);
       break;
 
     case 1:
-      w3[2] = amd_bytealign_S (w3[0],     0, offset);
-      w3[1] = amd_bytealign_S (w2[3], w3[0], offset);
-      w3[0] = amd_bytealign_S (w2[2], w2[3], offset);
-      w2[3] = amd_bytealign_S (w2[1], w2[2], offset);
-      w2[2] = amd_bytealign_S (w2[0], w2[1], offset);
-      w2[1] = amd_bytealign_S (w1[3], w2[0], offset);
-      w2[0] = amd_bytealign_S (w1[2], w1[3], offset);
-      w1[3] = amd_bytealign_S (w1[1], w1[2], offset);
-      w1[2] = amd_bytealign_S (w1[0], w1[1], offset);
-      w1[1] = amd_bytealign_S (w0[3], w1[0], offset);
-      w1[0] = amd_bytealign_S (w0[2], w0[3], offset);
-      w0[3] = amd_bytealign_S (w0[1], w0[2], offset);
-      w0[2] = amd_bytealign_S (w0[0], w0[1], offset);
-      w0[1] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w3[0],     0, offset);
+      w3[1] = amd_bytealign (w2[3], w3[0], offset);
+      w3[0] = amd_bytealign (w2[2], w2[3], offset);
+      w2[3] = amd_bytealign (w2[1], w2[2], offset);
+      w2[2] = amd_bytealign (w2[0], w2[1], offset);
+      w2[1] = amd_bytealign (w1[3], w2[0], offset);
+      w2[0] = amd_bytealign (w1[2], w1[3], offset);
+      w1[3] = amd_bytealign (w1[1], w1[2], offset);
+      w1[2] = amd_bytealign (w1[0], w1[1], offset);
+      w1[1] = amd_bytealign (w0[3], w1[0], offset);
+      w1[0] = amd_bytealign (w0[2], w0[3], offset);
+      w0[3] = amd_bytealign (w0[1], w0[2], offset);
+      w0[2] = amd_bytealign (w0[0], w0[1], offset);
+      w0[1] = amd_bytealign (    0, w0[0], offset);
       w0[0] = 0;
       break;
 
     case 2:
-      w3[2] = amd_bytealign_S (w2[3],     0, offset);
-      w3[1] = amd_bytealign_S (w2[2], w2[3], offset);
-      w3[0] = amd_bytealign_S (w2[1], w2[2], offset);
-      w2[3] = amd_bytealign_S (w2[0], w2[1], offset);
-      w2[2] = amd_bytealign_S (w1[3], w2[0], offset);
-      w2[1] = amd_bytealign_S (w1[2], w1[3], offset);
-      w2[0] = amd_bytealign_S (w1[1], w1[2], offset);
-      w1[3] = amd_bytealign_S (w1[0], w1[1], offset);
-      w1[2] = amd_bytealign_S (w0[3], w1[0], offset);
-      w1[1] = amd_bytealign_S (w0[2], w0[3], offset);
-      w1[0] = amd_bytealign_S (w0[1], w0[2], offset);
-      w0[3] = amd_bytealign_S (w0[0], w0[1], offset);
-      w0[2] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w2[3],     0, offset);
+      w3[1] = amd_bytealign (w2[2], w2[3], offset);
+      w3[0] = amd_bytealign (w2[1], w2[2], offset);
+      w2[3] = amd_bytealign (w2[0], w2[1], offset);
+      w2[2] = amd_bytealign (w1[3], w2[0], offset);
+      w2[1] = amd_bytealign (w1[2], w1[3], offset);
+      w2[0] = amd_bytealign (w1[1], w1[2], offset);
+      w1[3] = amd_bytealign (w1[0], w1[1], offset);
+      w1[2] = amd_bytealign (w0[3], w1[0], offset);
+      w1[1] = amd_bytealign (w0[2], w0[3], offset);
+      w1[0] = amd_bytealign (w0[1], w0[2], offset);
+      w0[3] = amd_bytealign (w0[0], w0[1], offset);
+      w0[2] = amd_bytealign (    0, w0[0], offset);
       w0[1] = 0;
       w0[0] = 0;
       break;
 
     case 3:
-      w3[2] = amd_bytealign_S (w2[2],     0, offset);
-      w3[1] = amd_bytealign_S (w2[1], w2[2], offset);
-      w3[0] = amd_bytealign_S (w2[0], w2[1], offset);
-      w2[3] = amd_bytealign_S (w1[3], w2[0], offset);
-      w2[2] = amd_bytealign_S (w1[2], w1[3], offset);
-      w2[1] = amd_bytealign_S (w1[1], w1[2], offset);
-      w2[0] = amd_bytealign_S (w1[0], w1[1], offset);
-      w1[3] = amd_bytealign_S (w0[3], w1[0], offset);
-      w1[2] = amd_bytealign_S (w0[2], w0[3], offset);
-      w1[1] = amd_bytealign_S (w0[1], w0[2], offset);
-      w1[0] = amd_bytealign_S (w0[0], w0[1], offset);
-      w0[3] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w2[2],     0, offset);
+      w3[1] = amd_bytealign (w2[1], w2[2], offset);
+      w3[0] = amd_bytealign (w2[0], w2[1], offset);
+      w2[3] = amd_bytealign (w1[3], w2[0], offset);
+      w2[2] = amd_bytealign (w1[2], w1[3], offset);
+      w2[1] = amd_bytealign (w1[1], w1[2], offset);
+      w2[0] = amd_bytealign (w1[0], w1[1], offset);
+      w1[3] = amd_bytealign (w0[3], w1[0], offset);
+      w1[2] = amd_bytealign (w0[2], w0[3], offset);
+      w1[1] = amd_bytealign (w0[1], w0[2], offset);
+      w1[0] = amd_bytealign (w0[0], w0[1], offset);
+      w0[3] = amd_bytealign (    0, w0[0], offset);
       w0[2] = 0;
       w0[1] = 0;
       w0[0] = 0;
       break;
 
     case 4:
-      w3[2] = amd_bytealign_S (w2[1],     0, offset);
-      w3[1] = amd_bytealign_S (w2[0], w2[1], offset);
-      w3[0] = amd_bytealign_S (w1[3], w2[0], offset);
-      w2[3] = amd_bytealign_S (w1[2], w1[3], offset);
-      w2[2] = amd_bytealign_S (w1[1], w1[2], offset);
-      w2[1] = amd_bytealign_S (w1[0], w1[1], offset);
-      w2[0] = amd_bytealign_S (w0[3], w1[0], offset);
-      w1[3] = amd_bytealign_S (w0[2], w0[3], offset);
-      w1[2] = amd_bytealign_S (w0[1], w0[2], offset);
-      w1[1] = amd_bytealign_S (w0[0], w0[1], offset);
-      w1[0] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w2[1],     0, offset);
+      w3[1] = amd_bytealign (w2[0], w2[1], offset);
+      w3[0] = amd_bytealign (w1[3], w2[0], offset);
+      w2[3] = amd_bytealign (w1[2], w1[3], offset);
+      w2[2] = amd_bytealign (w1[1], w1[2], offset);
+      w2[1] = amd_bytealign (w1[0], w1[1], offset);
+      w2[0] = amd_bytealign (w0[3], w1[0], offset);
+      w1[3] = amd_bytealign (w0[2], w0[3], offset);
+      w1[2] = amd_bytealign (w0[1], w0[2], offset);
+      w1[1] = amd_bytealign (w0[0], w0[1], offset);
+      w1[0] = amd_bytealign (    0, w0[0], offset);
       w0[3] = 0;
       w0[2] = 0;
       w0[1] = 0;
@@ -4841,16 +4803,16 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 5:
-      w3[2] = amd_bytealign_S (w2[0],     0, offset);
-      w3[1] = amd_bytealign_S (w1[3], w2[0], offset);
-      w3[0] = amd_bytealign_S (w1[2], w1[3], offset);
-      w2[3] = amd_bytealign_S (w1[1], w1[2], offset);
-      w2[2] = amd_bytealign_S (w1[0], w1[1], offset);
-      w2[1] = amd_bytealign_S (w0[3], w1[0], offset);
-      w2[0] = amd_bytealign_S (w0[2], w0[3], offset);
-      w1[3] = amd_bytealign_S (w0[1], w0[2], offset);
-      w1[2] = amd_bytealign_S (w0[0], w0[1], offset);
-      w1[1] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w2[0],     0, offset);
+      w3[1] = amd_bytealign (w1[3], w2[0], offset);
+      w3[0] = amd_bytealign (w1[2], w1[3], offset);
+      w2[3] = amd_bytealign (w1[1], w1[2], offset);
+      w2[2] = amd_bytealign (w1[0], w1[1], offset);
+      w2[1] = amd_bytealign (w0[3], w1[0], offset);
+      w2[0] = amd_bytealign (w0[2], w0[3], offset);
+      w1[3] = amd_bytealign (w0[1], w0[2], offset);
+      w1[2] = amd_bytealign (w0[0], w0[1], offset);
+      w1[1] = amd_bytealign (    0, w0[0], offset);
       w1[0] = 0;
       w0[3] = 0;
       w0[2] = 0;
@@ -4859,15 +4821,15 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 6:
-      w3[2] = amd_bytealign_S (w1[3],     0, offset);
-      w3[1] = amd_bytealign_S (w1[2], w1[3], offset);
-      w3[0] = amd_bytealign_S (w1[1], w1[2], offset);
-      w2[3] = amd_bytealign_S (w1[0], w1[1], offset);
-      w2[2] = amd_bytealign_S (w0[3], w1[0], offset);
-      w2[1] = amd_bytealign_S (w0[2], w0[3], offset);
-      w2[0] = amd_bytealign_S (w0[1], w0[2], offset);
-      w1[3] = amd_bytealign_S (w0[0], w0[1], offset);
-      w1[2] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w1[3],     0, offset);
+      w3[1] = amd_bytealign (w1[2], w1[3], offset);
+      w3[0] = amd_bytealign (w1[1], w1[2], offset);
+      w2[3] = amd_bytealign (w1[0], w1[1], offset);
+      w2[2] = amd_bytealign (w0[3], w1[0], offset);
+      w2[1] = amd_bytealign (w0[2], w0[3], offset);
+      w2[0] = amd_bytealign (w0[1], w0[2], offset);
+      w1[3] = amd_bytealign (w0[0], w0[1], offset);
+      w1[2] = amd_bytealign (    0, w0[0], offset);
       w1[1] = 0;
       w1[0] = 0;
       w0[3] = 0;
@@ -4877,14 +4839,14 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 7:
-      w3[2] = amd_bytealign_S (w1[2],     0, offset);
-      w3[1] = amd_bytealign_S (w1[1], w1[2], offset);
-      w3[0] = amd_bytealign_S (w1[0], w1[1], offset);
-      w2[3] = amd_bytealign_S (w0[3], w1[0], offset);
-      w2[2] = amd_bytealign_S (w0[2], w0[3], offset);
-      w2[1] = amd_bytealign_S (w0[1], w0[2], offset);
-      w2[0] = amd_bytealign_S (w0[0], w0[1], offset);
-      w1[3] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w1[2],     0, offset);
+      w3[1] = amd_bytealign (w1[1], w1[2], offset);
+      w3[0] = amd_bytealign (w1[0], w1[1], offset);
+      w2[3] = amd_bytealign (w0[3], w1[0], offset);
+      w2[2] = amd_bytealign (w0[2], w0[3], offset);
+      w2[1] = amd_bytealign (w0[1], w0[2], offset);
+      w2[0] = amd_bytealign (w0[0], w0[1], offset);
+      w1[3] = amd_bytealign (    0, w0[0], offset);
       w1[2] = 0;
       w1[1] = 0;
       w1[0] = 0;
@@ -4895,13 +4857,13 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 8:
-      w3[2] = amd_bytealign_S (w1[1],     0, offset);
-      w3[1] = amd_bytealign_S (w1[0], w1[1], offset);
-      w3[0] = amd_bytealign_S (w0[3], w1[0], offset);
-      w2[3] = amd_bytealign_S (w0[2], w0[3], offset);
-      w2[2] = amd_bytealign_S (w0[1], w0[2], offset);
-      w2[1] = amd_bytealign_S (w0[0], w0[1], offset);
-      w2[0] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w1[1],     0, offset);
+      w3[1] = amd_bytealign (w1[0], w1[1], offset);
+      w3[0] = amd_bytealign (w0[3], w1[0], offset);
+      w2[3] = amd_bytealign (w0[2], w0[3], offset);
+      w2[2] = amd_bytealign (w0[1], w0[2], offset);
+      w2[1] = amd_bytealign (w0[0], w0[1], offset);
+      w2[0] = amd_bytealign (    0, w0[0], offset);
       w1[3] = 0;
       w1[2] = 0;
       w1[1] = 0;
@@ -4913,12 +4875,12 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 9:
-      w3[2] = amd_bytealign_S (w1[0],     0, offset);
-      w3[1] = amd_bytealign_S (w0[3], w1[0], offset);
-      w3[0] = amd_bytealign_S (w0[2], w0[3], offset);
-      w2[3] = amd_bytealign_S (w0[1], w0[2], offset);
-      w2[2] = amd_bytealign_S (w0[0], w0[1], offset);
-      w2[1] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w1[0],     0, offset);
+      w3[1] = amd_bytealign (w0[3], w1[0], offset);
+      w3[0] = amd_bytealign (w0[2], w0[3], offset);
+      w2[3] = amd_bytealign (w0[1], w0[2], offset);
+      w2[2] = amd_bytealign (w0[0], w0[1], offset);
+      w2[1] = amd_bytealign (    0, w0[0], offset);
       w2[0] = 0;
       w1[3] = 0;
       w1[2] = 0;
@@ -4931,11 +4893,11 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 10:
-      w3[2] = amd_bytealign_S (w0[3],     0, offset);
-      w3[1] = amd_bytealign_S (w0[2], w0[3], offset);
-      w3[0] = amd_bytealign_S (w0[1], w0[2], offset);
-      w2[3] = amd_bytealign_S (w0[0], w0[1], offset);
-      w2[2] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w0[3],     0, offset);
+      w3[1] = amd_bytealign (w0[2], w0[3], offset);
+      w3[0] = amd_bytealign (w0[1], w0[2], offset);
+      w2[3] = amd_bytealign (w0[0], w0[1], offset);
+      w2[2] = amd_bytealign (    0, w0[0], offset);
       w2[1] = 0;
       w2[0] = 0;
       w1[3] = 0;
@@ -4949,10 +4911,10 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 11:
-      w3[2] = amd_bytealign_S (w0[2],     0, offset);
-      w3[1] = amd_bytealign_S (w0[1], w0[2], offset);
-      w3[0] = amd_bytealign_S (w0[0], w0[1], offset);
-      w2[3] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w0[2],     0, offset);
+      w3[1] = amd_bytealign (w0[1], w0[2], offset);
+      w3[0] = amd_bytealign (w0[0], w0[1], offset);
+      w2[3] = amd_bytealign (    0, w0[0], offset);
       w2[2] = 0;
       w2[1] = 0;
       w2[0] = 0;
@@ -4967,9 +4929,9 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 12:
-      w3[2] = amd_bytealign_S (w0[1],     0, offset);
-      w3[1] = amd_bytealign_S (w0[0], w0[1], offset);
-      w3[0] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w0[1],     0, offset);
+      w3[1] = amd_bytealign (w0[0], w0[1], offset);
+      w3[0] = amd_bytealign (    0, w0[0], offset);
       w2[3] = 0;
       w2[2] = 0;
       w2[1] = 0;
@@ -4985,8 +4947,8 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 13:
-      w3[2] = amd_bytealign_S (w0[0],     0, offset);
-      w3[1] = amd_bytealign_S (    0, w0[0], offset);
+      w3[2] = amd_bytealign (w0[0],     0, offset);
+      w3[1] = amd_bytealign (    0, w0[0], offset);
       w3[0] = 0;
       w2[3] = 0;
       w2[2] = 0;
@@ -5010,84 +4972,84 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
   switch (offset / 4)
   {
     case 0:
-      w3[1] = __byte_perm_S (w3[1], w3[0], selector);
-      w3[0] = __byte_perm_S (w3[0], w2[3], selector);
-      w2[3] = __byte_perm_S (w2[3], w2[2], selector);
-      w2[2] = __byte_perm_S (w2[2], w2[1], selector);
-      w2[1] = __byte_perm_S (w2[1], w2[0], selector);
-      w2[0] = __byte_perm_S (w2[0], w1[3], selector);
-      w1[3] = __byte_perm_S (w1[3], w1[2], selector);
-      w1[2] = __byte_perm_S (w1[2], w1[1], selector);
-      w1[1] = __byte_perm_S (w1[1], w1[0], selector);
-      w1[0] = __byte_perm_S (w1[0], w0[3], selector);
-      w0[3] = __byte_perm_S (w0[3], w0[2], selector);
-      w0[2] = __byte_perm_S (w0[2], w0[1], selector);
-      w0[1] = __byte_perm_S (w0[1], w0[0], selector);
-      w0[0] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w3[1], w3[0], selector);
+      w3[0] = __byte_perm (w3[0], w2[3], selector);
+      w2[3] = __byte_perm (w2[3], w2[2], selector);
+      w2[2] = __byte_perm (w2[2], w2[1], selector);
+      w2[1] = __byte_perm (w2[1], w2[0], selector);
+      w2[0] = __byte_perm (w2[0], w1[3], selector);
+      w1[3] = __byte_perm (w1[3], w1[2], selector);
+      w1[2] = __byte_perm (w1[2], w1[1], selector);
+      w1[1] = __byte_perm (w1[1], w1[0], selector);
+      w1[0] = __byte_perm (w1[0], w0[3], selector);
+      w0[3] = __byte_perm (w0[3], w0[2], selector);
+      w0[2] = __byte_perm (w0[2], w0[1], selector);
+      w0[1] = __byte_perm (w0[1], w0[0], selector);
+      w0[0] = __byte_perm (w0[0],     0, selector);
       break;
 
     case 1:
-      w3[1] = __byte_perm_S (w3[0], w2[3], selector);
-      w3[0] = __byte_perm_S (w2[3], w2[2], selector);
-      w2[3] = __byte_perm_S (w2[2], w2[1], selector);
-      w2[2] = __byte_perm_S (w2[1], w2[0], selector);
-      w2[1] = __byte_perm_S (w2[0], w1[3], selector);
-      w2[0] = __byte_perm_S (w1[3], w1[2], selector);
-      w1[3] = __byte_perm_S (w1[2], w1[1], selector);
-      w1[2] = __byte_perm_S (w1[1], w1[0], selector);
-      w1[1] = __byte_perm_S (w1[0], w0[3], selector);
-      w1[0] = __byte_perm_S (w0[3], w0[2], selector);
-      w0[3] = __byte_perm_S (w0[2], w0[1], selector);
-      w0[2] = __byte_perm_S (w0[1], w0[0], selector);
-      w0[1] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w3[0], w2[3], selector);
+      w3[0] = __byte_perm (w2[3], w2[2], selector);
+      w2[3] = __byte_perm (w2[2], w2[1], selector);
+      w2[2] = __byte_perm (w2[1], w2[0], selector);
+      w2[1] = __byte_perm (w2[0], w1[3], selector);
+      w2[0] = __byte_perm (w1[3], w1[2], selector);
+      w1[3] = __byte_perm (w1[2], w1[1], selector);
+      w1[2] = __byte_perm (w1[1], w1[0], selector);
+      w1[1] = __byte_perm (w1[0], w0[3], selector);
+      w1[0] = __byte_perm (w0[3], w0[2], selector);
+      w0[3] = __byte_perm (w0[2], w0[1], selector);
+      w0[2] = __byte_perm (w0[1], w0[0], selector);
+      w0[1] = __byte_perm (w0[0],     0, selector);
       w0[0] = 0;
       break;
 
     case 2:
-      w3[1] = __byte_perm_S (w2[3], w2[2], selector);
-      w3[0] = __byte_perm_S (w2[2], w2[1], selector);
-      w2[3] = __byte_perm_S (w2[1], w2[0], selector);
-      w2[2] = __byte_perm_S (w2[0], w1[3], selector);
-      w2[1] = __byte_perm_S (w1[3], w1[2], selector);
-      w2[0] = __byte_perm_S (w1[2], w1[1], selector);
-      w1[3] = __byte_perm_S (w1[1], w1[0], selector);
-      w1[2] = __byte_perm_S (w1[0], w0[3], selector);
-      w1[1] = __byte_perm_S (w0[3], w0[2], selector);
-      w1[0] = __byte_perm_S (w0[2], w0[1], selector);
-      w0[3] = __byte_perm_S (w0[1], w0[0], selector);
-      w0[2] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w2[3], w2[2], selector);
+      w3[0] = __byte_perm (w2[2], w2[1], selector);
+      w2[3] = __byte_perm (w2[1], w2[0], selector);
+      w2[2] = __byte_perm (w2[0], w1[3], selector);
+      w2[1] = __byte_perm (w1[3], w1[2], selector);
+      w2[0] = __byte_perm (w1[2], w1[1], selector);
+      w1[3] = __byte_perm (w1[1], w1[0], selector);
+      w1[2] = __byte_perm (w1[0], w0[3], selector);
+      w1[1] = __byte_perm (w0[3], w0[2], selector);
+      w1[0] = __byte_perm (w0[2], w0[1], selector);
+      w0[3] = __byte_perm (w0[1], w0[0], selector);
+      w0[2] = __byte_perm (w0[0],     0, selector);
       w0[1] = 0;
       w0[0] = 0;
       break;
 
     case 3:
-      w3[1] = __byte_perm_S (w2[2], w2[1], selector);
-      w3[0] = __byte_perm_S (w2[1], w2[0], selector);
-      w2[3] = __byte_perm_S (w2[0], w1[3], selector);
-      w2[2] = __byte_perm_S (w1[3], w1[2], selector);
-      w2[1] = __byte_perm_S (w1[2], w1[1], selector);
-      w2[0] = __byte_perm_S (w1[1], w1[0], selector);
-      w1[3] = __byte_perm_S (w1[0], w0[3], selector);
-      w1[2] = __byte_perm_S (w0[3], w0[2], selector);
-      w1[1] = __byte_perm_S (w0[2], w0[1], selector);
-      w1[0] = __byte_perm_S (w0[1], w0[0], selector);
-      w0[3] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w2[2], w2[1], selector);
+      w3[0] = __byte_perm (w2[1], w2[0], selector);
+      w2[3] = __byte_perm (w2[0], w1[3], selector);
+      w2[2] = __byte_perm (w1[3], w1[2], selector);
+      w2[1] = __byte_perm (w1[2], w1[1], selector);
+      w2[0] = __byte_perm (w1[1], w1[0], selector);
+      w1[3] = __byte_perm (w1[0], w0[3], selector);
+      w1[2] = __byte_perm (w0[3], w0[2], selector);
+      w1[1] = __byte_perm (w0[2], w0[1], selector);
+      w1[0] = __byte_perm (w0[1], w0[0], selector);
+      w0[3] = __byte_perm (w0[0],     0, selector);
       w0[2] = 0;
       w0[1] = 0;
       w0[0] = 0;
       break;
 
     case 4:
-      w3[1] = __byte_perm_S (w2[1], w2[0], selector);
-      w3[0] = __byte_perm_S (w2[0], w1[3], selector);
-      w2[3] = __byte_perm_S (w1[3], w1[2], selector);
-      w2[2] = __byte_perm_S (w1[2], w1[1], selector);
-      w2[1] = __byte_perm_S (w1[1], w1[0], selector);
-      w2[0] = __byte_perm_S (w1[0], w0[3], selector);
-      w1[3] = __byte_perm_S (w0[3], w0[2], selector);
-      w1[2] = __byte_perm_S (w0[2], w0[1], selector);
-      w1[1] = __byte_perm_S (w0[1], w0[0], selector);
-      w1[0] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w2[1], w2[0], selector);
+      w3[0] = __byte_perm (w2[0], w1[3], selector);
+      w2[3] = __byte_perm (w1[3], w1[2], selector);
+      w2[2] = __byte_perm (w1[2], w1[1], selector);
+      w2[1] = __byte_perm (w1[1], w1[0], selector);
+      w2[0] = __byte_perm (w1[0], w0[3], selector);
+      w1[3] = __byte_perm (w0[3], w0[2], selector);
+      w1[2] = __byte_perm (w0[2], w0[1], selector);
+      w1[1] = __byte_perm (w0[1], w0[0], selector);
+      w1[0] = __byte_perm (w0[0],     0, selector);
       w0[3] = 0;
       w0[2] = 0;
       w0[1] = 0;
@@ -5095,15 +5057,15 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 5:
-      w3[1] = __byte_perm_S (w2[0], w1[3], selector);
-      w3[0] = __byte_perm_S (w1[3], w1[2], selector);
-      w2[3] = __byte_perm_S (w1[2], w1[1], selector);
-      w2[2] = __byte_perm_S (w1[1], w1[0], selector);
-      w2[1] = __byte_perm_S (w1[0], w0[3], selector);
-      w2[0] = __byte_perm_S (w0[3], w0[2], selector);
-      w1[3] = __byte_perm_S (w0[2], w0[1], selector);
-      w1[2] = __byte_perm_S (w0[1], w0[0], selector);
-      w1[1] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w2[0], w1[3], selector);
+      w3[0] = __byte_perm (w1[3], w1[2], selector);
+      w2[3] = __byte_perm (w1[2], w1[1], selector);
+      w2[2] = __byte_perm (w1[1], w1[0], selector);
+      w2[1] = __byte_perm (w1[0], w0[3], selector);
+      w2[0] = __byte_perm (w0[3], w0[2], selector);
+      w1[3] = __byte_perm (w0[2], w0[1], selector);
+      w1[2] = __byte_perm (w0[1], w0[0], selector);
+      w1[1] = __byte_perm (w0[0],     0, selector);
       w1[0] = 0;
       w0[3] = 0;
       w0[2] = 0;
@@ -5112,14 +5074,14 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 6:
-      w3[1] = __byte_perm_S (w1[3], w1[2], selector);
-      w3[0] = __byte_perm_S (w1[2], w1[1], selector);
-      w2[3] = __byte_perm_S (w1[1], w1[0], selector);
-      w2[2] = __byte_perm_S (w1[0], w0[3], selector);
-      w2[1] = __byte_perm_S (w0[3], w0[2], selector);
-      w2[0] = __byte_perm_S (w0[2], w0[1], selector);
-      w1[3] = __byte_perm_S (w0[1], w0[0], selector);
-      w1[2] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w1[3], w1[2], selector);
+      w3[0] = __byte_perm (w1[2], w1[1], selector);
+      w2[3] = __byte_perm (w1[1], w1[0], selector);
+      w2[2] = __byte_perm (w1[0], w0[3], selector);
+      w2[1] = __byte_perm (w0[3], w0[2], selector);
+      w2[0] = __byte_perm (w0[2], w0[1], selector);
+      w1[3] = __byte_perm (w0[1], w0[0], selector);
+      w1[2] = __byte_perm (w0[0],     0, selector);
       w1[1] = 0;
       w1[0] = 0;
       w0[3] = 0;
@@ -5129,13 +5091,13 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 7:
-      w3[1] = __byte_perm_S (w1[2], w1[1], selector);
-      w3[0] = __byte_perm_S (w1[1], w1[0], selector);
-      w2[3] = __byte_perm_S (w1[0], w0[3], selector);
-      w2[2] = __byte_perm_S (w0[3], w0[2], selector);
-      w2[1] = __byte_perm_S (w0[2], w0[1], selector);
-      w2[0] = __byte_perm_S (w0[1], w0[0], selector);
-      w1[3] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w1[2], w1[1], selector);
+      w3[0] = __byte_perm (w1[1], w1[0], selector);
+      w2[3] = __byte_perm (w1[0], w0[3], selector);
+      w2[2] = __byte_perm (w0[3], w0[2], selector);
+      w2[1] = __byte_perm (w0[2], w0[1], selector);
+      w2[0] = __byte_perm (w0[1], w0[0], selector);
+      w1[3] = __byte_perm (w0[0],     0, selector);
       w1[2] = 0;
       w1[1] = 0;
       w1[0] = 0;
@@ -5146,12 +5108,12 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 8:
-      w3[1] = __byte_perm_S (w1[1], w1[0], selector);
-      w3[0] = __byte_perm_S (w1[0], w0[3], selector);
-      w2[3] = __byte_perm_S (w0[3], w0[2], selector);
-      w2[2] = __byte_perm_S (w0[2], w0[1], selector);
-      w2[1] = __byte_perm_S (w0[1], w0[0], selector);
-      w2[0] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w1[1], w1[0], selector);
+      w3[0] = __byte_perm (w1[0], w0[3], selector);
+      w2[3] = __byte_perm (w0[3], w0[2], selector);
+      w2[2] = __byte_perm (w0[2], w0[1], selector);
+      w2[1] = __byte_perm (w0[1], w0[0], selector);
+      w2[0] = __byte_perm (w0[0],     0, selector);
       w1[3] = 0;
       w1[2] = 0;
       w1[1] = 0;
@@ -5163,11 +5125,11 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 9:
-      w3[1] = __byte_perm_S (w1[0], w0[3], selector);
-      w3[0] = __byte_perm_S (w0[3], w0[2], selector);
-      w2[3] = __byte_perm_S (w0[2], w0[1], selector);
-      w2[2] = __byte_perm_S (w0[1], w0[0], selector);
-      w2[1] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w1[0], w0[3], selector);
+      w3[0] = __byte_perm (w0[3], w0[2], selector);
+      w2[3] = __byte_perm (w0[2], w0[1], selector);
+      w2[2] = __byte_perm (w0[1], w0[0], selector);
+      w2[1] = __byte_perm (w0[0],     0, selector);
       w2[0] = 0;
       w1[3] = 0;
       w1[2] = 0;
@@ -5180,10 +5142,10 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 10:
-      w3[1] = __byte_perm_S (w0[3], w0[2], selector);
-      w3[0] = __byte_perm_S (w0[2], w0[1], selector);
-      w2[3] = __byte_perm_S (w0[1], w0[0], selector);
-      w2[2] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w0[3], w0[2], selector);
+      w3[0] = __byte_perm (w0[2], w0[1], selector);
+      w2[3] = __byte_perm (w0[1], w0[0], selector);
+      w2[2] = __byte_perm (w0[0],     0, selector);
       w2[1] = 0;
       w2[0] = 0;
       w1[3] = 0;
@@ -5197,9 +5159,9 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 11:
-      w3[1] = __byte_perm_S (w0[2], w0[1], selector);
-      w3[0] = __byte_perm_S (w0[1], w0[0], selector);
-      w2[3] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w0[2], w0[1], selector);
+      w3[0] = __byte_perm (w0[1], w0[0], selector);
+      w2[3] = __byte_perm (w0[0],     0, selector);
       w2[2] = 0;
       w2[1] = 0;
       w2[0] = 0;
@@ -5214,8 +5176,8 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 12:
-      w3[1] = __byte_perm_S (w0[1], w0[0], selector);
-      w3[0] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w0[1], w0[0], selector);
+      w3[0] = __byte_perm (w0[0],     0, selector);
       w2[3] = 0;
       w2[2] = 0;
       w2[1] = 0;
@@ -5231,7 +5193,7 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
       break;
 
     case 13:
-      w3[1] = __byte_perm_S (w0[0],     0, selector);
+      w3[1] = __byte_perm (w0[0],     0, selector);
       w3[0] = 0;
       w2[3] = 0;
       w2[2] = 0;
@@ -5250,3984 +5212,3248 @@ static void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w
   #endif
 }
 
-static void switch_buffer_by_offset    (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32 offset)
+inline void overwrite_at_le (u32x sw[16], const u32x w0, const u32 salt_len)
 {
-  #if defined IS_AMD || defined IS_GENERIC
-  const int offset_mod_4 = offset & 3;
+  #if defined cl_amd_media_ops
+  switch (salt_len)
+  {
+    case  0:  sw[0] = w0;
+              break;
+    case  1:  sw[0] = amd_bytealign (w0, sw[0] << 24, 3);
+              sw[1] = amd_bytealign (sw[1] >>  8, w0, 3);
+              break;
+    case  2:  sw[0] = amd_bytealign (w0, sw[0] << 16, 2);
+              sw[1] = amd_bytealign (sw[1] >> 16, w0, 2);
+              break;
+    case  3:  sw[0] = amd_bytealign (w0, sw[0] <<  8, 1);
+              sw[1] = amd_bytealign (sw[1] >> 24, w0, 1);
+              break;
+    case  4:  sw[1] = w0;
+              break;
+    case  5:  sw[1] = amd_bytealign (w0, sw[1] << 24, 3);
+              sw[2] = amd_bytealign (sw[2] >>  8, w0, 3);
+              break;
+    case  6:  sw[1] = amd_bytealign (w0, sw[1] << 16, 2);
+              sw[2] = amd_bytealign (sw[2] >> 16, w0, 2);
+              break;
+    case  7:  sw[1] = amd_bytealign (w0, sw[1] <<  8, 1);
+              sw[2] = amd_bytealign (sw[2] >> 24, w0, 1);
+              break;
+    case  8:  sw[2] = w0;
+              break;
+    case  9:  sw[2] = amd_bytealign (w0, sw[2] << 24, 3);
+              sw[3] = amd_bytealign (sw[3] >>  8, w0, 3);
+              break;
+    case 10:  sw[2] = amd_bytealign (w0, sw[2] << 16, 2);
+              sw[3] = amd_bytealign (sw[3] >> 16, w0, 2);
+              break;
+    case 11:  sw[2] = amd_bytealign (w0, sw[2] <<  8, 1);
+              sw[3] = amd_bytealign (sw[3] >> 24, w0, 1);
+              break;
+    case 12:  sw[3] = w0;
+              break;
+    case 13:  sw[3] = amd_bytealign (w0, sw[3] << 24, 3);
+              sw[4] = amd_bytealign (sw[4] >>  8, w0, 3);
+              break;
+    case 14:  sw[3] = amd_bytealign (w0, sw[3] << 16, 2);
+              sw[4] = amd_bytealign (sw[4] >> 16, w0, 2);
+              break;
+    case 15:  sw[3] = amd_bytealign (w0, sw[3] <<  8, 1);
+              sw[4] = amd_bytealign (sw[4] >> 24, w0, 1);
+              break;
+    case 16:  sw[4] = w0;
+              break;
+    case 17:  sw[4] = amd_bytealign (w0, sw[4] << 24, 3);
+              sw[5] = amd_bytealign (sw[5] >>  8, w0, 3);
+              break;
+    case 18:  sw[4] = amd_bytealign (w0, sw[4] << 16, 2);
+              sw[5] = amd_bytealign (sw[5] >> 16, w0, 2);
+              break;
+    case 19:  sw[4] = amd_bytealign (w0, sw[4] <<  8, 1);
+              sw[5] = amd_bytealign (sw[5] >> 24, w0, 1);
+              break;
+    case 20:  sw[5] = w0;
+              break;
+    case 21:  sw[5] = amd_bytealign (w0, sw[5] << 24, 3);
+              sw[6] = amd_bytealign (sw[6] >>  8, w0, 3);
+              break;
+    case 22:  sw[5] = amd_bytealign (w0, sw[5] << 16, 2);
+              sw[6] = amd_bytealign (sw[6] >> 16, w0, 2);
+              break;
+    case 23:  sw[5] = amd_bytealign (w0, sw[5] <<  8, 1);
+              sw[6] = amd_bytealign (sw[6] >> 24, w0, 1);
+              break;
+    case 24:  sw[6] = w0;
+              break;
+    case 25:  sw[6] = amd_bytealign (w0, sw[6] << 24, 3);
+              sw[7] = amd_bytealign (sw[7] >>  8, w0, 3);
+              break;
+    case 26:  sw[6] = amd_bytealign (w0, sw[6] << 16, 2);
+              sw[7] = amd_bytealign (sw[7] >> 16, w0, 2);
+              break;
+    case 27:  sw[6] = amd_bytealign (w0, sw[6] <<  8, 1);
+              sw[7] = amd_bytealign (sw[7] >> 24, w0, 1);
+              break;
+    case 28:  sw[7] = w0;
+              break;
+    case 29:  sw[7] = amd_bytealign (w0, sw[7] << 24, 3);
+              sw[8] = amd_bytealign (sw[8] >>  8, w0, 3);
+              break;
+    case 30:  sw[7] = amd_bytealign (w0, sw[7] << 16, 2);
+              sw[8] = amd_bytealign (sw[8] >> 16, w0, 2);
+              break;
+    case 31:  sw[7] = amd_bytealign (w0, sw[7] <<  8, 1);
+              sw[8] = amd_bytealign (sw[8] >> 24, w0, 1);
+              break;
+  }
+  #else
+  switch (salt_len)
+  {
+    case  0:  sw[0] =  w0;
+              break;
+    case  1:  sw[0] = (sw[0] & 0x000000ff) | (w0 <<  8);
+              sw[1] = (sw[1] & 0xffffff00) | (w0 >> 24);
+              break;
+    case  2:  sw[0] = (sw[0] & 0x0000ffff) | (w0 << 16);
+              sw[1] = (sw[1] & 0xffff0000) | (w0 >> 16);
+              break;
+    case  3:  sw[0] = (sw[0] & 0x00ffffff) | (w0 << 24);
+              sw[1] = (sw[1] & 0xff000000) | (w0 >>  8);
+              break;
+    case  4:  sw[1] =  w0;
+              break;
+    case  5:  sw[1] = (sw[1] & 0x000000ff) | (w0 <<  8);
+              sw[2] = (sw[2] & 0xffffff00) | (w0 >> 24);
+              break;
+    case  6:  sw[1] = (sw[1] & 0x0000ffff) | (w0 << 16);
+              sw[2] = (sw[2] & 0xffff0000) | (w0 >> 16);
+              break;
+    case  7:  sw[1] = (sw[1] & 0x00ffffff) | (w0 << 24);
+              sw[2] = (sw[2] & 0xff000000) | (w0 >>  8);
+              break;
+    case  8:  sw[2] =  w0;
+              break;
+    case  9:  sw[2] = (sw[2] & 0x000000ff) | (w0 <<  8);
+              sw[3] = (sw[3] & 0xffffff00) | (w0 >> 24);
+              break;
+    case 10:  sw[2] = (sw[2] & 0x0000ffff) | (w0 << 16);
+              sw[3] = (sw[3] & 0xffff0000) | (w0 >> 16);
+              break;
+    case 11:  sw[2] = (sw[2] & 0x00ffffff) | (w0 << 24);
+              sw[3] = (sw[3] & 0xff000000) | (w0 >>  8);
+              break;
+    case 12:  sw[3] =  w0;
+              break;
+    case 13:  sw[3] = (sw[3] & 0x000000ff) | (w0 <<  8);
+              sw[4] = (sw[4] & 0xffffff00) | (w0 >> 24);
+              break;
+    case 14:  sw[3] = (sw[3] & 0x0000ffff) | (w0 << 16);
+              sw[4] = (sw[4] & 0xffff0000) | (w0 >> 16);
+              break;
+    case 15:  sw[3] = (sw[3] & 0x00ffffff) | (w0 << 24);
+              sw[4] = (sw[4] & 0xff000000) | (w0 >>  8);
+              break;
+    case 16:  sw[4] =  w0;
+              break;
+    case 17:  sw[4] = (sw[4] & 0x000000ff) | (w0 <<  8);
+              sw[5] = (sw[5] & 0xffffff00) | (w0 >> 24);
+              break;
+    case 18:  sw[4] = (sw[4] & 0x0000ffff) | (w0 << 16);
+              sw[5] = (sw[5] & 0xffff0000) | (w0 >> 16);
+              break;
+    case 19:  sw[4] = (sw[4] & 0x00ffffff) | (w0 << 24);
+              sw[5] = (sw[5] & 0xff000000) | (w0 >>  8);
+              break;
+    case 20:  sw[5] =  w0;
+              break;
+    case 21:  sw[5] = (sw[5] & 0x000000ff) | (w0 <<  8);
+              sw[6] = (sw[6] & 0xffffff00) | (w0 >> 24);
+              break;
+    case 22:  sw[5] = (sw[5] & 0x0000ffff) | (w0 << 16);
+              sw[6] = (sw[6] & 0xffff0000) | (w0 >> 16);
+              break;
+    case 23:  sw[5] = (sw[5] & 0x00ffffff) | (w0 << 24);
+              sw[6] = (sw[6] & 0xff000000) | (w0 >>  8);
+              break;
+    case 24:  sw[6] =  w0;
+              break;
+    case 25:  sw[6] = (sw[6] & 0x000000ff) | (w0 <<  8);
+              sw[7] = (sw[7] & 0xffffff00) | (w0 >> 24);
+              break;
+    case 26:  sw[6] = (sw[6] & 0x0000ffff) | (w0 << 16);
+              sw[7] = (sw[7] & 0xffff0000) | (w0 >> 16);
+              break;
+    case 27:  sw[6] = (sw[6] & 0x00ffffff) | (w0 << 24);
+              sw[7] = (sw[7] & 0xff000000) | (w0 >>  8);
+              break;
+    case 28:  sw[7] =  w0;
+              break;
+    case 29:  sw[7] = (sw[7] & 0x000000ff) | (w0 <<  8);
+              sw[8] = (sw[8] & 0xffffff00) | (w0 >> 24);
+              break;
+    case 30:  sw[7] = (sw[7] & 0x0000ffff) | (w0 << 16);
+              sw[8] = (sw[8] & 0xffff0000) | (w0 >> 16);
+              break;
+    case 31:  sw[7] = (sw[7] & 0x00ffffff) | (w0 << 24);
+              sw[8] = (sw[8] & 0xff000000) | (w0 >>  8);
+              break;
+  }
+  #endif
+}
 
-  const int offset_minus_4 = 4 - offset;
+inline void overwrite_at_be (u32x sw[16], const u32x w0, const u32 salt_len)
+{
+  // would be nice to have optimization based on amd_bytealign as with _le counterpart
 
-  switch (offset / 4)
+  switch (salt_len)
   {
-    case 0:
-      w3[2] = amd_bytealign (    0, w3[1], offset_minus_4);
-      w3[1] = amd_bytealign (w3[1], w3[0], offset_minus_4);
-      w3[0] = amd_bytealign (w3[0], w2[3], offset_minus_4);
-      w2[3] = amd_bytealign (w2[3], w2[2], offset_minus_4);
-      w2[2] = amd_bytealign (w2[2], w2[1], offset_minus_4);
-      w2[1] = amd_bytealign (w2[1], w2[0], offset_minus_4);
-      w2[0] = amd_bytealign (w2[0], w1[3], offset_minus_4);
-      w1[3] = amd_bytealign (w1[3], w1[2], offset_minus_4);
-      w1[2] = amd_bytealign (w1[2], w1[1], offset_minus_4);
-      w1[1] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w1[0] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w0[3] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w0[2] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w0[1] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w0[0] = amd_bytealign (w0[0],     0, offset_minus_4);
-
-      if (offset_mod_4 == 0)
-      {
-        w0[0] = w0[1];
-        w0[1] = w0[2];
-        w0[2] = w0[3];
-        w0[3] = w1[0];
-        w1[0] = w1[1];
-        w1[1] = w1[2];
-        w1[2] = w1[3];
-        w1[3] = w2[0];
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 1:
-      w3[2] = amd_bytealign (    0, w3[0], offset_minus_4);
-      w3[1] = amd_bytealign (w3[0], w2[3], offset_minus_4);
-      w3[0] = amd_bytealign (w2[3], w2[2], offset_minus_4);
-      w2[3] = amd_bytealign (w2[2], w2[1], offset_minus_4);
-      w2[2] = amd_bytealign (w2[1], w2[0], offset_minus_4);
-      w2[1] = amd_bytealign (w2[0], w1[3], offset_minus_4);
-      w2[0] = amd_bytealign (w1[3], w1[2], offset_minus_4);
-      w1[3] = amd_bytealign (w1[2], w1[1], offset_minus_4);
-      w1[2] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w1[1] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w1[0] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w0[3] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w0[2] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w0[1] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w0[1] = w0[2];
-        w0[2] = w0[3];
-        w0[3] = w1[0];
-        w1[0] = w1[1];
-        w1[1] = w1[2];
-        w1[2] = w1[3];
-        w1[3] = w2[0];
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 2:
-      w3[2] = amd_bytealign (    0, w2[3], offset_minus_4);
-      w3[1] = amd_bytealign (w2[3], w2[2], offset_minus_4);
-      w3[0] = amd_bytealign (w2[2], w2[1], offset_minus_4);
-      w2[3] = amd_bytealign (w2[1], w2[0], offset_minus_4);
-      w2[2] = amd_bytealign (w2[0], w1[3], offset_minus_4);
-      w2[1] = amd_bytealign (w1[3], w1[2], offset_minus_4);
-      w2[0] = amd_bytealign (w1[2], w1[1], offset_minus_4);
-      w1[3] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w1[2] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w1[1] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w1[0] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w0[3] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w0[2] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w0[2] = w0[3];
-        w0[3] = w1[0];
-        w1[0] = w1[1];
-        w1[1] = w1[2];
-        w1[2] = w1[3];
-        w1[3] = w2[0];
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 3:
-      w3[2] = amd_bytealign (    0, w2[2], offset_minus_4);
-      w3[1] = amd_bytealign (w2[2], w2[1], offset_minus_4);
-      w3[0] = amd_bytealign (w2[1], w2[0], offset_minus_4);
-      w2[3] = amd_bytealign (w2[0], w1[3], offset_minus_4);
-      w2[2] = amd_bytealign (w1[3], w1[2], offset_minus_4);
-      w2[1] = amd_bytealign (w1[2], w1[1], offset_minus_4);
-      w2[0] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w1[3] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w1[2] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w1[1] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w1[0] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w0[3] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w0[3] = w1[0];
-        w1[0] = w1[1];
-        w1[1] = w1[2];
-        w1[2] = w1[3];
-        w1[3] = w2[0];
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 4:
-      w3[2] = amd_bytealign (    0, w2[1], offset_minus_4);
-      w3[1] = amd_bytealign (w2[1], w2[0], offset_minus_4);
-      w3[0] = amd_bytealign (w2[0], w1[3], offset_minus_4);
-      w2[3] = amd_bytealign (w1[3], w1[2], offset_minus_4);
-      w2[2] = amd_bytealign (w1[2], w1[1], offset_minus_4);
-      w2[1] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w2[0] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w1[3] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w1[2] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w1[1] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w1[0] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w1[0] = w1[1];
-        w1[1] = w1[2];
-        w1[2] = w1[3];
-        w1[3] = w2[0];
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 5:
-      w3[2] = amd_bytealign (    0, w2[0], offset_minus_4);
-      w3[1] = amd_bytealign (w2[0], w1[3], offset_minus_4);
-      w3[0] = amd_bytealign (w1[3], w1[2], offset_minus_4);
-      w2[3] = amd_bytealign (w1[2], w1[1], offset_minus_4);
-      w2[2] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w2[1] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w2[0] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w1[3] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w1[2] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w1[1] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w1[1] = w1[2];
-        w1[2] = w1[3];
-        w1[3] = w2[0];
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
+    case  0:  sw[0] =  w0;
+              break;
+    case  1:  sw[0] = (sw[0] & 0xff000000) | (w0 >>  8);
+              sw[1] = (sw[1] & 0x00ffffff) | (w0 << 24);
+              break;
+    case  2:  sw[0] = (sw[0] & 0xffff0000) | (w0 >> 16);
+              sw[1] = (sw[1] & 0x0000ffff) | (w0 << 16);
+              break;
+    case  3:  sw[0] = (sw[0] & 0xffffff00) | (w0 >> 24);
+              sw[1] = (sw[1] & 0x000000ff) | (w0 <<  8);
+              break;
+    case  4:  sw[1] =  w0;
+              break;
+    case  5:  sw[1] = (sw[1] & 0xff000000) | (w0 >>  8);
+              sw[2] = (sw[2] & 0x00ffffff) | (w0 << 24);
+              break;
+    case  6:  sw[1] = (sw[1] & 0xffff0000) | (w0 >> 16);
+              sw[2] = (sw[2] & 0x0000ffff) | (w0 << 16);
+              break;
+    case  7:  sw[1] = (sw[1] & 0xffffff00) | (w0 >> 24);
+              sw[2] = (sw[2] & 0x000000ff) | (w0 <<  8);
+              break;
+    case  8:  sw[2] =  w0;
+              break;
+    case  9:  sw[2] = (sw[2] & 0xff000000) | (w0 >>  8);
+              sw[3] = (sw[3] & 0x00ffffff) | (w0 << 24);
+              break;
+    case 10:  sw[2] = (sw[2] & 0xffff0000) | (w0 >> 16);
+              sw[3] = (sw[3] & 0x0000ffff) | (w0 << 16);
+              break;
+    case 11:  sw[2] = (sw[2] & 0xffffff00) | (w0 >> 24);
+              sw[3] = (sw[3] & 0x000000ff) | (w0 <<  8);
+              break;
+    case 12:  sw[3] =  w0;
+              break;
+    case 13:  sw[3] = (sw[3] & 0xff000000) | (w0 >>  8);
+              sw[4] = (sw[4] & 0x00ffffff) | (w0 << 24);
+              break;
+    case 14:  sw[3] = (sw[3] & 0xffff0000) | (w0 >> 16);
+              sw[4] = (sw[4] & 0x0000ffff) | (w0 << 16);
+              break;
+    case 15:  sw[3] = (sw[3] & 0xffffff00) | (w0 >> 24);
+              sw[4] = (sw[4] & 0x000000ff) | (w0 <<  8);
+              break;
+    case 16:  sw[4] =  w0;
+              break;
+    case 17:  sw[4] = (sw[4] & 0xff000000) | (w0 >>  8);
+              sw[5] = (sw[5] & 0x00ffffff) | (w0 << 24);
+              break;
+    case 18:  sw[4] = (sw[4] & 0xffff0000) | (w0 >> 16);
+              sw[5] = (sw[5] & 0x0000ffff) | (w0 << 16);
+              break;
+    case 19:  sw[4] = (sw[4] & 0xffffff00) | (w0 >> 24);
+              sw[5] = (sw[5] & 0x000000ff) | (w0 <<  8);
+              break;
+    case 20:  sw[5] =  w0;
+              break;
+    case 21:  sw[5] = (sw[5] & 0xff000000) | (w0 >>  8);
+              sw[6] = (sw[6] & 0x00ffffff) | (w0 << 24);
+              break;
+    case 22:  sw[5] = (sw[5] & 0xffff0000) | (w0 >> 16);
+              sw[6] = (sw[6] & 0x0000ffff) | (w0 << 16);
+              break;
+    case 23:  sw[5] = (sw[5] & 0xffffff00) | (w0 >> 24);
+              sw[6] = (sw[6] & 0x000000ff) | (w0 <<  8);
+              break;
+    case 24:  sw[6] =  w0;
+              break;
+    case 25:  sw[6] = (sw[6] & 0xff000000) | (w0 >>  8);
+              sw[7] = (sw[7] & 0x00ffffff) | (w0 << 24);
+              break;
+    case 26:  sw[6] = (sw[6] & 0xffff0000) | (w0 >> 16);
+              sw[7] = (sw[7] & 0x0000ffff) | (w0 << 16);
+              break;
+    case 27:  sw[6] = (sw[6] & 0xffffff00) | (w0 >> 24);
+              sw[7] = (sw[7] & 0x000000ff) | (w0 <<  8);
+              break;
+    case 28:  sw[7] =  w0;
+              break;
+    case 29:  sw[7] = (sw[7] & 0xff000000) | (w0 >>  8);
+              sw[8] = (sw[8] & 0x00ffffff) | (w0 << 24);
+              break;
+    case 30:  sw[7] = (sw[7] & 0xffff0000) | (w0 >> 16);
+              sw[8] = (sw[8] & 0x0000ffff) | (w0 << 16);
+              break;
+    case 31:  sw[7] = (sw[7] & 0xffffff00) | (w0 >> 24);
+              sw[8] = (sw[8] & 0x000000ff) | (w0 <<  8);
+              break;
+  }
+}
 
-    case 6:
-      w3[2] = amd_bytealign (    0, w1[3], offset_minus_4);
-      w3[1] = amd_bytealign (w1[3], w1[2], offset_minus_4);
-      w3[0] = amd_bytealign (w1[2], w1[1], offset_minus_4);
-      w2[3] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w2[2] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w2[1] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w2[0] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w1[3] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w1[2] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w1[2] = w1[3];
-        w1[3] = w2[0];
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 7:
-      w3[2] = amd_bytealign (    0, w1[2], offset_minus_4);
-      w3[1] = amd_bytealign (w1[2], w1[1], offset_minus_4);
-      w3[0] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w2[3] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w2[2] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w2[1] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w2[0] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w1[3] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w1[3] = w2[0];
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 8:
-      w3[2] = amd_bytealign (    0, w1[1], offset_minus_4);
-      w3[1] = amd_bytealign (w1[1], w1[0], offset_minus_4);
-      w3[0] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w2[3] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w2[2] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w2[1] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w2[0] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w2[0] = w2[1];
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 9:
-      w3[2] = amd_bytealign (    0, w1[0], offset_minus_4);
-      w3[1] = amd_bytealign (w1[0], w0[3], offset_minus_4);
-      w3[0] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w2[3] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w2[2] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w2[1] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w2[1] = w2[2];
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 10:
-      w3[2] = amd_bytealign (    0, w0[3], offset_minus_4);
-      w3[1] = amd_bytealign (w0[3], w0[2], offset_minus_4);
-      w3[0] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w2[3] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w2[2] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w2[2] = w2[3];
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 11:
-      w3[2] = amd_bytealign (    0, w0[2], offset_minus_4);
-      w3[1] = amd_bytealign (w0[2], w0[1], offset_minus_4);
-      w3[0] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w2[3] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w2[3] = w3[0];
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 12:
-      w3[2] = amd_bytealign (    0, w0[1], offset_minus_4);
-      w3[1] = amd_bytealign (w0[1], w0[0], offset_minus_4);
-      w3[0] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w2[3] = 0;
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w3[0] = w3[1];
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-
-    case 13:
-      w3[2] = amd_bytealign (    0, w0[0], offset_minus_4);
-      w3[1] = amd_bytealign (w0[0],     0, offset_minus_4);
-      w3[0] = 0;
-      w2[3] = 0;
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      if (offset_mod_4 == 0)
-      {
-        w3[1] = w3[2];
-        w3[2] = 0;
-      }
-
-      break;
-  }
-  #endif
-
-  #ifdef IS_NV
-  const int offset_minus_4 = 4 - (offset % 4);
-
-  const int selector = (0x76543210 >> (offset_minus_4 * 4)) & 0xffff;
-
-  switch (offset / 4)
+inline void overwrite_at_le_4x4 (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32x wx, const u32 salt_len)
+{
+  #if defined cl_amd_media_ops
+  switch (salt_len)
   {
-    case 0:
-      w3[1] = __byte_perm (w3[0], w3[1], selector);
-      w3[0] = __byte_perm (w2[3], w3[0], selector);
-      w2[3] = __byte_perm (w2[2], w2[3], selector);
-      w2[2] = __byte_perm (w2[1], w2[2], selector);
-      w2[1] = __byte_perm (w2[0], w2[1], selector);
-      w2[0] = __byte_perm (w1[3], w2[0], selector);
-      w1[3] = __byte_perm (w1[2], w1[3], selector);
-      w1[2] = __byte_perm (w1[1], w1[2], selector);
-      w1[1] = __byte_perm (w1[0], w1[1], selector);
-      w1[0] = __byte_perm (w0[3], w1[0], selector);
-      w0[3] = __byte_perm (w0[2], w0[3], selector);
-      w0[2] = __byte_perm (w0[1], w0[2], selector);
-      w0[1] = __byte_perm (w0[0], w0[1], selector);
-      w0[0] = __byte_perm (    0, w0[0], selector);
-
-      break;
-
-    case 1:
-      w3[1] = __byte_perm (w2[3], w3[0], selector);
-      w3[0] = __byte_perm (w2[2], w2[3], selector);
-      w2[3] = __byte_perm (w2[1], w2[2], selector);
-      w2[2] = __byte_perm (w2[0], w2[1], selector);
-      w2[1] = __byte_perm (w1[3], w2[0], selector);
-      w2[0] = __byte_perm (w1[2], w1[3], selector);
-      w1[3] = __byte_perm (w1[1], w1[2], selector);
-      w1[2] = __byte_perm (w1[0], w1[1], selector);
-      w1[1] = __byte_perm (w0[3], w1[0], selector);
-      w1[0] = __byte_perm (w0[2], w0[3], selector);
-      w0[3] = __byte_perm (w0[1], w0[2], selector);
-      w0[2] = __byte_perm (w0[0], w0[1], selector);
-      w0[1] = __byte_perm (    0, w0[0], selector);
-      w0[0] = 0;
-
-      break;
-
-    case 2:
-      w3[1] = __byte_perm (w2[2], w2[3], selector);
-      w3[0] = __byte_perm (w2[1], w2[2], selector);
-      w2[3] = __byte_perm (w2[0], w2[1], selector);
-      w2[2] = __byte_perm (w1[3], w2[0], selector);
-      w2[1] = __byte_perm (w1[2], w1[3], selector);
-      w2[0] = __byte_perm (w1[1], w1[2], selector);
-      w1[3] = __byte_perm (w1[0], w1[1], selector);
-      w1[2] = __byte_perm (w0[3], w1[0], selector);
-      w1[1] = __byte_perm (w0[2], w0[3], selector);
-      w1[0] = __byte_perm (w0[1], w0[2], selector);
-      w0[3] = __byte_perm (w0[0], w0[1], selector);
-      w0[2] = __byte_perm (    0, w0[0], selector);
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 3:
-      w3[1] = __byte_perm (w2[1], w2[2], selector);
-      w3[0] = __byte_perm (w2[0], w2[1], selector);
-      w2[3] = __byte_perm (w1[3], w2[0], selector);
-      w2[2] = __byte_perm (w1[2], w1[3], selector);
-      w2[1] = __byte_perm (w1[1], w1[2], selector);
-      w2[0] = __byte_perm (w1[0], w1[1], selector);
-      w1[3] = __byte_perm (w0[3], w1[0], selector);
-      w1[2] = __byte_perm (w0[2], w0[3], selector);
-      w1[1] = __byte_perm (w0[1], w0[2], selector);
-      w1[0] = __byte_perm (w0[0], w0[1], selector);
-      w0[3] = __byte_perm (    0, w0[0], selector);
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 4:
-      w3[1] = __byte_perm (w2[0], w2[1], selector);
-      w3[0] = __byte_perm (w1[3], w2[0], selector);
-      w2[3] = __byte_perm (w1[2], w1[3], selector);
-      w2[2] = __byte_perm (w1[1], w1[2], selector);
-      w2[1] = __byte_perm (w1[0], w1[1], selector);
-      w2[0] = __byte_perm (w0[3], w1[0], selector);
-      w1[3] = __byte_perm (w0[2], w0[3], selector);
-      w1[2] = __byte_perm (w0[1], w0[2], selector);
-      w1[1] = __byte_perm (w0[0], w0[1], selector);
-      w1[0] = __byte_perm (    0, w0[0], selector);
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 5:
-      w3[1] = __byte_perm (w1[3], w2[0], selector);
-      w3[0] = __byte_perm (w1[2], w1[3], selector);
-      w2[3] = __byte_perm (w1[1], w1[2], selector);
-      w2[2] = __byte_perm (w1[0], w1[1], selector);
-      w2[1] = __byte_perm (w0[3], w1[0], selector);
-      w2[0] = __byte_perm (w0[2], w0[3], selector);
-      w1[3] = __byte_perm (w0[1], w0[2], selector);
-      w1[2] = __byte_perm (w0[0], w0[1], selector);
-      w1[1] = __byte_perm (    0, w0[0], selector);
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 6:
-      w3[1] = __byte_perm (w1[2], w1[3], selector);
-      w3[0] = __byte_perm (w1[1], w1[2], selector);
-      w2[3] = __byte_perm (w1[0], w1[1], selector);
-      w2[2] = __byte_perm (w0[3], w1[0], selector);
-      w2[1] = __byte_perm (w0[2], w0[3], selector);
-      w2[0] = __byte_perm (w0[1], w0[2], selector);
-      w1[3] = __byte_perm (w0[0], w0[1], selector);
-      w1[2] = __byte_perm (    0, w0[0], selector);
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 7:
-      w3[1] = __byte_perm (w1[1], w1[2], selector);
-      w3[0] = __byte_perm (w1[0], w1[1], selector);
-      w2[3] = __byte_perm (w0[3], w1[0], selector);
-      w2[2] = __byte_perm (w0[2], w0[3], selector);
-      w2[1] = __byte_perm (w0[1], w0[2], selector);
-      w2[0] = __byte_perm (w0[0], w0[1], selector);
-      w1[3] = __byte_perm (    0, w0[0], selector);
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 8:
-      w3[1] = __byte_perm (w1[0], w1[1], selector);
-      w3[0] = __byte_perm (w0[3], w1[0], selector);
-      w2[3] = __byte_perm (w0[2], w0[3], selector);
-      w2[2] = __byte_perm (w0[1], w0[2], selector);
-      w2[1] = __byte_perm (w0[0], w0[1], selector);
-      w2[0] = __byte_perm (    0, w0[0], selector);
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 9:
-      w3[1] = __byte_perm (w0[3], w1[0], selector);
-      w3[0] = __byte_perm (w0[2], w0[3], selector);
-      w2[3] = __byte_perm (w0[1], w0[2], selector);
-      w2[2] = __byte_perm (w0[0], w0[1], selector);
-      w2[1] = __byte_perm (    0, w0[0], selector);
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 10:
-      w3[1] = __byte_perm (w0[2], w0[3], selector);
-      w3[0] = __byte_perm (w0[1], w0[2], selector);
-      w2[3] = __byte_perm (w0[0], w0[1], selector);
-      w2[2] = __byte_perm (    0, w0[0], selector);
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 11:
-      w3[1] = __byte_perm (w0[1], w0[2], selector);
-      w3[0] = __byte_perm (w0[0], w0[1], selector);
-      w2[3] = __byte_perm (    0, w0[0], selector);
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 12:
-      w3[1] = __byte_perm (w0[0], w0[1], selector);
-      w3[0] = __byte_perm (    0, w0[0], selector);
-      w2[3] = 0;
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-
-    case 13:
-      w3[1] = __byte_perm (    0, w0[0], selector);
-      w3[0] = 0;
-      w2[3] = 0;
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-
-      break;
-  }
-  #endif
-}
-
-static void switch_buffer_by_offset_be (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32 offset)
-{
-  #if defined IS_AMD || defined IS_GENERIC
-  switch (offset / 4)
-  {
-    case 0:
-      w3[2] = amd_bytealign (w3[1],     0, offset);
-      w3[1] = amd_bytealign (w3[0], w3[1], offset);
-      w3[0] = amd_bytealign (w2[3], w3[0], offset);
-      w2[3] = amd_bytealign (w2[2], w2[3], offset);
-      w2[2] = amd_bytealign (w2[1], w2[2], offset);
-      w2[1] = amd_bytealign (w2[0], w2[1], offset);
-      w2[0] = amd_bytealign (w1[3], w2[0], offset);
-      w1[3] = amd_bytealign (w1[2], w1[3], offset);
-      w1[2] = amd_bytealign (w1[1], w1[2], offset);
-      w1[1] = amd_bytealign (w1[0], w1[1], offset);
-      w1[0] = amd_bytealign (w0[3], w1[0], offset);
-      w0[3] = amd_bytealign (w0[2], w0[3], offset);
-      w0[2] = amd_bytealign (w0[1], w0[2], offset);
-      w0[1] = amd_bytealign (w0[0], w0[1], offset);
-      w0[0] = amd_bytealign (    0, w0[0], offset);
-      break;
-
-    case 1:
-      w3[2] = amd_bytealign (w3[0],     0, offset);
-      w3[1] = amd_bytealign (w2[3], w3[0], offset);
-      w3[0] = amd_bytealign (w2[2], w2[3], offset);
-      w2[3] = amd_bytealign (w2[1], w2[2], offset);
-      w2[2] = amd_bytealign (w2[0], w2[1], offset);
-      w2[1] = amd_bytealign (w1[3], w2[0], offset);
-      w2[0] = amd_bytealign (w1[2], w1[3], offset);
-      w1[3] = amd_bytealign (w1[1], w1[2], offset);
-      w1[2] = amd_bytealign (w1[0], w1[1], offset);
-      w1[1] = amd_bytealign (w0[3], w1[0], offset);
-      w1[0] = amd_bytealign (w0[2], w0[3], offset);
-      w0[3] = amd_bytealign (w0[1], w0[2], offset);
-      w0[2] = amd_bytealign (w0[0], w0[1], offset);
-      w0[1] = amd_bytealign (    0, w0[0], offset);
-      w0[0] = 0;
-      break;
-
-    case 2:
-      w3[2] = amd_bytealign (w2[3],     0, offset);
-      w3[1] = amd_bytealign (w2[2], w2[3], offset);
-      w3[0] = amd_bytealign (w2[1], w2[2], offset);
-      w2[3] = amd_bytealign (w2[0], w2[1], offset);
-      w2[2] = amd_bytealign (w1[3], w2[0], offset);
-      w2[1] = amd_bytealign (w1[2], w1[3], offset);
-      w2[0] = amd_bytealign (w1[1], w1[2], offset);
-      w1[3] = amd_bytealign (w1[0], w1[1], offset);
-      w1[2] = amd_bytealign (w0[3], w1[0], offset);
-      w1[1] = amd_bytealign (w0[2], w0[3], offset);
-      w1[0] = amd_bytealign (w0[1], w0[2], offset);
-      w0[3] = amd_bytealign (w0[0], w0[1], offset);
-      w0[2] = amd_bytealign (    0, w0[0], offset);
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 3:
-      w3[2] = amd_bytealign (w2[2],     0, offset);
-      w3[1] = amd_bytealign (w2[1], w2[2], offset);
-      w3[0] = amd_bytealign (w2[0], w2[1], offset);
-      w2[3] = amd_bytealign (w1[3], w2[0], offset);
-      w2[2] = amd_bytealign (w1[2], w1[3], offset);
-      w2[1] = amd_bytealign (w1[1], w1[2], offset);
-      w2[0] = amd_bytealign (w1[0], w1[1], offset);
-      w1[3] = amd_bytealign (w0[3], w1[0], offset);
-      w1[2] = amd_bytealign (w0[2], w0[3], offset);
-      w1[1] = amd_bytealign (w0[1], w0[2], offset);
-      w1[0] = amd_bytealign (w0[0], w0[1], offset);
-      w0[3] = amd_bytealign (    0, w0[0], offset);
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 4:
-      w3[2] = amd_bytealign (w2[1],     0, offset);
-      w3[1] = amd_bytealign (w2[0], w2[1], offset);
-      w3[0] = amd_bytealign (w1[3], w2[0], offset);
-      w2[3] = amd_bytealign (w1[2], w1[3], offset);
-      w2[2] = amd_bytealign (w1[1], w1[2], offset);
-      w2[1] = amd_bytealign (w1[0], w1[1], offset);
-      w2[0] = amd_bytealign (w0[3], w1[0], offset);
-      w1[3] = amd_bytealign (w0[2], w0[3], offset);
-      w1[2] = amd_bytealign (w0[1], w0[2], offset);
-      w1[1] = amd_bytealign (w0[0], w0[1], offset);
-      w1[0] = amd_bytealign (    0, w0[0], offset);
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 5:
-      w3[2] = amd_bytealign (w2[0],     0, offset);
-      w3[1] = amd_bytealign (w1[3], w2[0], offset);
-      w3[0] = amd_bytealign (w1[2], w1[3], offset);
-      w2[3] = amd_bytealign (w1[1], w1[2], offset);
-      w2[2] = amd_bytealign (w1[0], w1[1], offset);
-      w2[1] = amd_bytealign (w0[3], w1[0], offset);
-      w2[0] = amd_bytealign (w0[2], w0[3], offset);
-      w1[3] = amd_bytealign (w0[1], w0[2], offset);
-      w1[2] = amd_bytealign (w0[0], w0[1], offset);
-      w1[1] = amd_bytealign (    0, w0[0], offset);
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 6:
-      w3[2] = amd_bytealign (w1[3],     0, offset);
-      w3[1] = amd_bytealign (w1[2], w1[3], offset);
-      w3[0] = amd_bytealign (w1[1], w1[2], offset);
-      w2[3] = amd_bytealign (w1[0], w1[1], offset);
-      w2[2] = amd_bytealign (w0[3], w1[0], offset);
-      w2[1] = amd_bytealign (w0[2], w0[3], offset);
-      w2[0] = amd_bytealign (w0[1], w0[2], offset);
-      w1[3] = amd_bytealign (w0[0], w0[1], offset);
-      w1[2] = amd_bytealign (    0, w0[0], offset);
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 7:
-      w3[2] = amd_bytealign (w1[2],     0, offset);
-      w3[1] = amd_bytealign (w1[1], w1[2], offset);
-      w3[0] = amd_bytealign (w1[0], w1[1], offset);
-      w2[3] = amd_bytealign (w0[3], w1[0], offset);
-      w2[2] = amd_bytealign (w0[2], w0[3], offset);
-      w2[1] = amd_bytealign (w0[1], w0[2], offset);
-      w2[0] = amd_bytealign (w0[0], w0[1], offset);
-      w1[3] = amd_bytealign (    0, w0[0], offset);
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 8:
-      w3[2] = amd_bytealign (w1[1],     0, offset);
-      w3[1] = amd_bytealign (w1[0], w1[1], offset);
-      w3[0] = amd_bytealign (w0[3], w1[0], offset);
-      w2[3] = amd_bytealign (w0[2], w0[3], offset);
-      w2[2] = amd_bytealign (w0[1], w0[2], offset);
-      w2[1] = amd_bytealign (w0[0], w0[1], offset);
-      w2[0] = amd_bytealign (    0, w0[0], offset);
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 9:
-      w3[2] = amd_bytealign (w1[0],     0, offset);
-      w3[1] = amd_bytealign (w0[3], w1[0], offset);
-      w3[0] = amd_bytealign (w0[2], w0[3], offset);
-      w2[3] = amd_bytealign (w0[1], w0[2], offset);
-      w2[2] = amd_bytealign (w0[0], w0[1], offset);
-      w2[1] = amd_bytealign (    0, w0[0], offset);
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 10:
-      w3[2] = amd_bytealign (w0[3],     0, offset);
-      w3[1] = amd_bytealign (w0[2], w0[3], offset);
-      w3[0] = amd_bytealign (w0[1], w0[2], offset);
-      w2[3] = amd_bytealign (w0[0], w0[1], offset);
-      w2[2] = amd_bytealign (    0, w0[0], offset);
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 11:
-      w3[2] = amd_bytealign (w0[2],     0, offset);
-      w3[1] = amd_bytealign (w0[1], w0[2], offset);
-      w3[0] = amd_bytealign (w0[0], w0[1], offset);
-      w2[3] = amd_bytealign (    0, w0[0], offset);
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 12:
-      w3[2] = amd_bytealign (w0[1],     0, offset);
-      w3[1] = amd_bytealign (w0[0], w0[1], offset);
-      w3[0] = amd_bytealign (    0, w0[0], offset);
-      w2[3] = 0;
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 13:
-      w3[2] = amd_bytealign (w0[0],     0, offset);
-      w3[1] = amd_bytealign (    0, w0[0], offset);
-      w3[0] = 0;
-      w2[3] = 0;
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-  }
-  #endif
-
-  #ifdef IS_NV
-  const int selector = (0x76543210 >> ((offset & 3) * 4)) & 0xffff;
-
-  switch (offset / 4)
-  {
-    case 0:
-      w3[1] = __byte_perm (w3[1], w3[0], selector);
-      w3[0] = __byte_perm (w3[0], w2[3], selector);
-      w2[3] = __byte_perm (w2[3], w2[2], selector);
-      w2[2] = __byte_perm (w2[2], w2[1], selector);
-      w2[1] = __byte_perm (w2[1], w2[0], selector);
-      w2[0] = __byte_perm (w2[0], w1[3], selector);
-      w1[3] = __byte_perm (w1[3], w1[2], selector);
-      w1[2] = __byte_perm (w1[2], w1[1], selector);
-      w1[1] = __byte_perm (w1[1], w1[0], selector);
-      w1[0] = __byte_perm (w1[0], w0[3], selector);
-      w0[3] = __byte_perm (w0[3], w0[2], selector);
-      w0[2] = __byte_perm (w0[2], w0[1], selector);
-      w0[1] = __byte_perm (w0[1], w0[0], selector);
-      w0[0] = __byte_perm (w0[0],     0, selector);
-      break;
-
-    case 1:
-      w3[1] = __byte_perm (w3[0], w2[3], selector);
-      w3[0] = __byte_perm (w2[3], w2[2], selector);
-      w2[3] = __byte_perm (w2[2], w2[1], selector);
-      w2[2] = __byte_perm (w2[1], w2[0], selector);
-      w2[1] = __byte_perm (w2[0], w1[3], selector);
-      w2[0] = __byte_perm (w1[3], w1[2], selector);
-      w1[3] = __byte_perm (w1[2], w1[1], selector);
-      w1[2] = __byte_perm (w1[1], w1[0], selector);
-      w1[1] = __byte_perm (w1[0], w0[3], selector);
-      w1[0] = __byte_perm (w0[3], w0[2], selector);
-      w0[3] = __byte_perm (w0[2], w0[1], selector);
-      w0[2] = __byte_perm (w0[1], w0[0], selector);
-      w0[1] = __byte_perm (w0[0],     0, selector);
-      w0[0] = 0;
-      break;
-
-    case 2:
-      w3[1] = __byte_perm (w2[3], w2[2], selector);
-      w3[0] = __byte_perm (w2[2], w2[1], selector);
-      w2[3] = __byte_perm (w2[1], w2[0], selector);
-      w2[2] = __byte_perm (w2[0], w1[3], selector);
-      w2[1] = __byte_perm (w1[3], w1[2], selector);
-      w2[0] = __byte_perm (w1[2], w1[1], selector);
-      w1[3] = __byte_perm (w1[1], w1[0], selector);
-      w1[2] = __byte_perm (w1[0], w0[3], selector);
-      w1[1] = __byte_perm (w0[3], w0[2], selector);
-      w1[0] = __byte_perm (w0[2], w0[1], selector);
-      w0[3] = __byte_perm (w0[1], w0[0], selector);
-      w0[2] = __byte_perm (w0[0],     0, selector);
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 3:
-      w3[1] = __byte_perm (w2[2], w2[1], selector);
-      w3[0] = __byte_perm (w2[1], w2[0], selector);
-      w2[3] = __byte_perm (w2[0], w1[3], selector);
-      w2[2] = __byte_perm (w1[3], w1[2], selector);
-      w2[1] = __byte_perm (w1[2], w1[1], selector);
-      w2[0] = __byte_perm (w1[1], w1[0], selector);
-      w1[3] = __byte_perm (w1[0], w0[3], selector);
-      w1[2] = __byte_perm (w0[3], w0[2], selector);
-      w1[1] = __byte_perm (w0[2], w0[1], selector);
-      w1[0] = __byte_perm (w0[1], w0[0], selector);
-      w0[3] = __byte_perm (w0[0],     0, selector);
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 4:
-      w3[1] = __byte_perm (w2[1], w2[0], selector);
-      w3[0] = __byte_perm (w2[0], w1[3], selector);
-      w2[3] = __byte_perm (w1[3], w1[2], selector);
-      w2[2] = __byte_perm (w1[2], w1[1], selector);
-      w2[1] = __byte_perm (w1[1], w1[0], selector);
-      w2[0] = __byte_perm (w1[0], w0[3], selector);
-      w1[3] = __byte_perm (w0[3], w0[2], selector);
-      w1[2] = __byte_perm (w0[2], w0[1], selector);
-      w1[1] = __byte_perm (w0[1], w0[0], selector);
-      w1[0] = __byte_perm (w0[0],     0, selector);
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 5:
-      w3[1] = __byte_perm (w2[0], w1[3], selector);
-      w3[0] = __byte_perm (w1[3], w1[2], selector);
-      w2[3] = __byte_perm (w1[2], w1[1], selector);
-      w2[2] = __byte_perm (w1[1], w1[0], selector);
-      w2[1] = __byte_perm (w1[0], w0[3], selector);
-      w2[0] = __byte_perm (w0[3], w0[2], selector);
-      w1[3] = __byte_perm (w0[2], w0[1], selector);
-      w1[2] = __byte_perm (w0[1], w0[0], selector);
-      w1[1] = __byte_perm (w0[0],     0, selector);
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 6:
-      w3[1] = __byte_perm (w1[3], w1[2], selector);
-      w3[0] = __byte_perm (w1[2], w1[1], selector);
-      w2[3] = __byte_perm (w1[1], w1[0], selector);
-      w2[2] = __byte_perm (w1[0], w0[3], selector);
-      w2[1] = __byte_perm (w0[3], w0[2], selector);
-      w2[0] = __byte_perm (w0[2], w0[1], selector);
-      w1[3] = __byte_perm (w0[1], w0[0], selector);
-      w1[2] = __byte_perm (w0[0],     0, selector);
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 7:
-      w3[1] = __byte_perm (w1[2], w1[1], selector);
-      w3[0] = __byte_perm (w1[1], w1[0], selector);
-      w2[3] = __byte_perm (w1[0], w0[3], selector);
-      w2[2] = __byte_perm (w0[3], w0[2], selector);
-      w2[1] = __byte_perm (w0[2], w0[1], selector);
-      w2[0] = __byte_perm (w0[1], w0[0], selector);
-      w1[3] = __byte_perm (w0[0],     0, selector);
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 8:
-      w3[1] = __byte_perm (w1[1], w1[0], selector);
-      w3[0] = __byte_perm (w1[0], w0[3], selector);
-      w2[3] = __byte_perm (w0[3], w0[2], selector);
-      w2[2] = __byte_perm (w0[2], w0[1], selector);
-      w2[1] = __byte_perm (w0[1], w0[0], selector);
-      w2[0] = __byte_perm (w0[0],     0, selector);
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 9:
-      w3[1] = __byte_perm (w1[0], w0[3], selector);
-      w3[0] = __byte_perm (w0[3], w0[2], selector);
-      w2[3] = __byte_perm (w0[2], w0[1], selector);
-      w2[2] = __byte_perm (w0[1], w0[0], selector);
-      w2[1] = __byte_perm (w0[0],     0, selector);
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 10:
-      w3[1] = __byte_perm (w0[3], w0[2], selector);
-      w3[0] = __byte_perm (w0[2], w0[1], selector);
-      w2[3] = __byte_perm (w0[1], w0[0], selector);
-      w2[2] = __byte_perm (w0[0],     0, selector);
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 11:
-      w3[1] = __byte_perm (w0[2], w0[1], selector);
-      w3[0] = __byte_perm (w0[1], w0[0], selector);
-      w2[3] = __byte_perm (w0[0],     0, selector);
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 12:
-      w3[1] = __byte_perm (w0[1], w0[0], selector);
-      w3[0] = __byte_perm (w0[0],     0, selector);
-      w2[3] = 0;
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
-
-    case 13:
-      w3[1] = __byte_perm (w0[0],     0, selector);
-      w3[0] = 0;
-      w2[3] = 0;
-      w2[2] = 0;
-      w2[1] = 0;
-      w2[0] = 0;
-      w1[3] = 0;
-      w1[2] = 0;
-      w1[1] = 0;
-      w1[0] = 0;
-      w0[3] = 0;
-      w0[2] = 0;
-      w0[1] = 0;
-      w0[0] = 0;
-      break;
+    case  0:  w0[0] = wx;
+              break;
+    case  1:  w0[0] = amd_bytealign (wx, w0[0] << 24, 3);
+              w0[1] = amd_bytealign (w0[1] >>  8, wx, 3);
+              break;
+    case  2:  w0[0] = amd_bytealign (wx, w0[0] << 16, 2);
+              w0[1] = amd_bytealign (w0[1] >> 16, wx, 2);
+              break;
+    case  3:  w0[0] = amd_bytealign (wx, w0[0] <<  8, 1);
+              w0[1] = amd_bytealign (w0[1] >> 24, wx, 1);
+              break;
+    case  4:  w0[1] = wx;
+              break;
+    case  5:  w0[1] = amd_bytealign (wx, w0[1] << 24, 3);
+              w0[2] = amd_bytealign (w0[2] >>  8, wx, 3);
+              break;
+    case  6:  w0[1] = amd_bytealign (wx, w0[1] << 16, 2);
+              w0[2] = amd_bytealign (w0[2] >> 16, wx, 2);
+              break;
+    case  7:  w0[1] = amd_bytealign (wx, w0[1] <<  8, 1);
+              w0[2] = amd_bytealign (w0[2] >> 24, wx, 1);
+              break;
+    case  8:  w0[2] = wx;
+              break;
+    case  9:  w0[2] = amd_bytealign (wx, w0[2] << 24, 3);
+              w0[3] = amd_bytealign (w0[3] >>  8, wx, 3);
+              break;
+    case 10:  w0[2] = amd_bytealign (wx, w0[2] << 16, 2);
+              w0[3] = amd_bytealign (w0[3] >> 16, wx, 2);
+              break;
+    case 11:  w0[2] = amd_bytealign (wx, w0[2] <<  8, 1);
+              w0[3] = amd_bytealign (w0[3] >> 24, wx, 1);
+              break;
+    case 12:  w0[3] = wx;
+              break;
+    case 13:  w0[3] = amd_bytealign (wx, w0[3] << 24, 3);
+              w1[0] = amd_bytealign (w1[0] >>  8, wx, 3);
+              break;
+    case 14:  w0[3] = amd_bytealign (wx, w0[3] << 16, 2);
+              w1[0] = amd_bytealign (w1[0] >> 16, wx, 2);
+              break;
+    case 15:  w0[3] = amd_bytealign (wx, w0[3] <<  8, 1);
+              w1[0] = amd_bytealign (w1[0] >> 24, wx, 1);
+              break;
+    case 16:  w1[0] = wx;
+              break;
+    case 17:  w1[0] = amd_bytealign (wx, w1[0] << 24, 3);
+              w1[1] = amd_bytealign (w1[1] >>  8, wx, 3);
+              break;
+    case 18:  w1[0] = amd_bytealign (wx, w1[0] << 16, 2);
+              w1[1] = amd_bytealign (w1[1] >> 16, wx, 2);
+              break;
+    case 19:  w1[0] = amd_bytealign (wx, w1[0] <<  8, 1);
+              w1[1] = amd_bytealign (w1[1] >> 24, wx, 1);
+              break;
+    case 20:  w1[1] = wx;
+              break;
+    case 21:  w1[1] = amd_bytealign (wx, w1[1] << 24, 3);
+              w1[2] = amd_bytealign (w1[2] >>  8, wx, 3);
+              break;
+    case 22:  w1[1] = amd_bytealign (wx, w1[1] << 16, 2);
+              w1[2] = amd_bytealign (w1[2] >> 16, wx, 2);
+              break;
+    case 23:  w1[1] = amd_bytealign (wx, w1[1] <<  8, 1);
+              w1[2] = amd_bytealign (w1[2] >> 24, wx, 1);
+              break;
+    case 24:  w1[2] = wx;
+              break;
+    case 25:  w1[2] = amd_bytealign (wx, w1[2] << 24, 3);
+              w1[3] = amd_bytealign (w1[3] >>  8, wx, 3);
+              break;
+    case 26:  w1[2] = amd_bytealign (wx, w1[2] << 16, 2);
+              w1[3] = amd_bytealign (w1[3] >> 16, wx, 2);
+              break;
+    case 27:  w1[2] = amd_bytealign (wx, w1[2] <<  8, 1);
+              w1[3] = amd_bytealign (w1[3] >> 24, wx, 1);
+              break;
+    case 28:  w1[3] = wx;
+              break;
+    case 29:  w1[3] = amd_bytealign (wx, w1[3] << 24, 3);
+              w2[0] = amd_bytealign (w2[0] >>  8, wx, 3);
+              break;
+    case 30:  w1[3] = amd_bytealign (wx, w1[3] << 16, 2);
+              w2[0] = amd_bytealign (w2[0] >> 16, wx, 2);
+              break;
+    case 31:  w1[3] = amd_bytealign (wx, w1[3] <<  8, 1);
+              w2[0] = amd_bytealign (w2[0] >> 24, wx, 1);
+              break;
+    case 32:  w2[0] = wx;
+              break;
+    case 33:  w2[0] = amd_bytealign (wx, w2[0] << 24, 3);
+              w2[1] = amd_bytealign (w2[1] >>  8, wx, 3);
+              break;
+    case 34:  w2[0] = amd_bytealign (wx, w2[0] << 16, 2);
+              w2[1] = amd_bytealign (w2[1] >> 16, wx, 2);
+              break;
+    case 35:  w2[0] = amd_bytealign (wx, w2[0] <<  8, 1);
+              w2[1] = amd_bytealign (w2[1] >> 24, wx, 1);
+              break;
+    case 36:  w2[1] = wx;
+              break;
+    case 37:  w2[1] = amd_bytealign (wx, w2[1] << 24, 3);
+              w2[2] = amd_bytealign (w2[2] >>  8, wx, 3);
+              break;
+    case 38:  w2[1] = amd_bytealign (wx, w2[1] << 16, 2);
+              w2[2] = amd_bytealign (w2[2] >> 16, wx, 2);
+              break;
+    case 39:  w2[1] = amd_bytealign (wx, w2[1] <<  8, 1);
+              w2[2] = amd_bytealign (w2[2] >> 24, wx, 1);
+              break;
+    case 40:  w2[2] = wx;
+              break;
+    case 41:  w2[2] = amd_bytealign (wx, w2[2] << 24, 3);
+              w2[3] = amd_bytealign (w2[3] >>  8, wx, 3);
+              break;
+    case 42:  w2[2] = amd_bytealign (wx, w2[2] << 16, 2);
+              w2[3] = amd_bytealign (w2[3] >> 16, wx, 2);
+              break;
+    case 43:  w2[2] = amd_bytealign (wx, w2[2] <<  8, 1);
+              w2[3] = amd_bytealign (w2[3] >> 24, wx, 1);
+              break;
+    case 44:  w2[3] = wx;
+              break;
+    case 45:  w2[3] = amd_bytealign (wx, w2[3] << 24, 3);
+              w3[0] = amd_bytealign (w3[0] >>  8, wx, 3);
+              break;
+    case 46:  w2[3] = amd_bytealign (wx, w2[3] << 16, 2);
+              w3[0] = amd_bytealign (w3[0] >> 16, wx, 2);
+              break;
+    case 47:  w2[3] = amd_bytealign (wx, w2[3] <<  8, 1);
+              w3[0] = amd_bytealign (w3[0] >> 24, wx, 1);
+              break;
+    case 48:  w3[0] = wx;
+              break;
+    case 49:  w3[0] = amd_bytealign (wx, w3[0] << 24, 3);
+              w3[1] = amd_bytealign (w3[1] >>  8, wx, 3);
+              break;
+    case 50:  w3[0] = amd_bytealign (wx, w3[0] << 16, 2);
+              w3[1] = amd_bytealign (w3[1] >> 16, wx, 2);
+              break;
+    case 51:  w3[0] = amd_bytealign (wx, w3[0] <<  8, 1);
+              w3[1] = amd_bytealign (w3[1] >> 24, wx, 1);
+              break;
+    case 52:  w3[1] = wx;
+              break;
+    case 53:  w3[1] = amd_bytealign (wx, w3[1] << 24, 3);
+              w3[2] = amd_bytealign (w3[2] >>  8, wx, 3);
+              break;
+    case 54:  w3[1] = amd_bytealign (wx, w3[1] << 16, 2);
+              w3[2] = amd_bytealign (w3[2] >> 16, wx, 2);
+              break;
+    case 55:  w3[1] = amd_bytealign (wx, w3[1] <<  8, 1);
+              w3[2] = amd_bytealign (w3[2] >> 24, wx, 1);
+              break;
+    case 56:  w3[2] = wx;
+              break;
+    case 57:  w3[2] = amd_bytealign (wx, w3[2] << 24, 3);
+              w3[3] = amd_bytealign (w3[3] >>  8, wx, 3);
+              break;
+    case 58:  w3[2] = amd_bytealign (wx, w3[2] << 16, 2);
+              w3[3] = amd_bytealign (w3[3] >> 16, wx, 2);
+              break;
+    case 59:  w3[2] = amd_bytealign (wx, w3[2] <<  8, 1);
+              w3[3] = amd_bytealign (w3[3] >> 24, wx, 1);
+              break;
+    case 60:  w3[3] = wx;
+              break;
+    case 61:  w3[3] = amd_bytealign (wx, w3[3] << 24, 3);
+              //w4[0] = amd_bytealign (w4[0] >>  8, wx, 3);
+              break;
+    case 62:  w3[3] = amd_bytealign (wx, w3[3] << 16, 2);
+              //w4[0] = amd_bytealign (w4[0] >> 16, wx, 2);
+              break;
+    case 63:  w3[3] = amd_bytealign (wx, w3[3] <<  8, 1);
+              //w4[0] = amd_bytealign (w4[0] >> 24, wx, 1);
+              break;
+  }
+  #else
+  switch (salt_len)
+  {
+    case  0:  w0[0] =  wx;
+              break;
+    case  1:  w0[0] = (w0[0] & 0x000000ff) | (wx <<  8);
+              w0[1] = (w0[1] & 0xffffff00) | (wx >> 24);
+              break;
+    case  2:  w0[0] = (w0[0] & 0x0000ffff) | (wx << 16);
+              w0[1] = (w0[1] & 0xffff0000) | (wx >> 16);
+              break;
+    case  3:  w0[0] = (w0[0] & 0x00ffffff) | (wx << 24);
+              w0[1] = (w0[1] & 0xff000000) | (wx >>  8);
+              break;
+    case  4:  w0[1] =  wx;
+              break;
+    case  5:  w0[1] = (w0[1] & 0x000000ff) | (wx <<  8);
+              w0[2] = (w0[2] & 0xffffff00) | (wx >> 24);
+              break;
+    case  6:  w0[1] = (w0[1] & 0x0000ffff) | (wx << 16);
+              w0[2] = (w0[2] & 0xffff0000) | (wx >> 16);
+              break;
+    case  7:  w0[1] = (w0[1] & 0x00ffffff) | (wx << 24);
+              w0[2] = (w0[2] & 0xff000000) | (wx >>  8);
+              break;
+    case  8:  w0[2] =  wx;
+              break;
+    case  9:  w0[2] = (w0[2] & 0x000000ff) | (wx <<  8);
+              w0[3] = (w0[3] & 0xffffff00) | (wx >> 24);
+              break;
+    case 10:  w0[2] = (w0[2] & 0x0000ffff) | (wx << 16);
+              w0[3] = (w0[3] & 0xffff0000) | (wx >> 16);
+              break;
+    case 11:  w0[2] = (w0[2] & 0x00ffffff) | (wx << 24);
+              w0[3] = (w0[3] & 0xff000000) | (wx >>  8);
+              break;
+    case 12:  w0[3] =  wx;
+              break;
+    case 13:  w0[3] = (w0[3] & 0x000000ff) | (wx <<  8);
+              w1[0] = (w1[0] & 0xffffff00) | (wx >> 24);
+              break;
+    case 14:  w0[3] = (w0[3] & 0x0000ffff) | (wx << 16);
+              w1[0] = (w1[0] & 0xffff0000) | (wx >> 16);
+              break;
+    case 15:  w0[3] = (w0[3] & 0x00ffffff) | (wx << 24);
+              w1[0] = (w1[0] & 0xff000000) | (wx >>  8);
+              break;
+    case 16:  w1[0] =  wx;
+              break;
+    case 17:  w1[0] = (w1[0] & 0x000000ff) | (wx <<  8);
+              w1[1] = (w1[1] & 0xffffff00) | (wx >> 24);
+              break;
+    case 18:  w1[0] = (w1[0] & 0x0000ffff) | (wx << 16);
+              w1[1] = (w1[1] & 0xffff0000) | (wx >> 16);
+              break;
+    case 19:  w1[0] = (w1[0] & 0x00ffffff) | (wx << 24);
+              w1[1] = (w1[1] & 0xff000000) | (wx >>  8);
+              break;
+    case 20:  w1[1] =  wx;
+              break;
+    case 21:  w1[1] = (w1[1] & 0x000000ff) | (wx <<  8);
+              w1[2] = (w1[2] & 0xffffff00) | (wx >> 24);
+              break;
+    case 22:  w1[1] = (w1[1] & 0x0000ffff) | (wx << 16);
+              w1[2] = (w1[2] & 0xffff0000) | (wx >> 16);
+              break;
+    case 23:  w1[1] = (w1[1] & 0x00ffffff) | (wx << 24);
+              w1[2] = (w1[2] & 0xff000000) | (wx >>  8);
+              break;
+    case 24:  w1[2] =  wx;
+              break;
+    case 25:  w1[2] = (w1[2] & 0x000000ff) | (wx <<  8);
+              w1[3] = (w1[3] & 0xffffff00) | (wx >> 24);
+              break;
+    case 26:  w1[2] = (w1[2] & 0x0000ffff) | (wx << 16);
+              w1[3] = (w1[3] & 0xffff0000) | (wx >> 16);
+              break;
+    case 27:  w1[2] = (w1[2] & 0x00ffffff) | (wx << 24);
+              w1[3] = (w1[3] & 0xff000000) | (wx >>  8);
+              break;
+    case 28:  w1[3] =  wx;
+              break;
+    case 29:  w1[3] = (w1[3] & 0x000000ff) | (wx <<  8);
+              w2[0] = (w2[0] & 0xffffff00) | (wx >> 24);
+              break;
+    case 30:  w1[3] = (w1[3] & 0x0000ffff) | (wx << 16);
+              w2[0] = (w2[0] & 0xffff0000) | (wx >> 16);
+              break;
+    case 31:  w1[3] = (w1[3] & 0x00ffffff) | (wx << 24);
+              w2[0] = (w2[0] & 0xff000000) | (wx >>  8);
+              break;
+    case 32:  w2[0] =  wx;
+              break;
+    case 33:  w2[0] = (w2[0] & 0x000000ff) | (wx <<  8);
+              w2[1] = (w2[1] & 0xffffff00) | (wx >> 24);
+              break;
+    case 34:  w2[0] = (w2[0] & 0x0000ffff) | (wx << 16);
+              w2[1] = (w2[1] & 0xffff0000) | (wx >> 16);
+              break;
+    case 35:  w2[0] = (w2[0] & 0x00ffffff) | (wx << 24);
+              w2[1] = (w2[1] & 0xff000000) | (wx >>  8);
+              break;
+    case 36:  w2[1] =  wx;
+              break;
+    case 37:  w2[1] = (w2[1] & 0x000000ff) | (wx <<  8);
+              w2[2] = (w2[2] & 0xffffff00) | (wx >> 24);
+              break;
+    case 38:  w2[1] = (w2[1] & 0x0000ffff) | (wx << 16);
+              w2[2] = (w2[2] & 0xffff0000) | (wx >> 16);
+              break;
+    case 39:  w2[1] = (w2[1] & 0x00ffffff) | (wx << 24);
+              w2[2] = (w2[2] & 0xff000000) | (wx >>  8);
+              break;
+    case 40:  w2[2] =  wx;
+              break;
+    case 41:  w2[2] = (w2[2] & 0x000000ff) | (wx <<  8);
+              w2[3] = (w2[3] & 0xffffff00) | (wx >> 24);
+              break;
+    case 42:  w2[2] = (w2[2] & 0x0000ffff) | (wx << 16);
+              w2[3] = (w2[3] & 0xffff0000) | (wx >> 16);
+              break;
+    case 43:  w2[2] = (w2[2] & 0x00ffffff) | (wx << 24);
+              w2[3] = (w2[3] & 0xff000000) | (wx >>  8);
+              break;
+    case 44:  w2[3] =  wx;
+              break;
+    case 45:  w2[3] = (w2[3] & 0x000000ff) | (wx <<  8);
+              w3[0] = (w3[0] & 0xffffff00) | (wx >> 24);
+              break;
+    case 46:  w2[3] = (w2[3] & 0x0000ffff) | (wx << 16);
+              w3[0] = (w3[0] & 0xffff0000) | (wx >> 16);
+              break;
+    case 47:  w2[3] = (w2[3] & 0x00ffffff) | (wx << 24);
+              w3[0] = (w3[0] & 0xff000000) | (wx >>  8);
+              break;
+    case 48:  w3[0] =  wx;
+              break;
+    case 49:  w3[0] = (w3[0] & 0x000000ff) | (wx <<  8);
+              w3[1] = (w3[1] & 0xffffff00) | (wx >> 24);
+              break;
+    case 50:  w3[0] = (w3[0] & 0x0000ffff) | (wx << 16);
+              w3[1] = (w3[1] & 0xffff0000) | (wx >> 16);
+              break;
+    case 51:  w3[0] = (w3[0] & 0x00ffffff) | (wx << 24);
+              w3[1] = (w3[1] & 0xff000000) | (wx >>  8);
+              break;
+    case 52:  w3[1] =  wx;
+              break;
+    case 53:  w3[1] = (w3[1] & 0x000000ff) | (wx <<  8);
+              w3[2] = (w3[2] & 0xffffff00) | (wx >> 24);
+              break;
+    case 54:  w3[1] = (w3[1] & 0x0000ffff) | (wx << 16);
+              w3[2] = (w3[2] & 0xffff0000) | (wx >> 16);
+              break;
+    case 55:  w3[1] = (w3[1] & 0x00ffffff) | (wx << 24);
+              w3[2] = (w3[2] & 0xff000000) | (wx >>  8);
+              break;
+    case 56:  w3[2] =  wx;
+              break;
+    case 57:  w3[2] = (w3[2] & 0x000000ff) | (wx <<  8);
+              w3[3] = (w3[3] & 0xffffff00) | (wx >> 24);
+              break;
+    case 58:  w3[2] = (w3[2] & 0x0000ffff) | (wx << 16);
+              w3[3] = (w3[3] & 0xffff0000) | (wx >> 16);
+              break;
+    case 59:  w3[2] = (w3[2] & 0x00ffffff) | (wx << 24);
+              w3[3] = (w3[3] & 0xff000000) | (wx >>  8);
+              break;
+    case 60:  w3[3] =  wx;
+              break;
+    case 61:  w3[3] = (w3[3] & 0x000000ff) | (wx <<  8);
+              //w4[0] = (w4[0] & 0xffffff00) | (wx >> 24);
+              break;
+    case 62:  w3[3] = (w3[3] & 0x0000ffff) | (wx << 16);
+              //w4[0] = (w4[0] & 0xffff0000) | (wx >> 16);
+              break;
+    case 63:  w3[3] = (w3[3] & 0x00ffffff) | (wx << 24);
+              //w4[0] = (w4[0] & 0xff000000) | (wx >>  8);
+              break;
   }
   #endif
 }
 
-/* not needed anymore?
-
-// before: append_0x80_2_be
-static void append_0x80_2x4_be (u32 w0[4], u32 w1[4], const u32 offset)
+inline void overwrite_at_be_4x4 (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32x wx, const u32 salt_len)
 {
-  switch (offset)
-  {
-    case  0:
-      w0[0] |= 0x80000000;
-      break;
-
-    case  1:
-      w0[0] |= 0x800000;
-      break;
-
-    case  2:
-      w0[0] |= 0x8000;
-      break;
-
-    case  3:
-      w0[0] |= 0x80;
-      break;
-
-    case  4:
-      w0[1] |= 0x80000000;
-      break;
-
-    case  5:
-      w0[1] |= 0x800000;
-      break;
-
-    case  6:
-      w0[1] |= 0x8000;
-      break;
-
-    case  7:
-      w0[1] |= 0x80;
-      break;
+  // would be nice to have optimization based on amd_bytealign as with _le counterpart
 
-    case  8:
-      w0[2] |= 0x80000000;
-      break;
-
-    case  9:
-      w0[2] |= 0x800000;
-      break;
-
-    case 10:
-      w0[2] |= 0x8000;
-      break;
-
-    case 11:
-      w0[2] |= 0x80;
-      break;
-
-    case 12:
-      w0[3] |= 0x80000000;
-      break;
-
-    case 13:
-      w0[3] |= 0x800000;
-      break;
-
-    case 14:
-      w0[3] |= 0x8000;
-      break;
-
-    case 15:
-      w0[3] |= 0x80;
-      break;
-
-    case 16:
-      w1[0] |= 0x80000000;
-      break;
-
-    case 17:
-      w1[0] |= 0x800000;
-      break;
-
-    case 18:
-      w1[0] |= 0x8000;
-      break;
-
-    case 19:
-      w1[0] |= 0x80;
-      break;
-
-    case 20:
-      w1[1] |= 0x80000000;
-      break;
-
-    case 21:
-      w1[1] |= 0x800000;
-      break;
-
-    case 22:
-      w1[1] |= 0x8000;
-      break;
-
-    case 23:
-      w1[1] |= 0x80;
-      break;
-
-    case 24:
-      w1[2] |= 0x80000000;
-      break;
-
-    case 25:
-      w1[2] |= 0x800000;
-      break;
-
-    case 26:
-      w1[2] |= 0x8000;
-      break;
-
-    case 27:
-      w1[2] |= 0x80;
-      break;
-
-    case 28:
-      w1[3] |= 0x80000000;
-      break;
-
-    case 29:
-      w1[3] |= 0x800000;
-      break;
-
-    case 30:
-      w1[3] |= 0x8000;
-      break;
-
-    case 31:
-      w1[3] |= 0x80;
-      break;
+  switch (salt_len)
+  {
+    case  0:  w0[0] =  wx;
+              break;
+    case  1:  w0[0] = (w0[0] & 0xff000000) | (wx >>  8);
+              w0[1] = (w0[1] & 0x00ffffff) | (wx << 24);
+              break;
+    case  2:  w0[0] = (w0[0] & 0xffff0000) | (wx >> 16);
+              w0[1] = (w0[1] & 0x0000ffff) | (wx << 16);
+              break;
+    case  3:  w0[0] = (w0[0] & 0xffffff00) | (wx >> 24);
+              w0[1] = (w0[1] & 0x000000ff) | (wx <<  8);
+              break;
+    case  4:  w0[1] =  wx;
+              break;
+    case  5:  w0[1] = (w0[1] & 0xff000000) | (wx >>  8);
+              w0[2] = (w0[2] & 0x00ffffff) | (wx << 24);
+              break;
+    case  6:  w0[1] = (w0[1] & 0xffff0000) | (wx >> 16);
+              w0[2] = (w0[2] & 0x0000ffff) | (wx << 16);
+              break;
+    case  7:  w0[1] = (w0[1] & 0xffffff00) | (wx >> 24);
+              w0[2] = (w0[2] & 0x000000ff) | (wx <<  8);
+              break;
+    case  8:  w0[2] =  wx;
+              break;
+    case  9:  w0[2] = (w0[2] & 0xff000000) | (wx >>  8);
+              w0[3] = (w0[3] & 0x00ffffff) | (wx << 24);
+              break;
+    case 10:  w0[2] = (w0[2] & 0xffff0000) | (wx >> 16);
+              w0[3] = (w0[3] & 0x0000ffff) | (wx << 16);
+              break;
+    case 11:  w0[2] = (w0[2] & 0xffffff00) | (wx >> 24);
+              w0[3] = (w0[3] & 0x000000ff) | (wx <<  8);
+              break;
+    case 12:  w0[3] =  wx;
+              break;
+    case 13:  w0[3] = (w0[3] & 0xff000000) | (wx >>  8);
+              w1[0] = (w1[0] & 0x00ffffff) | (wx << 24);
+              break;
+    case 14:  w0[3] = (w0[3] & 0xffff0000) | (wx >> 16);
+              w1[0] = (w1[0] & 0x0000ffff) | (wx << 16);
+              break;
+    case 15:  w0[3] = (w0[3] & 0xffffff00) | (wx >> 24);
+              w1[0] = (w1[0] & 0x000000ff) | (wx <<  8);
+              break;
+    case 16:  w1[0] =  wx;
+              break;
+    case 17:  w1[0] = (w1[0] & 0xff000000) | (wx >>  8);
+              w1[1] = (w1[1] & 0x00ffffff) | (wx << 24);
+              break;
+    case 18:  w1[0] = (w1[0] & 0xffff0000) | (wx >> 16);
+              w1[1] = (w1[1] & 0x0000ffff) | (wx << 16);
+              break;
+    case 19:  w1[0] = (w1[0] & 0xffffff00) | (wx >> 24);
+              w1[1] = (w1[1] & 0x000000ff) | (wx <<  8);
+              break;
+    case 20:  w1[1] =  wx;
+              break;
+    case 21:  w1[1] = (w1[1] & 0xff000000) | (wx >>  8);
+              w1[2] = (w1[2] & 0x00ffffff) | (wx << 24);
+              break;
+    case 22:  w1[1] = (w1[1] & 0xffff0000) | (wx >> 16);
+              w1[2] = (w1[2] & 0x0000ffff) | (wx << 16);
+              break;
+    case 23:  w1[1] = (w1[1] & 0xffffff00) | (wx >> 24);
+              w1[2] = (w1[2] & 0x000000ff) | (wx <<  8);
+              break;
+    case 24:  w1[2] =  wx;
+              break;
+    case 25:  w1[2] = (w1[2] & 0xff000000) | (wx >>  8);
+              w1[3] = (w1[3] & 0x00ffffff) | (wx << 24);
+              break;
+    case 26:  w1[2] = (w1[2] & 0xffff0000) | (wx >> 16);
+              w1[3] = (w1[3] & 0x0000ffff) | (wx << 16);
+              break;
+    case 27:  w1[2] = (w1[2] & 0xffffff00) | (wx >> 24);
+              w1[3] = (w1[3] & 0x000000ff) | (wx <<  8);
+              break;
+    case 28:  w1[3] =  wx;
+              break;
+    case 29:  w1[3] = (w1[3] & 0xff000000) | (wx >>  8);
+              w2[0] = (w2[0] & 0x00ffffff) | (wx << 24);
+              break;
+    case 30:  w1[3] = (w1[3] & 0xffff0000) | (wx >> 16);
+              w2[0] = (w2[0] & 0x0000ffff) | (wx << 16);
+              break;
+    case 31:  w1[3] = (w1[3] & 0xffffff00) | (wx >> 24);
+              w2[0] = (w2[0] & 0x000000ff) | (wx <<  8);
+              break;
+    case 32:  w2[0] =  wx;
+              break;
+    case 33:  w2[0] = (w2[0] & 0xff000000) | (wx >>  8);
+              w2[1] = (w2[1] & 0x00ffffff) | (wx << 24);
+              break;
+    case 34:  w2[0] = (w2[0] & 0xffff0000) | (wx >> 16);
+              w2[1] = (w2[1] & 0x0000ffff) | (wx << 16);
+              break;
+    case 35:  w2[0] = (w2[0] & 0xffffff00) | (wx >> 24);
+              w2[1] = (w2[1] & 0x000000ff) | (wx <<  8);
+              break;
+    case 36:  w2[1] =  wx;
+              break;
+    case 37:  w2[1] = (w2[1] & 0xff000000) | (wx >>  8);
+              w2[2] = (w2[2] & 0x00ffffff) | (wx << 24);
+              break;
+    case 38:  w2[1] = (w2[1] & 0xffff0000) | (wx >> 16);
+              w2[2] = (w2[2] & 0x0000ffff) | (wx << 16);
+              break;
+    case 39:  w2[1] = (w2[1] & 0xffffff00) | (wx >> 24);
+              w2[2] = (w2[2] & 0x000000ff) | (wx <<  8);
+              break;
+    case 40:  w2[2] =  wx;
+              break;
+    case 41:  w2[2] = (w2[2] & 0xff000000) | (wx >>  8);
+              w2[3] = (w2[3] & 0x00ffffff) | (wx << 24);
+              break;
+    case 42:  w2[2] = (w2[2] & 0xffff0000) | (wx >> 16);
+              w2[3] = (w2[3] & 0x0000ffff) | (wx << 16);
+              break;
+    case 43:  w2[2] = (w2[2] & 0xffffff00) | (wx >> 24);
+              w2[3] = (w2[3] & 0x000000ff) | (wx <<  8);
+              break;
+    case 44:  w2[3] =  wx;
+              break;
+    case 45:  w2[3] = (w2[3] & 0xff000000) | (wx >>  8);
+              w3[0] = (w3[0] & 0x00ffffff) | (wx << 24);
+              break;
+    case 46:  w2[3] = (w2[3] & 0xffff0000) | (wx >> 16);
+              w3[0] = (w3[0] & 0x0000ffff) | (wx << 16);
+              break;
+    case 47:  w2[3] = (w2[3] & 0xffffff00) | (wx >> 24);
+              w3[0] = (w3[0] & 0x000000ff) | (wx <<  8);
+              break;
+    case 48:  w3[0] =  wx;
+              break;
+    case 49:  w3[0] = (w3[0] & 0xff000000) | (wx >>  8);
+              w3[1] = (w3[1] & 0x00ffffff) | (wx << 24);
+              break;
+    case 50:  w3[0] = (w3[0] & 0xffff0000) | (wx >> 16);
+              w3[1] = (w3[1] & 0x0000ffff) | (wx << 16);
+              break;
+    case 51:  w3[0] = (w3[0] & 0xffffff00) | (wx >> 24);
+              w3[1] = (w3[1] & 0x000000ff) | (wx <<  8);
+              break;
+    case 52:  w3[1] =  wx;
+              break;
+    case 53:  w3[1] = (w3[1] & 0xff000000) | (wx >>  8);
+              w3[2] = (w3[2] & 0x00ffffff) | (wx << 24);
+              break;
+    case 54:  w3[1] = (w3[1] & 0xffff0000) | (wx >> 16);
+              w3[2] = (w3[2] & 0x0000ffff) | (wx << 16);
+              break;
+    case 55:  w3[1] = (w3[1] & 0xffffff00) | (wx >> 24);
+              w3[2] = (w3[2] & 0x000000ff) | (wx <<  8);
+              break;
+    case 56:  w3[2] =  wx;
+              break;
+    case 57:  w3[2] = (w3[2] & 0xff000000) | (wx >>  8);
+              w3[3] = (w3[3] & 0x00ffffff) | (wx << 24);
+              break;
+    case 58:  w3[2] = (w3[2] & 0xffff0000) | (wx >> 16);
+              w3[3] = (w3[3] & 0x0000ffff) | (wx << 16);
+              break;
+    case 59:  w3[2] = (w3[2] & 0xffffff00) | (wx >> 24);
+              w3[3] = (w3[3] & 0x000000ff) | (wx <<  8);
+              break;
+    case 60:  w3[3] =  wx;
+              break;
+    case 61:  w3[3] = (w3[3] & 0xff000000) | (wx >>  8);
+              //w4[0] = (w4[0] & 0x00ffffff) | (wx << 24);
+              break;
+    case 62:  w3[3] = (w3[3] & 0xffff0000) | (wx >> 16);
+              //w4[0] = (w4[0] & 0x0000ffff) | (wx << 16);
+              break;
+    case 63:  w3[3] = (w3[3] & 0xffffff00) | (wx >> 24);
+              //w4[0] = (w4[0] & 0x000000ff) | (wx <<  8);
+              break;
   }
 }
 
-// before: append_0x80_8
-static void append_0x80_1x32 (u32 w[32], const u32 offset)
+/**
+ * vector functions as scalar (for outer loop usage)
+ */
+
+inline void append_0x01_2x4_S (u32x w0[4], u32x w1[4], const u32 offset)
 {
   switch (offset)
   {
     case 0:
-      w[ 0] = 0x80;
+      w0[0] = 0x01;
       break;
 
     case 1:
-      w[ 0] = w[ 0] | 0x8000;
+      w0[0] = w0[0] | 0x0100;
       break;
 
     case 2:
-      w[ 0] = w[ 0] | 0x800000;
+      w0[0] = w0[0] | 0x010000;
       break;
 
     case 3:
-      w[ 0] = w[ 0] | 0x80000000;
+      w0[0] = w0[0] | 0x01000000;
       break;
 
     case 4:
-      w[ 1] = 0x80;
+      w0[1] = 0x01;
       break;
 
     case 5:
-      w[ 1] = w[ 1] | 0x8000;
+      w0[1] = w0[1] | 0x0100;
       break;
 
     case 6:
-      w[ 1] = w[ 1] | 0x800000;
+      w0[1] = w0[1] | 0x010000;
       break;
 
     case 7:
-      w[ 1] = w[ 1] | 0x80000000;
+      w0[1] = w0[1] | 0x01000000;
       break;
 
     case 8:
-      w[ 2] = 0x80;
+      w0[2] = 0x01;
       break;
 
     case 9:
-      w[ 2] = w[ 2] | 0x8000;
+      w0[2] = w0[2] | 0x0100;
       break;
 
     case 10:
-      w[ 2] = w[ 2] | 0x800000;
+      w0[2] = w0[2] | 0x010000;
       break;
 
     case 11:
-      w[ 2] = w[ 2] | 0x80000000;
+      w0[2] = w0[2] | 0x01000000;
       break;
 
     case 12:
-      w[ 3] = 0x80;
+      w0[3] = 0x01;
       break;
 
     case 13:
-      w[ 3] = w[ 3] | 0x8000;
+      w0[3] = w0[3] | 0x0100;
       break;
 
     case 14:
-      w[ 3] = w[ 3] | 0x800000;
+      w0[3] = w0[3] | 0x010000;
       break;
 
     case 15:
-      w[ 3] = w[ 3] | 0x80000000;
+      w0[3] = w0[3] | 0x01000000;
       break;
 
     case 16:
-      w[ 4] = 0x80;
-      break;
-
-    case 17:
-      w[ 4] = w[ 4] | 0x8000;
-      break;
-
-    case 18:
-      w[ 4] = w[ 4] | 0x800000;
-      break;
-
-    case 19:
-      w[ 4] = w[ 4] | 0x80000000;
-      break;
-
-    case 20:
-      w[ 5] = 0x80;
-      break;
-
-    case 21:
-      w[ 5] = w[ 5] | 0x8000;
-      break;
-
-    case 22:
-      w[ 5] = w[ 5] | 0x800000;
-      break;
-
-    case 23:
-      w[ 5] = w[ 5] | 0x80000000;
-      break;
-
-    case 24:
-      w[ 6] = 0x80;
-      break;
-
-    case 25:
-      w[ 6] = w[ 6] | 0x8000;
-      break;
-
-    case 26:
-      w[ 6] = w[ 6] | 0x800000;
-      break;
-
-    case 27:
-      w[ 6] = w[ 6] | 0x80000000;
-      break;
-
-    case 28:
-      w[ 7] = 0x80;
-      break;
-
-    case 29:
-      w[ 7] = w[ 7] | 0x8000;
-      break;
-
-    case 30:
-      w[ 7] = w[ 7] | 0x800000;
-      break;
-
-    case 31:
-      w[ 7] = w[ 7] | 0x80000000;
-      break;
-
-    case 32:
-      w[ 8] = 0x80;
-      break;
-
-    case 33:
-      w[ 8] = w[ 8] | 0x8000;
-      break;
-
-    case 34:
-      w[ 8] = w[ 8] | 0x800000;
-      break;
-
-    case 35:
-      w[ 8] = w[ 8] | 0x80000000;
-      break;
-
-    case 36:
-      w[ 9] = 0x80;
-      break;
-
-    case 37:
-      w[ 9] = w[ 9] | 0x8000;
-      break;
-
-    case 38:
-      w[ 9] = w[ 9] | 0x800000;
-      break;
-
-    case 39:
-      w[ 9] = w[ 9] | 0x80000000;
-      break;
-
-    case 40:
-      w[10] = 0x80;
-      break;
-
-    case 41:
-      w[10] = w[10] | 0x8000;
-      break;
-
-    case 42:
-      w[10] = w[10] | 0x800000;
-      break;
-
-    case 43:
-      w[10] = w[10] | 0x80000000;
-      break;
-
-    case 44:
-      w[11] = 0x80;
-      break;
-
-    case 45:
-      w[11] = w[11] | 0x8000;
-      break;
-
-    case 46:
-      w[11] = w[11] | 0x800000;
-      break;
-
-    case 47:
-      w[11] = w[11] | 0x80000000;
-      break;
-
-    case 48:
-      w[12] = 0x80;
-      break;
-
-    case 49:
-      w[12] = w[12] | 0x8000;
-      break;
-
-    case 50:
-      w[12] = w[12] | 0x800000;
-      break;
-
-    case 51:
-      w[12] = w[12] | 0x80000000;
-      break;
-
-    case 52:
-      w[13] = 0x80;
-      break;
-
-    case 53:
-      w[13] = w[13] | 0x8000;
-      break;
-
-    case 54:
-      w[13] = w[13] | 0x800000;
-      break;
-
-    case 55:
-      w[13] = w[13] | 0x80000000;
-      break;
-
-    case 56:
-      w[14] = 0x80;
-      break;
-
-    case 57:
-      w[14] = w[14] | 0x8000;
-      break;
-
-    case 58:
-      w[14] = w[14] | 0x800000;
-      break;
-
-    case 59:
-      w[14] = w[14] | 0x80000000;
-      break;
-
-    case 60:
-      w[15] = 0x80;
-      break;
-
-    case 61:
-      w[15] = w[15] | 0x8000;
-      break;
-
-    case 62:
-      w[15] = w[15] | 0x800000;
-      break;
-
-    case 63:
-      w[15] = w[15] | 0x80000000;
-      break;
-
-    case 64:
-      w[16] = 0x80;
-      break;
-
-    case 65:
-      w[16] = w[16] | 0x8000;
-      break;
-
-    case 66:
-      w[16] = w[16] | 0x800000;
-      break;
-
-    case 67:
-      w[16] = w[16] | 0x80000000;
-      break;
-
-    case 68:
-      w[17] = 0x80;
-      break;
-
-    case 69:
-      w[17] = w[17] | 0x8000;
-      break;
-
-    case 70:
-      w[17] = w[17] | 0x800000;
-      break;
-
-    case 71:
-      w[17] = w[17] | 0x80000000;
+      w1[0] = 0x01;
       break;
 
-    case 72:
-      w[18] = 0x80;
+    case 17:
+      w1[0] = w1[0] | 0x0100;
       break;
 
-    case 73:
-      w[18] = w[18] | 0x8000;
+    case 18:
+      w1[0] = w1[0] | 0x010000;
       break;
 
-    case 74:
-      w[18] = w[18] | 0x800000;
+    case 19:
+      w1[0] = w1[0] | 0x01000000;
       break;
 
-    case 75:
-      w[18] = w[18] | 0x80000000;
+    case 20:
+      w1[1] = 0x01;
       break;
 
-    case 76:
-      w[19] = 0x80;
+    case 21:
+      w1[1] = w1[1] | 0x0100;
       break;
 
-    case 77:
-      w[19] = w[19] | 0x8000;
+    case 22:
+      w1[1] = w1[1] | 0x010000;
       break;
 
-    case 78:
-      w[19] = w[19] | 0x800000;
+    case 23:
+      w1[1] = w1[1] | 0x01000000;
       break;
 
-    case 79:
-      w[19] = w[19] | 0x80000000;
+    case 24:
+      w1[2] = 0x01;
       break;
 
-    case 80:
-      w[20] = 0x80;
+    case 25:
+      w1[2] = w1[2] | 0x0100;
       break;
 
-    case 81:
-      w[20] = w[20] | 0x8000;
+    case 26:
+      w1[2] = w1[2] | 0x010000;
       break;
 
-    case 82:
-      w[20] = w[20] | 0x800000;
+    case 27:
+      w1[2] = w1[2] | 0x01000000;
       break;
 
-    case 83:
-      w[20] = w[20] | 0x80000000;
+    case 28:
+      w1[3] = 0x01;
       break;
 
-    case 84:
-      w[21] = 0x80;
+    case 29:
+      w1[3] = w1[3] | 0x0100;
       break;
 
-    case 85:
-      w[21] = w[21] | 0x8000;
+    case 30:
+      w1[3] = w1[3] | 0x010000;
       break;
 
-    case 86:
-      w[21] = w[21] | 0x800000;
+    case 31:
+      w1[3] = w1[3] | 0x01000000;
       break;
+  }
+}
 
-    case 87:
-      w[21] = w[21] | 0x80000000;
+inline void append_0x80_1x4_S (u32 w0[4], const u32 offset)
+{
+  switch (offset)
+  {
+    case 0:
+      w0[0]  = 0x80;
       break;
 
-    case 88:
-      w[22] = 0x80;
+    case 1:
+      w0[0] = w0[0] | 0x8000;
       break;
 
-    case 89:
-      w[22] = w[22] | 0x8000;
+    case 2:
+      w0[0] = w0[0] | 0x800000;
       break;
 
-    case 90:
-      w[22] = w[22] | 0x800000;
+    case 3:
+      w0[0] = w0[0] | 0x80000000;
       break;
 
-    case 91:
-      w[22] = w[22] | 0x80000000;
+    case 4:
+      w0[1] = 0x80;
       break;
 
-    case 92:
-      w[23] = 0x80;
+    case 5:
+      w0[1] = w0[1] | 0x8000;
       break;
 
-    case 93:
-      w[23] = w[23] | 0x8000;
+    case 6:
+      w0[1] = w0[1] | 0x800000;
       break;
 
-    case 94:
-      w[23] = w[23] | 0x800000;
+    case 7:
+      w0[1] = w0[1] | 0x80000000;
       break;
 
-    case 95:
-      w[23] = w[23] | 0x80000000;
+    case 8:
+      w0[2] = 0x80;
       break;
 
-    case 96:
-      w[24] = 0x80;
+    case 9:
+      w0[2] = w0[2] | 0x8000;
       break;
 
-    case 97:
-      w[24] = w[24] | 0x8000;
+    case 10:
+      w0[2] = w0[2] | 0x800000;
       break;
 
-    case 98:
-      w[24] = w[24] | 0x800000;
+    case 11:
+      w0[2] = w0[2] | 0x80000000;
       break;
 
-    case 99:
-      w[24] = w[24] | 0x80000000;
+    case 12:
+      w0[3] = 0x80;
       break;
 
-    case 100:
-      w[25] = 0x80;
+    case 13:
+      w0[3] = w0[3] | 0x8000;
       break;
 
-    case 101:
-      w[25] = w[25] | 0x8000;
+    case 14:
+      w0[3] = w0[3] | 0x800000;
       break;
 
-    case 102:
-      w[25] = w[25] | 0x800000;
+    case 15:
+      w0[3] = w0[3] | 0x80000000;
       break;
+  }
+}
 
-    case 103:
-      w[25] = w[25] | 0x80000000;
+inline void append_0x80_2x4_S (u32 w0[4], u32 w1[4], const u32 offset)
+{
+  switch (offset)
+  {
+    case 0:
+      w0[0] = 0x80;
       break;
 
-    case 104:
-      w[26] = 0x80;
+    case 1:
+      w0[0] = w0[0] | 0x8000;
       break;
 
-    case 105:
-      w[26] = w[26] | 0x8000;
+    case 2:
+      w0[0] = w0[0] | 0x800000;
       break;
 
-    case 106:
-      w[26] = w[26] | 0x800000;
+    case 3:
+      w0[0] = w0[0] | 0x80000000;
       break;
 
-    case 107:
-      w[26] = w[26] | 0x80000000;
+    case 4:
+      w0[1] = 0x80;
       break;
 
-    case 108:
-      w[27] = 0x80;
+    case 5:
+      w0[1] = w0[1] | 0x8000;
       break;
 
-    case 109:
-      w[27] = w[27] | 0x8000;
+    case 6:
+      w0[1] = w0[1] | 0x800000;
       break;
 
-    case 110:
-      w[27] = w[27] | 0x800000;
+    case 7:
+      w0[1] = w0[1] | 0x80000000;
       break;
 
-    case 111:
-      w[27] = w[27] | 0x80000000;
+    case 8:
+      w0[2] = 0x80;
       break;
 
-    case 112:
-      w[28] = 0x80;
+    case 9:
+      w0[2] = w0[2] | 0x8000;
       break;
 
-    case 113:
-      w[28] = w[28] | 0x8000;
+    case 10:
+      w0[2] = w0[2] | 0x800000;
       break;
 
-    case 114:
-      w[28] = w[28] | 0x800000;
+    case 11:
+      w0[2] = w0[2] | 0x80000000;
       break;
 
-    case 115:
-      w[28] = w[28] | 0x80000000;
+    case 12:
+      w0[3] = 0x80;
       break;
 
-    case 116:
-      w[29] = 0x80;
+    case 13:
+      w0[3] = w0[3] | 0x8000;
       break;
 
-    case 117:
-      w[29] = w[29] | 0x8000;
+    case 14:
+      w0[3] = w0[3] | 0x800000;
       break;
 
-    case 118:
-      w[29] = w[29] | 0x800000;
+    case 15:
+      w0[3] = w0[3] | 0x80000000;
       break;
 
-    case 119:
-      w[29] = w[29] | 0x80000000;
+    case 16:
+      w1[0] = 0x80;
       break;
 
-    case 120:
-      w[30] = 0x80;
+    case 17:
+      w1[0] = w1[0] | 0x8000;
       break;
 
-    case 121:
-      w[30] = w[30] | 0x8000;
+    case 18:
+      w1[0] = w1[0] | 0x800000;
       break;
 
-    case 122:
-      w[30] = w[30] | 0x800000;
+    case 19:
+      w1[0] = w1[0] | 0x80000000;
       break;
 
-    case 123:
-      w[30] = w[30] | 0x80000000;
+    case 20:
+      w1[1] = 0x80;
       break;
 
-    case 124:
-      w[31] = 0x80;
+    case 21:
+      w1[1] = w1[1] | 0x8000;
       break;
 
-    case 125:
-      w[31] = w[31] | 0x8000;
+    case 22:
+      w1[1] = w1[1] | 0x800000;
       break;
 
-    case 126:
-      w[31] = w[31] | 0x800000;
+    case 23:
+      w1[1] = w1[1] | 0x80000000;
       break;
 
-    case 127:
-      w[31] = w[31] | 0x80000000;
+    case 24:
+      w1[2] = 0x80;
       break;
-  }
-}
 
-// before: device_memcat2L
-static void memcat_c7_d1x2_sl1x2_sr1x2 (const u32 offset, u32 dst0[2], u32 src_l0[2], u32 src_r0[2])
-{
-  switch (offset)
-  {
-    case 1:
-      dst0[0] = src_l0[0]       | src_r0[0] <<  8;
-      dst0[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
+    case 25:
+      w1[2] = w1[2] | 0x8000;
       break;
 
-    case 2:
-      dst0[0] = src_l0[0]       | src_r0[0] << 16;
-      dst0[1] = src_r0[0] >> 16 | src_r0[1] << 16;
+    case 26:
+      w1[2] = w1[2] | 0x800000;
       break;
 
-    case 3:
-      dst0[0] = src_l0[0]       | src_r0[0] << 24;
-      dst0[1] = src_r0[0] >>  8 | src_r0[1] << 24;
+    case 27:
+      w1[2] = w1[2] | 0x80000000;
       break;
 
-    case 4:
-      dst0[1] = src_r0[0];
+    case 28:
+      w1[3] = 0x80;
       break;
 
-    case 5:
-      dst0[1] = src_l0[1]       | src_r0[0] <<  8;
+    case 29:
+      w1[3] = w1[3] | 0x8000;
       break;
 
-    case 6:
-      dst0[1] = src_l0[1]       | src_r0[0] << 16;
+    case 30:
+      w1[3] = w1[3] | 0x800000;
       break;
 
-    case 7:
-      dst0[1] = src_l0[1]       | src_r0[0] << 24;
+    case 31:
+      w1[3] = w1[3] | 0x80000000;
       break;
   }
 }
 
-// before: device_memcat4L
-static void memcat_c15_d1x4_sl1x4_sr1x4 (const u32 offset, u32 dst0[4], u32 src_l0[4], u32 src_r0[4])
+inline void append_0x80_3x4_S (u32 w0[4], u32 w1[4], u32 w2[4], const u32 offset)
 {
   switch (offset)
   {
+    case 0:
+      w0[0] = 0x80;
+      break;
+
     case 1:
-      dst0[0] = src_l0[0]       | src_r0[0] <<  8;
-      dst0[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst0[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst0[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
+      w0[0] = w0[0] | 0x8000;
       break;
 
     case 2:
-      dst0[0] = src_l0[0]       | src_r0[0] << 16;
-      dst0[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst0[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst0[3] = src_r0[2] >> 16 | src_r0[3] << 16;
+      w0[0] = w0[0] | 0x800000;
       break;
 
     case 3:
-      dst0[0] = src_l0[0]       | src_r0[0] << 24;
-      dst0[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst0[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst0[3] = src_r0[2] >>  8 | src_r0[3] << 24;
+      w0[0] = w0[0] | 0x80000000;
       break;
 
     case 4:
-      dst0[1] = src_r0[0];
-      dst0[2] = src_r0[1];
-      dst0[3] = src_r0[2];
+      w0[1] = 0x80;
       break;
 
     case 5:
-      dst0[1] = src_l0[1]       | src_r0[0] <<  8;
-      dst0[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst0[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
+      w0[1] = w0[1] | 0x8000;
       break;
 
     case 6:
-      dst0[1] = src_l0[1]       | src_r0[0] << 16;
-      dst0[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst0[3] = src_r0[1] >> 16 | src_r0[2] << 16;
+      w0[1] = w0[1] | 0x800000;
       break;
 
     case 7:
-      dst0[1] = src_l0[1]       | src_r0[0] << 24;
-      dst0[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst0[3] = src_r0[1] >>  8 | src_r0[2] << 24;
+      w0[1] = w0[1] | 0x80000000;
       break;
 
     case 8:
-      dst0[2] = src_r0[0];
-      dst0[3] = src_r0[1];
+      w0[2] = 0x80;
       break;
 
     case 9:
-      dst0[2] = src_l0[2]       | src_r0[0] <<  8;
-      dst0[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
+      w0[2] = w0[2] | 0x8000;
       break;
 
     case 10:
-      dst0[2] = src_l0[2]       | src_r0[0] << 16;
-      dst0[3] = src_r0[0] >> 16 | src_r0[1] << 16;
+      w0[2] = w0[2] | 0x800000;
       break;
 
     case 11:
-      dst0[2] = src_l0[2]       | src_r0[0] << 24;
-      dst0[3] = src_r0[0] >>  8 | src_r0[1] << 24;
+      w0[2] = w0[2] | 0x80000000;
       break;
 
     case 12:
-      dst0[3] = src_r0[0];
+      w0[3] = 0x80;
       break;
 
     case 13:
-      dst0[3] = src_l0[3]       | src_r0[0] <<  8;
+      w0[3] = w0[3] | 0x8000;
       break;
 
     case 14:
-      dst0[3] = src_l0[3]       | src_r0[0] << 16;
+      w0[3] = w0[3] | 0x800000;
       break;
 
     case 15:
-      dst0[3] = src_l0[3]       | src_r0[0] << 24;
+      w0[3] = w0[3] | 0x80000000;
       break;
-  }
-}
 
-// before: device_memcat8L
-static void memcat_c31_d2x4_sl2x4_sr1x4 (const u32 offset, u32 dst0[4], u32 dst1[4], u32 src_l0[4], u32 src_l1[4], u32 src_r0[4])
-{
-  switch (offset)
-  {
-    case 1:
-      dst0[0] = src_l0[0]       | src_r0[0] <<  8;
-      dst0[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst0[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst0[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[0] = src_r0[3] >> 24;
+    case 16:
+      w1[0] = 0x80;
       break;
 
-    case 2:
-      dst0[0] = src_l0[0]       | src_r0[0] << 16;
-      dst0[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst0[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst0[3] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[0] = src_r0[3] >> 16;
+    case 17:
+      w1[0] = w1[0] | 0x8000;
       break;
 
-    case 3:
-      dst0[0] = src_l0[0]       | src_r0[0] << 24;
-      dst0[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst0[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst0[3] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[0] = src_r0[3] >>  8;
+    case 18:
+      w1[0] = w1[0] | 0x800000;
       break;
 
-    case 4:
-      dst0[1] = src_r0[0];
-      dst0[2] = src_r0[1];
-      dst0[3] = src_r0[2];
-      dst1[0] = src_r0[3];
+    case 19:
+      w1[0] = w1[0] | 0x80000000;
       break;
 
-    case 5:
-      dst0[1] = src_l0[1]       | src_r0[0] <<  8;
-      dst0[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst0[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[0] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[1] = src_r0[3] >> 24;
+    case 20:
+      w1[1] = 0x80;
       break;
 
-    case 6:
-      dst0[1] = src_l0[1]       | src_r0[0] << 16;
-      dst0[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst0[3] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[0] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[1] = src_r0[3] >> 16;
+    case 21:
+      w1[1] = w1[1] | 0x8000;
       break;
 
-    case 7:
-      dst0[1] = src_l0[1]       | src_r0[0] << 24;
-      dst0[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst0[3] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[0] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[1] = src_r0[3] >>  8;
+    case 22:
+      w1[1] = w1[1] | 0x800000;
       break;
 
-    case 8:
-      dst0[2] = src_r0[0];
-      dst0[3] = src_r0[1];
-      dst1[0] = src_r0[2];
-      dst1[1] = src_r0[3];
+    case 23:
+      w1[1] = w1[1] | 0x80000000;
       break;
 
-    case 9:
-      dst0[2] = src_l0[2]       | src_r0[0] <<  8;
-      dst0[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[0] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[1] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[2] = src_r0[3] >> 24;
+    case 24:
+      w1[2] = 0x80;
+      break;
+
+    case 25:
+      w1[2] = w1[2] | 0x8000;
       break;
 
-    case 10:
-      dst0[2] = src_l0[2]       | src_r0[0] << 16;
-      dst0[3] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[0] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[1] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[2] = src_r0[3] >> 16;
+    case 26:
+      w1[2] = w1[2] | 0x800000;
       break;
 
-    case 11:
-      dst0[2] = src_l0[2]       | src_r0[0] << 24;
-      dst0[3] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[0] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[1] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[2] = src_r0[3] >>  8;
+    case 27:
+      w1[2] = w1[2] | 0x80000000;
       break;
 
-    case 12:
-      dst0[3] = src_r0[0];
-      dst1[0] = src_r0[1];
-      dst1[1] = src_r0[2];
-      dst1[2] = src_r0[3];
+    case 28:
+      w1[3] = 0x80;
       break;
 
-    case 13:
-      dst0[3] = src_l0[3]       | src_r0[0] <<  8;
-      dst1[0] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[1] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[2] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[3] = src_r0[3] >> 24;
+    case 29:
+      w1[3] = w1[3] | 0x8000;
       break;
 
-    case 14:
-      dst0[3] = src_l0[3]       | src_r0[0] << 16;
-      dst1[0] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[1] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[2] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[3] = src_r0[3] >> 16;
+    case 30:
+      w1[3] = w1[3] | 0x800000;
       break;
 
-    case 15:
-      dst0[3] = src_l0[3]       | src_r0[0] << 24;
-      dst1[0] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[1] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[2] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[3] = src_r0[3] >>  8;
+    case 31:
+      w1[3] = w1[3] | 0x80000000;
       break;
 
-    case 16:
-      dst1[0] = src_r0[0];
-      dst1[1] = src_r0[1];
-      dst1[2] = src_r0[2];
-      dst1[3] = src_r0[3];
+    case 32:
+      w2[0] = 0x80;
       break;
 
-    case 17:
-      dst1[0] = src_l1[0]       | src_r0[0] <<  8;
-      dst1[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
+    case 33:
+      w2[0] = w2[0] | 0x8000;
       break;
 
-    case 18:
-      dst1[0] = src_l1[0]       | src_r0[0] << 16;
-      dst1[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[3] = src_r0[2] >> 16 | src_r0[3] << 16;
+    case 34:
+      w2[0] = w2[0] | 0x800000;
       break;
 
-    case 19:
-      dst1[0] = src_l1[0]       | src_r0[0] << 24;
-      dst1[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[3] = src_r0[2] >>  8 | src_r0[3] << 24;
+    case 35:
+      w2[0] = w2[0] | 0x80000000;
       break;
 
-    case 20:
-      dst1[1] = src_r0[0];
-      dst1[2] = src_r0[1];
-      dst1[3] = src_r0[2];
+    case 36:
+      w2[1] = 0x80;
       break;
 
-    case 21:
-      dst1[1] = src_l1[1]       | src_r0[0] <<  8;
-      dst1[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
+    case 37:
+      w2[1] = w2[1] | 0x8000;
       break;
 
-    case 22:
-      dst1[1] = src_l1[1]       | src_r0[0] << 16;
-      dst1[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[3] = src_r0[1] >> 16 | src_r0[2] << 16;
+    case 38:
+      w2[1] = w2[1] | 0x800000;
       break;
 
-    case 23:
-      dst1[1] = src_l1[1]       | src_r0[0] << 24;
-      dst1[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[3] = src_r0[1] >>  8 | src_r0[2] << 24;
+    case 39:
+      w2[1] = w2[1] | 0x80000000;
       break;
 
-    case 24:
-      dst1[2] = src_r0[0];
-      dst1[3] = src_r0[1];
+    case 40:
+      w2[2] = 0x80;
       break;
 
-    case 25:
-      dst1[2] = src_l1[2]       | src_r0[0] <<  8;
-      dst1[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
+    case 41:
+      w2[2] = w2[2] | 0x8000;
       break;
 
-    case 26:
-      dst1[2] = src_l1[2]       | src_r0[0] << 16;
-      dst1[3] = src_r0[0] >> 16 | src_r0[1] << 16;
+    case 42:
+      w2[2] = w2[2] | 0x800000;
       break;
 
-    case 27:
-      dst1[2] = src_l1[2]       | src_r0[0] << 24;
-      dst1[3] = src_r0[0] >>  8 | src_r0[1] << 24;
+    case 43:
+      w2[2] = w2[2] | 0x80000000;
       break;
 
-    case 28:
-      dst1[3] = src_r0[0];
+    case 44:
+      w2[3] = 0x80;
       break;
 
-    case 29:
-      dst1[3] = src_l1[3]       | src_r0[0] <<  8;
+    case 45:
+      w2[3] = w2[3] | 0x8000;
       break;
 
-    case 30:
-      dst1[3] = src_l1[3]       | src_r0[0] << 16;
+    case 46:
+      w2[3] = w2[3] | 0x800000;
       break;
 
-    case 31:
-      dst1[3] = src_l1[3]       | src_r0[0] << 24;
+    case 47:
+      w2[3] = w2[3] | 0x80000000;
       break;
   }
 }
 
-// before: device_memcat12L
-static void memcat_c47_d3x4_sl3x4_sr1x4 (const u32 offset, u32 dst0[4], u32 dst1[4], u32 dst2[4], u32 src_l0[4], u32 src_l1[4], u32 src_l2[4], u32 src_r0[4])
+inline void append_0x80_4x4_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 offset)
 {
   switch (offset)
   {
+    case 0:
+      w0[0] = 0x80;
+      break;
+
     case 1:
-      dst0[0] = src_l0[0]       | src_r0[0] <<  8;
-      dst0[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst0[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst0[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[0] = src_r0[3] >> 24;
+      w0[0] = w0[0] | 0x8000;
       break;
 
     case 2:
-      dst0[0] = src_l0[0]       | src_r0[0] << 16;
-      dst0[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst0[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst0[3] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[0] = src_r0[3] >> 16;
+      w0[0] = w0[0] | 0x800000;
       break;
 
     case 3:
-      dst0[0] = src_l0[0]       | src_r0[0] << 24;
-      dst0[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst0[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst0[3] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[0] = src_r0[3] >>  8;
+      w0[0] = w0[0] | 0x80000000;
       break;
 
     case 4:
-      dst0[1] = src_r0[0];
-      dst0[2] = src_r0[1];
-      dst0[3] = src_r0[2];
-      dst1[0] = src_r0[3];
+      w0[1] = 0x80;
       break;
 
     case 5:
-      dst0[1] = src_l0[1]       | src_r0[0] <<  8;
-      dst0[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst0[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[0] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[1] = src_r0[3] >> 24;
+      w0[1] = w0[1] | 0x8000;
       break;
 
     case 6:
-      dst0[1] = src_l0[1]       | src_r0[0] << 16;
-      dst0[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst0[3] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[0] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[1] = src_r0[3] >> 16;
+      w0[1] = w0[1] | 0x800000;
       break;
 
     case 7:
-      dst0[1] = src_l0[1]       | src_r0[0] << 24;
-      dst0[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst0[3] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[0] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[1] = src_r0[3] >>  8;
+      w0[1] = w0[1] | 0x80000000;
       break;
 
     case 8:
-      dst0[2] = src_r0[0];
-      dst0[3] = src_r0[1];
-      dst1[0] = src_r0[2];
-      dst1[1] = src_r0[3];
+      w0[2] = 0x80;
       break;
 
     case 9:
-      dst0[2] = src_l0[2]       | src_r0[0] <<  8;
-      dst0[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[0] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[1] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[2] = src_r0[3] >> 24;
+      w0[2] = w0[2] | 0x8000;
       break;
 
     case 10:
-      dst0[2] = src_l0[2]       | src_r0[0] << 16;
-      dst0[3] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[0] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[1] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[2] = src_r0[3] >> 16;
+      w0[2] = w0[2] | 0x800000;
       break;
 
     case 11:
-      dst0[2] = src_l0[2]       | src_r0[0] << 24;
-      dst0[3] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[0] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[1] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[2] = src_r0[3] >>  8;
+      w0[2] = w0[2] | 0x80000000;
       break;
 
     case 12:
-      dst0[3] = src_r0[0];
-      dst1[0] = src_r0[1];
-      dst1[1] = src_r0[2];
-      dst1[2] = src_r0[3];
+      w0[3] = 0x80;
       break;
 
     case 13:
-      dst0[3] = src_l0[3]       | src_r0[0] <<  8;
-      dst1[0] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[1] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[2] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[3] = src_r0[3] >> 24;
+      w0[3] = w0[3] | 0x8000;
       break;
 
     case 14:
-      dst0[3] = src_l0[3]       | src_r0[0] << 16;
-      dst1[0] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[1] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[2] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[3] = src_r0[3] >> 16;
+      w0[3] = w0[3] | 0x800000;
       break;
 
     case 15:
-      dst0[3] = src_l0[3]       | src_r0[0] << 24;
-      dst1[0] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[1] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[2] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[3] = src_r0[3] >>  8;
+      w0[3] = w0[3] | 0x80000000;
       break;
 
     case 16:
-      dst1[0] = src_r0[0];
-      dst1[1] = src_r0[1];
-      dst1[2] = src_r0[2];
-      dst1[3] = src_r0[3];
+      w1[0] = 0x80;
       break;
 
     case 17:
-      dst1[0] = src_l1[0]       | src_r0[0] <<  8;
-      dst1[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst2[0] = src_r0[3] >> 24;
+      w1[0] = w1[0] | 0x8000;
       break;
 
     case 18:
-      dst1[0] = src_l1[0]       | src_r0[0] << 16;
-      dst1[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[3] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst2[0] = src_r0[3] >> 16;
+      w1[0] = w1[0] | 0x800000;
       break;
 
     case 19:
-      dst1[0] = src_l1[0]       | src_r0[0] << 24;
-      dst1[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[3] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst2[0] = src_r0[3] >>  8;
+      w1[0] = w1[0] | 0x80000000;
       break;
 
     case 20:
-      dst1[1] = src_r0[0];
-      dst1[2] = src_r0[1];
-      dst1[3] = src_r0[2];
-      dst2[0] = src_r0[3];
+      w1[1] = 0x80;
       break;
 
     case 21:
-      dst1[1] = src_l1[1]       | src_r0[0] <<  8;
-      dst1[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst2[0] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst2[1] = src_r0[3] >> 24;
+      w1[1] = w1[1] | 0x8000;
       break;
 
     case 22:
-      dst1[1] = src_l1[1]       | src_r0[0] << 16;
-      dst1[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[3] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst2[0] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst2[1] = src_r0[3] >> 16;
+      w1[1] = w1[1] | 0x800000;
       break;
 
     case 23:
-      dst1[1] = src_l1[1]       | src_r0[0] << 24;
-      dst1[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[3] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst2[0] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst2[1] = src_r0[3] >>  8;
+      w1[1] = w1[1] | 0x80000000;
       break;
 
     case 24:
-      dst1[2] = src_r0[0];
-      dst1[3] = src_r0[1];
-      dst2[0] = src_r0[2];
-      dst2[1] = src_r0[3];
+      w1[2] = 0x80;
       break;
 
     case 25:
-      dst1[2] = src_l1[2]       | src_r0[0] <<  8;
-      dst1[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst2[0] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst2[1] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst2[2] = src_r0[3] >> 24;
+      w1[2] = w1[2] | 0x8000;
       break;
 
     case 26:
-      dst1[2] = src_l1[2]       | src_r0[0] << 16;
-      dst1[3] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst2[0] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst2[1] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst2[2] = src_r0[3] >> 16;
+      w1[2] = w1[2] | 0x800000;
       break;
 
     case 27:
-      dst1[2] = src_l1[2]       | src_r0[0] << 24;
-      dst1[3] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst2[0] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst2[1] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst2[2] = src_r0[3] >>  8;
+      w1[2] = w1[2] | 0x80000000;
       break;
 
     case 28:
-      dst1[3] = src_r0[0];
-      dst2[0] = src_r0[1];
-      dst2[1] = src_r0[2];
-      dst2[2] = src_r0[3];
+      w1[3] = 0x80;
       break;
 
     case 29:
-      dst1[3] = src_l1[3]       | src_r0[0] <<  8;
-      dst2[0] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst2[1] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst2[2] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst2[3] = src_r0[3] >> 24;
+      w1[3] = w1[3] | 0x8000;
       break;
 
     case 30:
-      dst1[3] = src_l1[3]       | src_r0[0] << 16;
-      dst2[0] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst2[1] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst2[2] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst2[3] = src_r0[3] >> 16;
+      w1[3] = w1[3] | 0x800000;
       break;
 
     case 31:
-      dst1[3] = src_l1[3]       | src_r0[0] << 24;
-      dst2[0] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst2[1] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst2[2] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst2[3] = src_r0[3] >>  8;
+      w1[3] = w1[3] | 0x80000000;
       break;
 
     case 32:
-      dst2[0] = src_r0[0];
-      dst2[1] = src_r0[1];
-      dst2[2] = src_r0[2];
-      dst2[3] = src_r0[3];
+      w2[0] = 0x80;
       break;
 
     case 33:
-      dst2[0] = src_l2[0]       | src_r0[0] <<  8;
-      dst2[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst2[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst2[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
+      w2[0] = w2[0] | 0x8000;
       break;
 
     case 34:
-      dst2[0] = src_l2[0]       | src_r0[0] << 16;
-      dst2[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst2[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst2[3] = src_r0[2] >> 16 | src_r0[3] << 16;
+      w2[0] = w2[0] | 0x800000;
       break;
 
     case 35:
-      dst2[0] = src_l2[0]       | src_r0[0] << 24;
-      dst2[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst2[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst2[3] = src_r0[2] >>  8 | src_r0[3] << 24;
+      w2[0] = w2[0] | 0x80000000;
       break;
 
     case 36:
-      dst2[1] = src_r0[0];
-      dst2[2] = src_r0[1];
-      dst2[3] = src_r0[2];
+      w2[1] = 0x80;
       break;
 
     case 37:
-      dst2[1] = src_l2[1]       | src_r0[0] <<  8;
-      dst2[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst2[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
+      w2[1] = w2[1] | 0x8000;
       break;
 
     case 38:
-      dst2[1] = src_l2[1]       | src_r0[0] << 16;
-      dst2[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst2[3] = src_r0[1] >> 16 | src_r0[2] << 16;
+      w2[1] = w2[1] | 0x800000;
       break;
 
     case 39:
-      dst2[1] = src_l2[1]       | src_r0[0] << 24;
-      dst2[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst2[3] = src_r0[1] >>  8 | src_r0[2] << 24;
+      w2[1] = w2[1] | 0x80000000;
       break;
 
     case 40:
-      dst2[2] = src_r0[0];
-      dst2[3] = src_r0[1];
+      w2[2] = 0x80;
       break;
 
     case 41:
-      dst2[2] = src_l2[2]       | src_r0[0] <<  8;
-      dst2[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
+      w2[2] = w2[2] | 0x8000;
       break;
 
     case 42:
-      dst2[2] = src_l2[2]       | src_r0[0] << 16;
-      dst2[3] = src_r0[0] >> 16 | src_r0[1] << 16;
+      w2[2] = w2[2] | 0x800000;
       break;
 
     case 43:
-      dst2[2] = src_l2[2]       | src_r0[0] << 24;
-      dst2[3] = src_r0[0] >>  8 | src_r0[1] << 24;
+      w2[2] = w2[2] | 0x80000000;
       break;
 
     case 44:
-      dst2[3] = src_r0[0];
+      w2[3] = 0x80;
       break;
 
     case 45:
-      dst2[3] = src_l2[3]       | src_r0[0] <<  8;
+      w2[3] = w2[3] | 0x8000;
       break;
 
     case 46:
-      dst2[3] = src_l2[3]       | src_r0[0] << 16;
+      w2[3] = w2[3] | 0x800000;
+      break;
+
+    case 47:
+      w2[3] = w2[3] | 0x80000000;
+      break;
+
+    case 48:
+      w3[0] = 0x80;
+      break;
+
+    case 49:
+      w3[0] = w3[0] | 0x8000;
+      break;
+
+    case 50:
+      w3[0] = w3[0] | 0x800000;
+      break;
+
+    case 51:
+      w3[0] = w3[0] | 0x80000000;
+      break;
+
+    case 52:
+      w3[1] = 0x80;
+      break;
+
+    case 53:
+      w3[1] = w3[1] | 0x8000;
+      break;
+
+    case 54:
+      w3[1] = w3[1] | 0x800000;
+      break;
+
+    case 55:
+      w3[1] = w3[1] | 0x80000000;
+      break;
+
+    case 56:
+      w3[2] = 0x80;
+      break;
+
+    case 57:
+      w3[2] = w3[2] | 0x8000;
+      break;
+
+    case 58:
+      w3[2] = w3[2] | 0x800000;
+      break;
+
+    case 59:
+      w3[2] = w3[2] | 0x80000000;
+      break;
+
+    case 60:
+      w3[3] = 0x80;
+      break;
+
+    case 61:
+      w3[3] = w3[3] | 0x8000;
+      break;
+
+    case 62:
+      w3[3] = w3[3] | 0x800000;
+      break;
+
+    case 63:
+      w3[3] = w3[3] | 0x80000000;
       break;
+  }
+}
+
+inline void truncate_block_S (u32 w[4], const u32 len)
+{
+  switch (len)
+  {
+    case  0:  w[0] &= 0;
+              w[1] &= 0;
+              w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  1:  w[0] &= 0x000000FF;
+              w[1] &= 0;
+              w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  2:  w[0] &= 0x0000FFFF;
+              w[1] &= 0;
+              w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  3:  w[0] &= 0x00FFFFFF;
+              w[1] &= 0;
+              w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  4:  w[1] &= 0;
+              w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  5:  w[1] &= 0x000000FF;
+              w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  6:  w[1] &= 0x0000FFFF;
+              w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  7:  w[1] &= 0x00FFFFFF;
+              w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  8:  w[2] &= 0;
+              w[3] &= 0;
+              break;
+    case  9:  w[2] &= 0x000000FF;
+              w[3] &= 0;
+              break;
+    case 10:  w[2] &= 0x0000FFFF;
+              w[3] &= 0;
+              break;
+    case 11:  w[2] &= 0x00FFFFFF;
+              w[3] &= 0;
+              break;
+    case 12:  w[3] &= 0;
+              break;
+    case 13:  w[3] &= 0x000000FF;
+              break;
+    case 14:  w[3] &= 0x0000FFFF;
+              break;
+    case 15:  w[3] &= 0x00FFFFFF;
+              break;
+  }
+}
+
+inline void make_unicode_S (const u32 in[4], u32 out1[4], u32 out2[4])
+{
+  #ifdef IS_NV
+  out2[3] = __byte_perm_S (in[3], 0, 0x7372);
+  out2[2] = __byte_perm_S (in[3], 0, 0x7170);
+  out2[1] = __byte_perm_S (in[2], 0, 0x7372);
+  out2[0] = __byte_perm_S (in[2], 0, 0x7170);
+  out1[3] = __byte_perm_S (in[1], 0, 0x7372);
+  out1[2] = __byte_perm_S (in[1], 0, 0x7170);
+  out1[1] = __byte_perm_S (in[0], 0, 0x7372);
+  out1[0] = __byte_perm_S (in[0], 0, 0x7170);
+  #endif
 
-    case 47:
-      dst2[3] = src_l2[3]       | src_r0[0] << 24;
-      break;
-  }
+  #if defined IS_AMD || defined IS_GENERIC
+  out2[3]  = ((in[3] >> 8) & 0x00FF0000) | ((in[3] >> 16) & 0x000000FF);
+  out2[2]  = ((in[3] << 8) & 0x00FF0000) | ((in[3] >>  0) & 0x000000FF);
+  out2[1]  = ((in[2] >> 8) & 0x00FF0000) | ((in[2] >> 16) & 0x000000FF);
+  out2[0]  = ((in[2] << 8) & 0x00FF0000) | ((in[2] >>  0) & 0x000000FF);
+  out1[3]  = ((in[1] >> 8) & 0x00FF0000) | ((in[1] >> 16) & 0x000000FF);
+  out1[2]  = ((in[1] << 8) & 0x00FF0000) | ((in[1] >>  0) & 0x000000FF);
+  out1[1]  = ((in[0] >> 8) & 0x00FF0000) | ((in[0] >> 16) & 0x000000FF);
+  out1[0]  = ((in[0] << 8) & 0x00FF0000) | ((in[0] >>  0) & 0x000000FF);
+  #endif
 }
 
-// before: device_memcat12L
-static void memcat_c47_d3x4_sl3x4_sr2x4 (const u32 offset, u32 dst0[4], u32 dst1[4], u32 dst2[4], u32 src_l0[4], u32 src_l1[4], u32 src_l2[4], u32 src_r0[4], u32 src_r1[4])
+inline void undo_unicode_S (const u32 in1[4], const u32 in2[4], u32 out[4])
 {
-  switch (offset)
-  {
-    case 0:
-      dst0[0] = src_r0[0];
-      dst0[1] = src_r0[1];
-      dst0[2] = src_r0[2];
-      dst0[3] = src_r0[3];
-      dst1[0] = src_r1[0];
-      dst1[1] = src_r1[1];
-      dst1[2] = src_r1[2];
-      dst1[3] = src_r1[3];
-      break;
-
-    case 1:
-      dst0[0] = src_l0[0]       | src_r0[0] <<  8;
-      dst0[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst0[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst0[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[0] = src_r0[3] >> 24 | src_r1[0] <<  8;
-      dst1[1] = src_r1[0] >> 24 | src_r1[1] <<  8;
-      dst1[2] = src_r1[1] >> 24 | src_r1[2] <<  8;
-      dst1[3] = src_r1[2] >> 24 | src_r1[3] <<  8;
-      dst2[0] = src_r1[3] >> 24;
-      break;
-
-    case 2:
-      dst0[0] = src_l0[0]       | src_r0[0] << 16;
-      dst0[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst0[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst0[3] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[0] = src_r0[3] >> 16 | src_r1[0] << 16;
-      dst1[1] = src_r1[0] >> 16 | src_r1[1] << 16;
-      dst1[2] = src_r1[1] >> 16 | src_r1[2] << 16;
-      dst1[3] = src_r1[2] >> 16 | src_r1[3] << 16;
-      dst2[0] = src_r1[3] >> 16;
-      break;
+  #ifdef IS_NV
+  out[0] = __byte_perm_S (in1[0], in1[1], 0x6420);
+  out[1] = __byte_perm_S (in1[2], in1[3], 0x6420);
+  out[2] = __byte_perm_S (in2[0], in2[1], 0x6420);
+  out[3] = __byte_perm_S (in2[2], in2[3], 0x6420);
+  #endif
 
-    case 3:
-      dst0[0] = src_l0[0]       | src_r0[0] << 24;
-      dst0[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst0[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst0[3] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[0] = src_r0[3] >>  8 | src_r1[0] << 24;
-      dst1[1] = src_r1[0] >>  8 | src_r1[1] << 24;
-      dst1[2] = src_r1[1] >>  8 | src_r1[2] << 24;
-      dst1[3] = src_r1[2] >>  8 | src_r1[3] << 24;
-      dst2[0] = src_r1[3] >>  8;
-      break;
+  #if defined IS_AMD || defined IS_GENERIC
+  out[0] = ((in1[0] & 0x000000ff) >>  0) | ((in1[0] & 0x00ff0000) >>  8)
+         | ((in1[1] & 0x000000ff) << 16) | ((in1[1] & 0x00ff0000) <<  8);
+  out[1] = ((in1[2] & 0x000000ff) >>  0) | ((in1[2] & 0x00ff0000) >>  8)
+         | ((in1[3] & 0x000000ff) << 16) | ((in1[3] & 0x00ff0000) <<  8);
+  out[2] = ((in2[0] & 0x000000ff) >>  0) | ((in2[0] & 0x00ff0000) >>  8)
+         | ((in2[1] & 0x000000ff) << 16) | ((in2[1] & 0x00ff0000) <<  8);
+  out[3] = ((in2[2] & 0x000000ff) >>  0) | ((in2[2] & 0x00ff0000) >>  8)
+         | ((in2[3] & 0x000000ff) << 16) | ((in2[3] & 0x00ff0000) <<  8);
+  #endif
+}
 
-    case 4:
-      dst0[1] = src_r0[0];
-      dst0[2] = src_r0[1];
-      dst0[3] = src_r0[2];
-      dst1[0] = src_r0[3];
-      dst1[1] = src_r1[0];
-      dst1[2] = src_r1[1];
-      dst1[3] = src_r1[2];
-      dst2[0] = src_r1[3];
-      break;
+inline void switch_buffer_by_offset_le_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 offset)
+{
+  #if defined IS_AMD || defined IS_GENERIC
+  const int offset_mod_4 = offset & 3;
 
-    case 5:
-      dst0[1] = src_l0[1]       | src_r0[0] <<  8;
-      dst0[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst0[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[0] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[1] = src_r0[3] >> 24 | src_r1[0] <<  8;
-      dst1[2] = src_r1[0] >> 24 | src_r1[1] <<  8;
-      dst1[3] = src_r1[1] >> 24 | src_r1[2] <<  8;
-      dst2[0] = src_r1[2] >> 24 | src_r1[3] <<  8;
-      dst2[1] = src_r1[3] >> 24;
-      break;
+  const int offset_minus_4 = 4 - offset;
 
-    case 6:
-      dst0[1] = src_l0[1]       | src_r0[0] << 16;
-      dst0[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst0[3] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[0] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[1] = src_r0[3] >> 16 | src_r1[0] << 16;
-      dst1[2] = src_r1[0] >> 16 | src_r1[1] << 16;
-      dst1[3] = src_r1[1] >> 16 | src_r1[2] << 16;
-      dst2[0] = src_r1[2] >> 16 | src_r1[3] << 16;
-      dst2[1] = src_r1[3] >> 16;
-      break;
+  switch (offset / 4)
+  {
+    case 0:
+      w3[2] = amd_bytealign_S (    0, w3[1], offset_minus_4);
+      w3[1] = amd_bytealign_S (w3[1], w3[0], offset_minus_4);
+      w3[0] = amd_bytealign_S (w3[0], w2[3], offset_minus_4);
+      w2[3] = amd_bytealign_S (w2[3], w2[2], offset_minus_4);
+      w2[2] = amd_bytealign_S (w2[2], w2[1], offset_minus_4);
+      w2[1] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
+      w2[0] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
+      w1[3] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
+      w1[2] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
+      w1[1] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w1[0] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w0[3] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w0[2] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w0[1] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w0[0] = amd_bytealign_S (w0[0],     0, offset_minus_4);
 
-    case 7:
-      dst0[1] = src_l0[1]       | src_r0[0] << 24;
-      dst0[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst0[3] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[0] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[1] = src_r0[3] >>  8 | src_r1[0] << 24;
-      dst1[2] = src_r1[0] >>  8 | src_r1[1] << 24;
-      dst1[3] = src_r1[1] >>  8 | src_r1[2] << 24;
-      dst2[0] = src_r1[2] >>  8 | src_r1[3] << 24;
-      dst2[1] = src_r1[3] >>  8;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w0[0] = w0[1];
+        w0[1] = w0[2];
+        w0[2] = w0[3];
+        w0[3] = w1[0];
+        w1[0] = w1[1];
+        w1[1] = w1[2];
+        w1[2] = w1[3];
+        w1[3] = w2[0];
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 8:
-      dst0[2] = src_r0[0];
-      dst0[3] = src_r0[1];
-      dst1[0] = src_r0[2];
-      dst1[1] = src_r0[3];
-      dst1[2] = src_r1[0];
-      dst1[3] = src_r1[1];
-      dst2[0] = src_r1[2];
-      dst2[1] = src_r1[3];
       break;
 
-    case 9:
-      dst0[2] = src_l0[2]       | src_r0[0] <<  8;
-      dst0[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[0] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[1] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[2] = src_r0[3] >> 24 | src_r1[0] <<  8;
-      dst1[3] = src_r1[0] >> 24 | src_r1[1] <<  8;
-      dst2[0] = src_r1[1] >> 24 | src_r1[2] <<  8;
-      dst2[1] = src_r1[2] >> 24 | src_r1[3] <<  8;
-      dst2[2] = src_r1[3] >> 24;
-      break;
+    case 1:
+      w3[2] = amd_bytealign_S (    0, w3[0], offset_minus_4);
+      w3[1] = amd_bytealign_S (w3[0], w2[3], offset_minus_4);
+      w3[0] = amd_bytealign_S (w2[3], w2[2], offset_minus_4);
+      w2[3] = amd_bytealign_S (w2[2], w2[1], offset_minus_4);
+      w2[2] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
+      w2[1] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
+      w2[0] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
+      w1[3] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
+      w1[2] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w1[1] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w1[0] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w0[3] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w0[2] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w0[1] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w0[0] = 0;
 
-    case 10:
-      dst0[2] = src_l0[2]       | src_r0[0] << 16;
-      dst0[3] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[0] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[1] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[2] = src_r0[3] >> 16 | src_r1[0] << 16;
-      dst1[3] = src_r1[0] >> 16 | src_r1[1] << 16;
-      dst2[0] = src_r1[1] >> 16 | src_r1[2] << 16;
-      dst2[1] = src_r1[2] >> 16 | src_r1[3] << 16;
-      dst2[2] = src_r1[3] >> 16;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w0[1] = w0[2];
+        w0[2] = w0[3];
+        w0[3] = w1[0];
+        w1[0] = w1[1];
+        w1[1] = w1[2];
+        w1[2] = w1[3];
+        w1[3] = w2[0];
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 11:
-      dst0[2] = src_l0[2]       | src_r0[0] << 24;
-      dst0[3] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[0] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[1] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[2] = src_r0[3] >>  8 | src_r1[0] << 24;
-      dst1[3] = src_r1[0] >>  8 | src_r1[1] << 24;
-      dst2[0] = src_r1[1] >>  8 | src_r1[2] << 24;
-      dst2[1] = src_r1[2] >>  8 | src_r1[3] << 24;
-      dst2[2] = src_r1[3] >>  8;
       break;
 
-    case 12:
-      dst0[3] = src_r0[0];
-      dst1[0] = src_r0[1];
-      dst1[1] = src_r0[2];
-      dst1[2] = src_r0[3];
-      dst1[3] = src_r1[0];
-      dst2[0] = src_r1[1];
-      dst2[1] = src_r1[2];
-      dst2[2] = src_r1[3];
-      break;
+    case 2:
+      w3[2] = amd_bytealign_S (    0, w2[3], offset_minus_4);
+      w3[1] = amd_bytealign_S (w2[3], w2[2], offset_minus_4);
+      w3[0] = amd_bytealign_S (w2[2], w2[1], offset_minus_4);
+      w2[3] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
+      w2[2] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
+      w2[1] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
+      w2[0] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
+      w1[3] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w1[2] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w1[1] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w1[0] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w0[3] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w0[2] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 13:
-      dst0[3] = src_l0[3]       | src_r0[0] <<  8;
-      dst1[0] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[1] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[2] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst1[3] = src_r0[3] >> 24 | src_r1[0] <<  8;
-      dst2[0] = src_r1[0] >> 24 | src_r1[1] <<  8;
-      dst2[1] = src_r1[1] >> 24 | src_r1[2] <<  8;
-      dst2[2] = src_r1[2] >> 24 | src_r1[3] <<  8;
-      dst2[3] = src_r1[3] >> 24;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w0[2] = w0[3];
+        w0[3] = w1[0];
+        w1[0] = w1[1];
+        w1[1] = w1[2];
+        w1[2] = w1[3];
+        w1[3] = w2[0];
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 14:
-      dst0[3] = src_l0[3]       | src_r0[0] << 16;
-      dst1[0] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[1] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[2] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst1[3] = src_r0[3] >> 16 | src_r1[0] << 16;
-      dst2[0] = src_r1[0] >> 16 | src_r1[1] << 16;
-      dst2[1] = src_r1[1] >> 16 | src_r1[2] << 16;
-      dst2[2] = src_r1[2] >> 16 | src_r1[3] << 16;
-      dst2[3] = src_r1[3] >> 16;
       break;
 
-    case 15:
-      dst0[3] = src_l0[3]       | src_r0[0] << 24;
-      dst1[0] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[1] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[2] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst1[3] = src_r0[3] >>  8 | src_r1[0] << 24;
-      dst2[0] = src_r1[0] >>  8 | src_r1[1] << 24;
-      dst2[1] = src_r1[1] >>  8 | src_r1[2] << 24;
-      dst2[2] = src_r1[2] >>  8 | src_r1[3] << 24;
-      dst2[3] = src_r1[3] >>  8;
-      break;
+    case 3:
+      w3[2] = amd_bytealign_S (    0, w2[2], offset_minus_4);
+      w3[1] = amd_bytealign_S (w2[2], w2[1], offset_minus_4);
+      w3[0] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
+      w2[3] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
+      w2[2] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
+      w2[1] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
+      w2[0] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w1[3] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w1[2] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w1[1] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w1[0] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w0[3] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 16:
-      dst1[0] = src_r0[0];
-      dst1[1] = src_r0[1];
-      dst1[2] = src_r0[2];
-      dst1[3] = src_r0[3];
-      dst2[0] = src_r1[0];
-      dst2[1] = src_r1[1];
-      dst2[2] = src_r1[2];
-      dst2[3] = src_r1[3];
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w0[3] = w1[0];
+        w1[0] = w1[1];
+        w1[1] = w1[2];
+        w1[2] = w1[3];
+        w1[3] = w2[0];
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 17:
-      dst1[0] = src_l1[0]       | src_r0[0] <<  8;
-      dst1[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst1[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst2[0] = src_r0[3] >> 24 | src_r1[0] <<  8;
-      dst2[1] = src_r1[0] >> 24 | src_r1[1] <<  8;
-      dst2[2] = src_r1[1] >> 24 | src_r1[2] <<  8;
-      dst2[3] = src_r1[2] >> 24 | src_r1[3] <<  8;
       break;
 
-    case 18:
-      dst1[0] = src_l1[0]       | src_r0[0] << 16;
-      dst1[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst1[3] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst2[0] = src_r0[3] >> 16 | src_r1[0] << 16;
-      dst2[1] = src_r1[0] >> 16 | src_r1[1] << 16;
-      dst2[2] = src_r1[1] >> 16 | src_r1[2] << 16;
-      dst2[3] = src_r1[2] >> 16 | src_r1[3] << 16;
-      break;
+    case 4:
+      w3[2] = amd_bytealign_S (    0, w2[1], offset_minus_4);
+      w3[1] = amd_bytealign_S (w2[1], w2[0], offset_minus_4);
+      w3[0] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
+      w2[3] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
+      w2[2] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
+      w2[1] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w2[0] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w1[3] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w1[2] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w1[1] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w1[0] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 19:
-      dst1[0] = src_l1[0]       | src_r0[0] << 24;
-      dst1[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst1[3] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst2[0] = src_r0[3] >>  8 | src_r1[0] << 24;
-      dst2[1] = src_r1[0] >>  8 | src_r1[1] << 24;
-      dst2[2] = src_r1[1] >>  8 | src_r1[2] << 24;
-      dst2[3] = src_r1[2] >>  8 | src_r1[3] << 24;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w1[0] = w1[1];
+        w1[1] = w1[2];
+        w1[2] = w1[3];
+        w1[3] = w2[0];
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 20:
-      dst1[1] = src_r1[0];
-      dst1[2] = src_r0[1];
-      dst1[3] = src_r0[2];
-      dst2[0] = src_r0[3];
-      dst2[1] = src_r1[0];
-      dst2[2] = src_r1[1];
-      dst2[3] = src_r1[2];
       break;
 
-    case 21:
-      dst1[1] = src_l1[1]       | src_r0[0] <<  8;
-      dst1[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst1[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst2[0] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst2[1] = src_r0[3] >> 24 | src_r1[0] <<  8;
-      dst2[2] = src_r1[0] >> 24 | src_r1[1] <<  8;
-      dst2[3] = src_r1[1] >> 24 | src_r1[2] <<  8;
-      break;
+    case 5:
+      w3[2] = amd_bytealign_S (    0, w2[0], offset_minus_4);
+      w3[1] = amd_bytealign_S (w2[0], w1[3], offset_minus_4);
+      w3[0] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
+      w2[3] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
+      w2[2] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w2[1] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w2[0] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w1[3] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w1[2] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w1[1] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 22:
-      dst1[1] = src_l1[1]       | src_r0[0] << 16;
-      dst1[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst1[3] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst2[0] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst2[1] = src_r0[3] >> 16 | src_r1[0] << 16;
-      dst2[2] = src_r1[0] >> 16 | src_r1[1] << 16;
-      dst2[3] = src_r1[1] >> 16 | src_r1[2] << 16;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w1[1] = w1[2];
+        w1[2] = w1[3];
+        w1[3] = w2[0];
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 23:
-      dst1[1] = src_l1[1]       | src_r0[0] << 24;
-      dst1[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst1[3] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst2[0] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst2[1] = src_r0[3] >>  8 | src_r1[0] << 24;
-      dst2[2] = src_r1[0] >>  8 | src_r1[1] << 24;
-      dst2[3] = src_r1[1] >>  8 | src_r1[2] << 24;
       break;
 
-    case 24:
-      dst1[2] = src_r1[0];
-      dst1[3] = src_r0[1];
-      dst2[0] = src_r0[2];
-      dst2[1] = src_r0[3];
-      dst2[2] = src_r1[0];
-      dst2[3] = src_r1[1];
-      break;
+    case 6:
+      w3[2] = amd_bytealign_S (    0, w1[3], offset_minus_4);
+      w3[1] = amd_bytealign_S (w1[3], w1[2], offset_minus_4);
+      w3[0] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
+      w2[3] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w2[2] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w2[1] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w2[0] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w1[3] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w1[2] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 25:
-      dst1[2] = src_l1[2]       | src_r0[0] <<  8;
-      dst1[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst2[0] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst2[1] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst2[2] = src_r0[3] >> 24 | src_r1[0] <<  8;
-      dst2[3] = src_r1[0] >> 24 | src_r1[1] <<  8;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w1[2] = w1[3];
+        w1[3] = w2[0];
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 26:
-      dst1[2] = src_l1[2]       | src_r0[0] << 16;
-      dst1[3] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst2[0] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst2[1] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst2[2] = src_r0[3] >> 16 | src_r1[0] << 16;
-      dst2[3] = src_r1[0] >> 16 | src_r1[1] << 16;
       break;
 
-    case 27:
-      dst1[2] = src_l1[2]       | src_r0[0] << 24;
-      dst1[3] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst2[0] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst2[1] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst2[2] = src_r0[3] >>  8 | src_r1[0] << 24;
-      dst2[3] = src_r1[0] >>  8 | src_r1[1] << 24;
-      break;
+    case 7:
+      w3[2] = amd_bytealign_S (    0, w1[2], offset_minus_4);
+      w3[1] = amd_bytealign_S (w1[2], w1[1], offset_minus_4);
+      w3[0] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w2[3] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w2[2] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w2[1] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w2[0] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w1[3] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 28:
-      dst1[3] = src_r1[0];
-      dst2[0] = src_r0[1];
-      dst2[1] = src_r0[2];
-      dst2[2] = src_r0[3];
-      dst2[3] = src_r1[0];
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w1[3] = w2[0];
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 29:
-      dst1[3] = src_l1[3]       | src_r0[0] <<  8;
-      dst2[0] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst2[1] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst2[2] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      dst2[3] = src_r0[3] >> 24 | src_r1[0] <<  8;
       break;
 
-    case 30:
-      dst1[3] = src_l1[3]       | src_r0[0] << 16;
-      dst2[0] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst2[1] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst2[2] = src_r0[2] >> 16 | src_r0[3] << 16;
-      dst2[3] = src_r0[3] >> 16 | src_r1[0] << 16;
-      break;
+    case 8:
+      w3[2] = amd_bytealign_S (    0, w1[1], offset_minus_4);
+      w3[1] = amd_bytealign_S (w1[1], w1[0], offset_minus_4);
+      w3[0] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w2[3] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w2[2] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w2[1] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w2[0] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 31:
-      dst1[3] = src_l1[3]       | src_r0[0] << 24;
-      dst2[0] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst2[1] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst2[2] = src_r0[2] >>  8 | src_r0[3] << 24;
-      dst2[3] = src_r0[3] >>  8 | src_r1[0] << 24;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w2[0] = w2[1];
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 32:
-      dst2[0] = src_r0[0];
-      dst2[1] = src_r0[1];
-      dst2[2] = src_r0[2];
-      dst2[3] = src_r0[3];
       break;
 
-    case 33:
-      dst2[0] = src_l2[0]       | src_r0[0] <<  8;
-      dst2[1] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst2[2] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      dst2[3] = src_r0[2] >> 24 | src_r0[3] <<  8;
-      break;
+    case 9:
+      w3[2] = amd_bytealign_S (    0, w1[0], offset_minus_4);
+      w3[1] = amd_bytealign_S (w1[0], w0[3], offset_minus_4);
+      w3[0] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w2[3] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w2[2] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w2[1] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 34:
-      dst2[0] = src_l2[0]       | src_r0[0] << 16;
-      dst2[1] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst2[2] = src_r0[1] >> 16 | src_r0[2] << 16;
-      dst2[3] = src_r0[2] >> 16 | src_r0[3] << 16;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w2[1] = w2[2];
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 35:
-      dst2[0] = src_l2[0]       | src_r0[0] << 24;
-      dst2[1] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst2[2] = src_r0[1] >>  8 | src_r0[2] << 24;
-      dst2[3] = src_r0[2] >>  8 | src_r0[3] << 24;
       break;
 
-    case 36:
-      dst2[1] = src_r0[0];
-      dst2[2] = src_r0[1];
-      dst2[3] = src_r0[2];
-      break;
+    case 10:
+      w3[2] = amd_bytealign_S (    0, w0[3], offset_minus_4);
+      w3[1] = amd_bytealign_S (w0[3], w0[2], offset_minus_4);
+      w3[0] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w2[3] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w2[2] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 37:
-      dst2[1] = src_l2[1]       | src_r0[0] <<  8;
-      dst2[2] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      dst2[3] = src_r0[1] >> 24 | src_r0[2] <<  8;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w2[2] = w2[3];
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 38:
-      dst2[1] = src_l2[1]       | src_r0[0] << 16;
-      dst2[2] = src_r0[0] >> 16 | src_r0[1] << 16;
-      dst2[3] = src_r0[1] >> 16 | src_r0[2] << 16;
       break;
 
-    case 39:
-      dst2[1] = src_l2[1]       | src_r0[0] << 24;
-      dst2[2] = src_r0[0] >>  8 | src_r0[1] << 24;
-      dst2[3] = src_r0[1] >>  8 | src_r0[2] << 24;
-      break;
+    case 11:
+      w3[2] = amd_bytealign_S (    0, w0[2], offset_minus_4);
+      w3[1] = amd_bytealign_S (w0[2], w0[1], offset_minus_4);
+      w3[0] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w2[3] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 40:
-      dst2[2] = src_r0[0];
-      dst2[3] = src_r0[1];
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w2[3] = w3[0];
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 41:
-      dst2[2] = src_l2[2]       | src_r0[0] <<  8;
-      dst2[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
       break;
 
-    case 42:
-      dst2[2] = src_l2[2]       | src_r0[0] << 16;
-      dst2[3] = src_r0[0] >> 16 | src_r0[1] << 16;
-      break;
+    case 12:
+      w3[2] = amd_bytealign_S (    0, w0[1], offset_minus_4);
+      w3[1] = amd_bytealign_S (w0[1], w0[0], offset_minus_4);
+      w3[0] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w2[3] = 0;
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 43:
-      dst2[2] = src_l2[2]       | src_r0[0] << 24;
-      dst2[3] = src_r0[0] >>  8 | src_r0[1] << 24;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w3[0] = w3[1];
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 44:
-      dst2[3] = src_r0[0];
       break;
 
-    case 45:
-      dst2[3] = src_l2[3]       | src_r0[0] <<  8;
-      break;
+    case 13:
+      w3[2] = amd_bytealign_S (    0, w0[0], offset_minus_4);
+      w3[1] = amd_bytealign_S (w0[0],     0, offset_minus_4);
+      w3[0] = 0;
+      w2[3] = 0;
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 46:
-      dst2[3] = src_l2[3]       | src_r0[0] << 16;
-      break;
+      if (offset_mod_4 == 0)
+      {
+        w3[1] = w3[2];
+        w3[2] = 0;
+      }
 
-    case 47:
-      dst2[3] = src_l2[3]       | src_r0[0] << 24;
       break;
   }
-}
+  #endif
 
-// before: memcat16_9
-static void memcat_c15_w4x4_a3x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 append0[4], const u32 append1[4], const u32 append2[4], const u32 offset)
-{
-  switch (offset)
+  #ifdef IS_NV
+  const int offset_minus_4 = 4 - (offset % 4);
+
+  const int selector = (0x76543210 >> (offset_minus_4 * 4)) & 0xffff;
+
+  switch (offset / 4)
   {
     case 0:
-      w0[0] = append0[0];
-      w0[1] = append0[1];
-      w0[2] = append0[2];
-      w0[3] = append0[3];
-      w1[0] = append1[0];
-      w1[1] = append1[1];
-      w1[2] = append1[2];
-      w1[3] = append1[3];
-      w2[0] = append2[0];
+      w3[1] = __byte_perm_S (w3[0], w3[1], selector);
+      w3[0] = __byte_perm_S (w2[3], w3[0], selector);
+      w2[3] = __byte_perm_S (w2[2], w2[3], selector);
+      w2[2] = __byte_perm_S (w2[1], w2[2], selector);
+      w2[1] = __byte_perm_S (w2[0], w2[1], selector);
+      w2[0] = __byte_perm_S (w1[3], w2[0], selector);
+      w1[3] = __byte_perm_S (w1[2], w1[3], selector);
+      w1[2] = __byte_perm_S (w1[1], w1[2], selector);
+      w1[1] = __byte_perm_S (w1[0], w1[1], selector);
+      w1[0] = __byte_perm_S (w0[3], w1[0], selector);
+      w0[3] = __byte_perm_S (w0[2], w0[3], selector);
+      w0[2] = __byte_perm_S (w0[1], w0[2], selector);
+      w0[1] = __byte_perm_S (w0[0], w0[1], selector);
+      w0[0] = __byte_perm_S (    0, w0[0], selector);
+
       break;
 
     case 1:
-      w0[0] = w0[0]            | append0[0] <<  8;
-      w0[1] = append0[0] >> 24 | append0[1] <<  8;
-      w0[2] = append0[1] >> 24 | append0[2] <<  8;
-      w0[3] = append0[2] >> 24 | append0[3] <<  8;
-      w1[0] = append0[3] >> 24 | append1[0] <<  8;
-      w1[1] = append1[0] >> 24 | append1[1] <<  8;
-      w1[2] = append1[1] >> 24 | append1[2] <<  8;
-      w1[3] = append1[2] >> 24 | append1[3] <<  8;
-      w2[0] = append1[3] >> 24 | append2[0] <<  8;
-      w2[1] = append2[0] >> 24;
+      w3[1] = __byte_perm_S (w2[3], w3[0], selector);
+      w3[0] = __byte_perm_S (w2[2], w2[3], selector);
+      w2[3] = __byte_perm_S (w2[1], w2[2], selector);
+      w2[2] = __byte_perm_S (w2[0], w2[1], selector);
+      w2[1] = __byte_perm_S (w1[3], w2[0], selector);
+      w2[0] = __byte_perm_S (w1[2], w1[3], selector);
+      w1[3] = __byte_perm_S (w1[1], w1[2], selector);
+      w1[2] = __byte_perm_S (w1[0], w1[1], selector);
+      w1[1] = __byte_perm_S (w0[3], w1[0], selector);
+      w1[0] = __byte_perm_S (w0[2], w0[3], selector);
+      w0[3] = __byte_perm_S (w0[1], w0[2], selector);
+      w0[2] = __byte_perm_S (w0[0], w0[1], selector);
+      w0[1] = __byte_perm_S (    0, w0[0], selector);
+      w0[0] = 0;
+
       break;
 
     case 2:
-      w0[0] = w0[0]            | append0[0] << 16;
-      w0[1] = append0[0] >> 16 | append0[1] << 16;
-      w0[2] = append0[1] >> 16 | append0[2] << 16;
-      w0[3] = append0[2] >> 16 | append0[3] << 16;
-      w1[0] = append0[3] >> 16 | append1[0] << 16;
-      w1[1] = append1[0] >> 16 | append1[1] << 16;
-      w1[2] = append1[1] >> 16 | append1[2] << 16;
-      w1[3] = append1[2] >> 16 | append1[3] << 16;
-      w2[0] = append1[3] >> 16 | append2[0] << 16;
-      w2[1] = append2[0] >> 16;
+      w3[1] = __byte_perm_S (w2[2], w2[3], selector);
+      w3[0] = __byte_perm_S (w2[1], w2[2], selector);
+      w2[3] = __byte_perm_S (w2[0], w2[1], selector);
+      w2[2] = __byte_perm_S (w1[3], w2[0], selector);
+      w2[1] = __byte_perm_S (w1[2], w1[3], selector);
+      w2[0] = __byte_perm_S (w1[1], w1[2], selector);
+      w1[3] = __byte_perm_S (w1[0], w1[1], selector);
+      w1[2] = __byte_perm_S (w0[3], w1[0], selector);
+      w1[1] = __byte_perm_S (w0[2], w0[3], selector);
+      w1[0] = __byte_perm_S (w0[1], w0[2], selector);
+      w0[3] = __byte_perm_S (w0[0], w0[1], selector);
+      w0[2] = __byte_perm_S (    0, w0[0], selector);
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 3:
-      w0[0] = w0[0]            | append0[0] << 24;
-      w0[1] = append0[0] >>  8 | append0[1] << 24;
-      w0[2] = append0[1] >>  8 | append0[2] << 24;
-      w0[3] = append0[2] >>  8 | append0[3] << 24;
-      w1[0] = append0[3] >>  8 | append1[0] << 24;
-      w1[1] = append1[0] >>  8 | append1[1] << 24;
-      w1[2] = append1[1] >>  8 | append1[2] << 24;
-      w1[3] = append1[2] >>  8 | append1[3] << 24;
-      w2[0] = append1[3] >>  8 | append2[0] << 24;
-      w2[1] = append2[0] >>  8;
+      w3[1] = __byte_perm_S (w2[1], w2[2], selector);
+      w3[0] = __byte_perm_S (w2[0], w2[1], selector);
+      w2[3] = __byte_perm_S (w1[3], w2[0], selector);
+      w2[2] = __byte_perm_S (w1[2], w1[3], selector);
+      w2[1] = __byte_perm_S (w1[1], w1[2], selector);
+      w2[0] = __byte_perm_S (w1[0], w1[1], selector);
+      w1[3] = __byte_perm_S (w0[3], w1[0], selector);
+      w1[2] = __byte_perm_S (w0[2], w0[3], selector);
+      w1[1] = __byte_perm_S (w0[1], w0[2], selector);
+      w1[0] = __byte_perm_S (w0[0], w0[1], selector);
+      w0[3] = __byte_perm_S (    0, w0[0], selector);
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 4:
-      w0[1] = append0[0];
-      w0[2] = append0[1];
-      w0[3] = append0[2];
-      w1[0] = append0[3];
-      w1[1] = append1[0];
-      w1[2] = append1[1];
-      w1[3] = append1[2];
-      w2[0] = append1[3];
-      w2[1] = append2[0];
+      w3[1] = __byte_perm_S (w2[0], w2[1], selector);
+      w3[0] = __byte_perm_S (w1[3], w2[0], selector);
+      w2[3] = __byte_perm_S (w1[2], w1[3], selector);
+      w2[2] = __byte_perm_S (w1[1], w1[2], selector);
+      w2[1] = __byte_perm_S (w1[0], w1[1], selector);
+      w2[0] = __byte_perm_S (w0[3], w1[0], selector);
+      w1[3] = __byte_perm_S (w0[2], w0[3], selector);
+      w1[2] = __byte_perm_S (w0[1], w0[2], selector);
+      w1[1] = __byte_perm_S (w0[0], w0[1], selector);
+      w1[0] = __byte_perm_S (    0, w0[0], selector);
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 5:
-      w0[1] = w0[1]            | append0[0] <<  8;
-      w0[2] = append0[0] >> 24 | append0[1] <<  8;
-      w0[3] = append0[1] >> 24 | append0[2] <<  8;
-      w1[0] = append0[2] >> 24 | append0[3] <<  8;
-      w1[1] = append0[3] >> 24 | append1[0] <<  8;
-      w1[2] = append1[0] >> 24 | append1[1] <<  8;
-      w1[3] = append1[1] >> 24 | append1[2] <<  8;
-      w2[0] = append1[2] >> 24 | append1[3] <<  8;
-      w2[1] = append1[3] >> 24 | append2[0] <<  8;
-      w2[2] = append2[0] >> 24;
+      w3[1] = __byte_perm_S (w1[3], w2[0], selector);
+      w3[0] = __byte_perm_S (w1[2], w1[3], selector);
+      w2[3] = __byte_perm_S (w1[1], w1[2], selector);
+      w2[2] = __byte_perm_S (w1[0], w1[1], selector);
+      w2[1] = __byte_perm_S (w0[3], w1[0], selector);
+      w2[0] = __byte_perm_S (w0[2], w0[3], selector);
+      w1[3] = __byte_perm_S (w0[1], w0[2], selector);
+      w1[2] = __byte_perm_S (w0[0], w0[1], selector);
+      w1[1] = __byte_perm_S (    0, w0[0], selector);
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 6:
-      w0[1] = w0[1]            | append0[0] << 16;
-      w0[2] = append0[0] >> 16 | append0[1] << 16;
-      w0[3] = append0[1] >> 16 | append0[2] << 16;
-      w1[0] = append0[2] >> 16 | append0[3] << 16;
-      w1[1] = append0[3] >> 16 | append1[0] << 16;
-      w1[2] = append1[0] >> 16 | append1[1] << 16;
-      w1[3] = append1[1] >> 16 | append1[2] << 16;
-      w2[0] = append1[2] >> 16 | append1[3] << 16;
-      w2[1] = append1[3] >> 16 | append2[0] << 16;
-      w2[2] = append2[0] >> 16;
+      w3[1] = __byte_perm_S (w1[2], w1[3], selector);
+      w3[0] = __byte_perm_S (w1[1], w1[2], selector);
+      w2[3] = __byte_perm_S (w1[0], w1[1], selector);
+      w2[2] = __byte_perm_S (w0[3], w1[0], selector);
+      w2[1] = __byte_perm_S (w0[2], w0[3], selector);
+      w2[0] = __byte_perm_S (w0[1], w0[2], selector);
+      w1[3] = __byte_perm_S (w0[0], w0[1], selector);
+      w1[2] = __byte_perm_S (    0, w0[0], selector);
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 7:
-      w0[1] = w0[1]            | append0[0] << 24;
-      w0[2] = append0[0] >>  8 | append0[1] << 24;
-      w0[3] = append0[1] >>  8 | append0[2] << 24;
-      w1[0] = append0[2] >>  8 | append0[3] << 24;
-      w1[1] = append0[3] >>  8 | append1[0] << 24;
-      w1[2] = append1[0] >>  8 | append1[1] << 24;
-      w1[3] = append1[1] >>  8 | append1[2] << 24;
-      w2[0] = append1[2] >>  8 | append1[3] << 24;
-      w2[1] = append1[3] >>  8 | append2[0] << 24;
-      w2[2] = append2[0] >>  8;
+      w3[1] = __byte_perm_S (w1[1], w1[2], selector);
+      w3[0] = __byte_perm_S (w1[0], w1[1], selector);
+      w2[3] = __byte_perm_S (w0[3], w1[0], selector);
+      w2[2] = __byte_perm_S (w0[2], w0[3], selector);
+      w2[1] = __byte_perm_S (w0[1], w0[2], selector);
+      w2[0] = __byte_perm_S (w0[0], w0[1], selector);
+      w1[3] = __byte_perm_S (    0, w0[0], selector);
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 8:
-      w0[2] = append0[0];
-      w0[3] = append0[1];
-      w1[0] = append0[2];
-      w1[1] = append0[3];
-      w1[2] = append1[0];
-      w1[3] = append1[1];
-      w2[0] = append1[2];
-      w2[1] = append1[3];
-      w2[2] = append2[0];
+      w3[1] = __byte_perm_S (w1[0], w1[1], selector);
+      w3[0] = __byte_perm_S (w0[3], w1[0], selector);
+      w2[3] = __byte_perm_S (w0[2], w0[3], selector);
+      w2[2] = __byte_perm_S (w0[1], w0[2], selector);
+      w2[1] = __byte_perm_S (w0[0], w0[1], selector);
+      w2[0] = __byte_perm_S (    0, w0[0], selector);
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 9:
-      w0[2] = w0[2]            | append0[0] <<  8;
-      w0[3] = append0[0] >> 24 | append0[1] <<  8;
-      w1[0] = append0[1] >> 24 | append0[2] <<  8;
-      w1[1] = append0[2] >> 24 | append0[3] <<  8;
-      w1[2] = append0[3] >> 24 | append1[0] <<  8;
-      w1[3] = append1[0] >> 24 | append1[1] <<  8;
-      w2[0] = append1[1] >> 24 | append1[2] <<  8;
-      w2[1] = append1[2] >> 24 | append1[3] <<  8;
-      w2[2] = append1[3] >> 24 | append2[0] <<  8;
-      w2[3] = append2[0] >> 24;
+      w3[1] = __byte_perm_S (w0[3], w1[0], selector);
+      w3[0] = __byte_perm_S (w0[2], w0[3], selector);
+      w2[3] = __byte_perm_S (w0[1], w0[2], selector);
+      w2[2] = __byte_perm_S (w0[0], w0[1], selector);
+      w2[1] = __byte_perm_S (    0, w0[0], selector);
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 10:
-      w0[2] = w0[2]            | append0[0] << 16;
-      w0[3] = append0[0] >> 16 | append0[1] << 16;
-      w1[0] = append0[1] >> 16 | append0[2] << 16;
-      w1[1] = append0[2] >> 16 | append0[3] << 16;
-      w1[2] = append0[3] >> 16 | append1[0] << 16;
-      w1[3] = append1[0] >> 16 | append1[1] << 16;
-      w2[0] = append1[1] >> 16 | append1[2] << 16;
-      w2[1] = append1[2] >> 16 | append1[3] << 16;
-      w2[2] = append1[3] >> 16 | append2[0] << 16;
-      w2[3] = append2[0] >> 16;
+      w3[1] = __byte_perm_S (w0[2], w0[3], selector);
+      w3[0] = __byte_perm_S (w0[1], w0[2], selector);
+      w2[3] = __byte_perm_S (w0[0], w0[1], selector);
+      w2[2] = __byte_perm_S (    0, w0[0], selector);
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 11:
-      w0[2] = w0[2]            | append0[0] << 24;
-      w0[3] = append0[0] >>  8 | append0[1] << 24;
-      w1[0] = append0[1] >>  8 | append0[2] << 24;
-      w1[1] = append0[2] >>  8 | append0[3] << 24;
-      w1[2] = append0[3] >>  8 | append1[0] << 24;
-      w1[3] = append1[0] >>  8 | append1[1] << 24;
-      w2[0] = append1[1] >>  8 | append1[2] << 24;
-      w2[1] = append1[2] >>  8 | append1[3] << 24;
-      w2[2] = append1[3] >>  8 | append2[0] << 24;
-      w2[3] = append2[0] >>  8;
+      w3[1] = __byte_perm_S (w0[1], w0[2], selector);
+      w3[0] = __byte_perm_S (w0[0], w0[1], selector);
+      w2[3] = __byte_perm_S (    0, w0[0], selector);
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
+
       break;
 
     case 12:
-      w0[3] = append0[0];
-      w1[0] = append0[1];
-      w1[1] = append0[2];
-      w1[2] = append0[3];
-      w1[3] = append1[0];
-      w2[0] = append1[1];
-      w2[1] = append1[2];
-      w2[2] = append1[3];
-      w2[3] = append2[0];
-      break;
+      w3[1] = __byte_perm_S (w0[0], w0[1], selector);
+      w3[0] = __byte_perm_S (    0, w0[0], selector);
+      w2[3] = 0;
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 13:
-      w0[3] = w0[3]            | append0[0] <<  8;
-      w1[0] = append0[0] >> 24 | append0[1] <<  8;
-      w1[1] = append0[1] >> 24 | append0[2] <<  8;
-      w1[2] = append0[2] >> 24 | append0[3] <<  8;
-      w1[3] = append0[3] >> 24 | append1[0] <<  8;
-      w2[0] = append1[0] >> 24 | append1[1] <<  8;
-      w2[1] = append1[1] >> 24 | append1[2] <<  8;
-      w2[2] = append1[2] >> 24 | append1[3] <<  8;
-      w2[3] = append1[3] >> 24 | append2[0] <<  8;
-      w3[0] = append2[0] >> 24;
       break;
 
-    case 14:
-      w0[3] = w0[3]            | append0[0] << 16;
-      w1[0] = append0[0] >> 16 | append0[1] << 16;
-      w1[1] = append0[1] >> 16 | append0[2] << 16;
-      w1[2] = append0[2] >> 16 | append0[3] << 16;
-      w1[3] = append0[3] >> 16 | append1[0] << 16;
-      w2[0] = append1[0] >> 16 | append1[1] << 16;
-      w2[1] = append1[1] >> 16 | append1[2] << 16;
-      w2[2] = append1[2] >> 16 | append1[3] << 16;
-      w2[3] = append1[3] >> 16 | append2[0] << 16;
-      w3[0] = append2[0] >> 16;
-      break;
+    case 13:
+      w3[1] = __byte_perm_S (    0, w0[0], selector);
+      w3[0] = 0;
+      w2[3] = 0;
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
 
-    case 15:
-      w0[3] = w0[3]            | append0[0] << 24;
-      w1[0] = append0[0] >>  8 | append0[1] << 24;
-      w1[1] = append0[1] >>  8 | append0[2] << 24;
-      w1[2] = append0[2] >>  8 | append0[3] << 24;
-      w1[3] = append0[3] >>  8 | append1[0] << 24;
-      w2[0] = append1[0] >>  8 | append1[1] << 24;
-      w2[1] = append1[1] >>  8 | append1[2] << 24;
-      w2[2] = append1[2] >>  8 | append1[3] << 24;
-      w2[3] = append1[3] >>  8 | append2[0] << 24;
-      w3[0] = append2[0] >>  8;
       break;
   }
+  #endif
 }
 
-// before: memcat32_8
-static void memcat_c32_w4x4_a2x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 append0[4], const u32 append1[4], const u32 offset)
+inline void switch_buffer_by_offset_be_S (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 offset)
 {
-  switch (offset)
+  #if defined IS_AMD || defined IS_GENERIC
+  switch (offset / 4)
   {
     case 0:
-      w0[0] = append0[0];
-      w0[1] = append0[1];
-      w0[2] = append0[2];
-      w0[3] = append0[3];
-      w1[0] = append1[0];
-      w1[1] = append1[1];
-      w1[2] = append1[2];
-      w1[3] = append1[3];
+      w3[2] = amd_bytealign_S (w3[1],     0, offset);
+      w3[1] = amd_bytealign_S (w3[0], w3[1], offset);
+      w3[0] = amd_bytealign_S (w2[3], w3[0], offset);
+      w2[3] = amd_bytealign_S (w2[2], w2[3], offset);
+      w2[2] = amd_bytealign_S (w2[1], w2[2], offset);
+      w2[1] = amd_bytealign_S (w2[0], w2[1], offset);
+      w2[0] = amd_bytealign_S (w1[3], w2[0], offset);
+      w1[3] = amd_bytealign_S (w1[2], w1[3], offset);
+      w1[2] = amd_bytealign_S (w1[1], w1[2], offset);
+      w1[1] = amd_bytealign_S (w1[0], w1[1], offset);
+      w1[0] = amd_bytealign_S (w0[3], w1[0], offset);
+      w0[3] = amd_bytealign_S (w0[2], w0[3], offset);
+      w0[2] = amd_bytealign_S (w0[1], w0[2], offset);
+      w0[1] = amd_bytealign_S (w0[0], w0[1], offset);
+      w0[0] = amd_bytealign_S (    0, w0[0], offset);
       break;
 
     case 1:
-      w0[0] = w0[0]            | append0[0] <<  8;
-      w0[1] = append0[0] >> 24 | append0[1] <<  8;
-      w0[2] = append0[1] >> 24 | append0[2] <<  8;
-      w0[3] = append0[2] >> 24 | append0[3] <<  8;
-      w1[0] = append0[3] >> 24 | append1[0] <<  8;
-      w1[1] = append1[0] >> 24 | append1[1] <<  8;
-      w1[2] = append1[1] >> 24 | append1[2] <<  8;
-      w1[3] = append1[2] >> 24 | append1[3] <<  8;
-      w2[0] = append1[3] >> 24;
+      w3[2] = amd_bytealign_S (w3[0],     0, offset);
+      w3[1] = amd_bytealign_S (w2[3], w3[0], offset);
+      w3[0] = amd_bytealign_S (w2[2], w2[3], offset);
+      w2[3] = amd_bytealign_S (w2[1], w2[2], offset);
+      w2[2] = amd_bytealign_S (w2[0], w2[1], offset);
+      w2[1] = amd_bytealign_S (w1[3], w2[0], offset);
+      w2[0] = amd_bytealign_S (w1[2], w1[3], offset);
+      w1[3] = amd_bytealign_S (w1[1], w1[2], offset);
+      w1[2] = amd_bytealign_S (w1[0], w1[1], offset);
+      w1[1] = amd_bytealign_S (w0[3], w1[0], offset);
+      w1[0] = amd_bytealign_S (w0[2], w0[3], offset);
+      w0[3] = amd_bytealign_S (w0[1], w0[2], offset);
+      w0[2] = amd_bytealign_S (w0[0], w0[1], offset);
+      w0[1] = amd_bytealign_S (    0, w0[0], offset);
+      w0[0] = 0;
       break;
 
     case 2:
-      w0[0] = w0[0]            | append0[0] << 16;
-      w0[1] = append0[0] >> 16 | append0[1] << 16;
-      w0[2] = append0[1] >> 16 | append0[2] << 16;
-      w0[3] = append0[2] >> 16 | append0[3] << 16;
-      w1[0] = append0[3] >> 16 | append1[0] << 16;
-      w1[1] = append1[0] >> 16 | append1[1] << 16;
-      w1[2] = append1[1] >> 16 | append1[2] << 16;
-      w1[3] = append1[2] >> 16 | append1[3] << 16;
-      w2[0] = append1[3] >> 16;
+      w3[2] = amd_bytealign_S (w2[3],     0, offset);
+      w3[1] = amd_bytealign_S (w2[2], w2[3], offset);
+      w3[0] = amd_bytealign_S (w2[1], w2[2], offset);
+      w2[3] = amd_bytealign_S (w2[0], w2[1], offset);
+      w2[2] = amd_bytealign_S (w1[3], w2[0], offset);
+      w2[1] = amd_bytealign_S (w1[2], w1[3], offset);
+      w2[0] = amd_bytealign_S (w1[1], w1[2], offset);
+      w1[3] = amd_bytealign_S (w1[0], w1[1], offset);
+      w1[2] = amd_bytealign_S (w0[3], w1[0], offset);
+      w1[1] = amd_bytealign_S (w0[2], w0[3], offset);
+      w1[0] = amd_bytealign_S (w0[1], w0[2], offset);
+      w0[3] = amd_bytealign_S (w0[0], w0[1], offset);
+      w0[2] = amd_bytealign_S (    0, w0[0], offset);
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 3:
-      w0[0] = w0[0]            | append0[0] << 24;
-      w0[1] = append0[0] >>  8 | append0[1] << 24;
-      w0[2] = append0[1] >>  8 | append0[2] << 24;
-      w0[3] = append0[2] >>  8 | append0[3] << 24;
-      w1[0] = append0[3] >>  8 | append1[0] << 24;
-      w1[1] = append1[0] >>  8 | append1[1] << 24;
-      w1[2] = append1[1] >>  8 | append1[2] << 24;
-      w1[3] = append1[2] >>  8 | append1[3] << 24;
-      w2[0] = append1[3] >>  8;
+      w3[2] = amd_bytealign_S (w2[2],     0, offset);
+      w3[1] = amd_bytealign_S (w2[1], w2[2], offset);
+      w3[0] = amd_bytealign_S (w2[0], w2[1], offset);
+      w2[3] = amd_bytealign_S (w1[3], w2[0], offset);
+      w2[2] = amd_bytealign_S (w1[2], w1[3], offset);
+      w2[1] = amd_bytealign_S (w1[1], w1[2], offset);
+      w2[0] = amd_bytealign_S (w1[0], w1[1], offset);
+      w1[3] = amd_bytealign_S (w0[3], w1[0], offset);
+      w1[2] = amd_bytealign_S (w0[2], w0[3], offset);
+      w1[1] = amd_bytealign_S (w0[1], w0[2], offset);
+      w1[0] = amd_bytealign_S (w0[0], w0[1], offset);
+      w0[3] = amd_bytealign_S (    0, w0[0], offset);
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 4:
-      w0[1] = append0[0];
-      w0[2] = append0[1];
-      w0[3] = append0[2];
-      w1[0] = append0[3];
-      w1[1] = append1[0];
-      w1[2] = append1[1];
-      w1[3] = append1[2];
-      w2[0] = append1[3];
+      w3[2] = amd_bytealign_S (w2[1],     0, offset);
+      w3[1] = amd_bytealign_S (w2[0], w2[1], offset);
+      w3[0] = amd_bytealign_S (w1[3], w2[0], offset);
+      w2[3] = amd_bytealign_S (w1[2], w1[3], offset);
+      w2[2] = amd_bytealign_S (w1[1], w1[2], offset);
+      w2[1] = amd_bytealign_S (w1[0], w1[1], offset);
+      w2[0] = amd_bytealign_S (w0[3], w1[0], offset);
+      w1[3] = amd_bytealign_S (w0[2], w0[3], offset);
+      w1[2] = amd_bytealign_S (w0[1], w0[2], offset);
+      w1[1] = amd_bytealign_S (w0[0], w0[1], offset);
+      w1[0] = amd_bytealign_S (    0, w0[0], offset);
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 5:
-      w0[1] = w0[1]            | append0[0] <<  8;
-      w0[2] = append0[0] >> 24 | append0[1] <<  8;
-      w0[3] = append0[1] >> 24 | append0[2] <<  8;
-      w1[0] = append0[2] >> 24 | append0[3] <<  8;
-      w1[1] = append0[3] >> 24 | append1[0] <<  8;
-      w1[2] = append1[0] >> 24 | append1[1] <<  8;
-      w1[3] = append1[1] >> 24 | append1[2] <<  8;
-      w2[0] = append1[2] >> 24 | append1[3] <<  8;
-      w2[1] = append1[3] >> 24;
+      w3[2] = amd_bytealign_S (w2[0],     0, offset);
+      w3[1] = amd_bytealign_S (w1[3], w2[0], offset);
+      w3[0] = amd_bytealign_S (w1[2], w1[3], offset);
+      w2[3] = amd_bytealign_S (w1[1], w1[2], offset);
+      w2[2] = amd_bytealign_S (w1[0], w1[1], offset);
+      w2[1] = amd_bytealign_S (w0[3], w1[0], offset);
+      w2[0] = amd_bytealign_S (w0[2], w0[3], offset);
+      w1[3] = amd_bytealign_S (w0[1], w0[2], offset);
+      w1[2] = amd_bytealign_S (w0[0], w0[1], offset);
+      w1[1] = amd_bytealign_S (    0, w0[0], offset);
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 6:
-      w0[1] = w0[1]            | append0[0] << 16;
-      w0[2] = append0[0] >> 16 | append0[1] << 16;
-      w0[3] = append0[1] >> 16 | append0[2] << 16;
-      w1[0] = append0[2] >> 16 | append0[3] << 16;
-      w1[1] = append0[3] >> 16 | append1[0] << 16;
-      w1[2] = append1[0] >> 16 | append1[1] << 16;
-      w1[3] = append1[1] >> 16 | append1[2] << 16;
-      w2[0] = append1[2] >> 16 | append1[3] << 16;
-      w2[1] = append1[3] >> 16;
+      w3[2] = amd_bytealign_S (w1[3],     0, offset);
+      w3[1] = amd_bytealign_S (w1[2], w1[3], offset);
+      w3[0] = amd_bytealign_S (w1[1], w1[2], offset);
+      w2[3] = amd_bytealign_S (w1[0], w1[1], offset);
+      w2[2] = amd_bytealign_S (w0[3], w1[0], offset);
+      w2[1] = amd_bytealign_S (w0[2], w0[3], offset);
+      w2[0] = amd_bytealign_S (w0[1], w0[2], offset);
+      w1[3] = amd_bytealign_S (w0[0], w0[1], offset);
+      w1[2] = amd_bytealign_S (    0, w0[0], offset);
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 7:
-      w0[1] = w0[1]            | append0[0] << 24;
-      w0[2] = append0[0] >>  8 | append0[1] << 24;
-      w0[3] = append0[1] >>  8 | append0[2] << 24;
-      w1[0] = append0[2] >>  8 | append0[3] << 24;
-      w1[1] = append0[3] >>  8 | append1[0] << 24;
-      w1[2] = append1[0] >>  8 | append1[1] << 24;
-      w1[3] = append1[1] >>  8 | append1[2] << 24;
-      w2[0] = append1[2] >>  8 | append1[3] << 24;
-      w2[1] = append1[3] >>  8;
+      w3[2] = amd_bytealign_S (w1[2],     0, offset);
+      w3[1] = amd_bytealign_S (w1[1], w1[2], offset);
+      w3[0] = amd_bytealign_S (w1[0], w1[1], offset);
+      w2[3] = amd_bytealign_S (w0[3], w1[0], offset);
+      w2[2] = amd_bytealign_S (w0[2], w0[3], offset);
+      w2[1] = amd_bytealign_S (w0[1], w0[2], offset);
+      w2[0] = amd_bytealign_S (w0[0], w0[1], offset);
+      w1[3] = amd_bytealign_S (    0, w0[0], offset);
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 8:
-      w0[2] = append0[0];
-      w0[3] = append0[1];
-      w1[0] = append0[2];
-      w1[1] = append0[3];
-      w1[2] = append1[0];
-      w1[3] = append1[1];
-      w2[0] = append1[2];
-      w2[1] = append1[3];
+      w3[2] = amd_bytealign_S (w1[1],     0, offset);
+      w3[1] = amd_bytealign_S (w1[0], w1[1], offset);
+      w3[0] = amd_bytealign_S (w0[3], w1[0], offset);
+      w2[3] = amd_bytealign_S (w0[2], w0[3], offset);
+      w2[2] = amd_bytealign_S (w0[1], w0[2], offset);
+      w2[1] = amd_bytealign_S (w0[0], w0[1], offset);
+      w2[0] = amd_bytealign_S (    0, w0[0], offset);
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 9:
-      w0[2] = w0[2]            | append0[0] <<  8;
-      w0[3] = append0[0] >> 24 | append0[1] <<  8;
-      w1[0] = append0[1] >> 24 | append0[2] <<  8;
-      w1[1] = append0[2] >> 24 | append0[3] <<  8;
-      w1[2] = append0[3] >> 24 | append1[0] <<  8;
-      w1[3] = append1[0] >> 24 | append1[1] <<  8;
-      w2[0] = append1[1] >> 24 | append1[2] <<  8;
-      w2[1] = append1[2] >> 24 | append1[3] <<  8;
-      w2[2] = append1[3] >> 24;
+      w3[2] = amd_bytealign_S (w1[0],     0, offset);
+      w3[1] = amd_bytealign_S (w0[3], w1[0], offset);
+      w3[0] = amd_bytealign_S (w0[2], w0[3], offset);
+      w2[3] = amd_bytealign_S (w0[1], w0[2], offset);
+      w2[2] = amd_bytealign_S (w0[0], w0[1], offset);
+      w2[1] = amd_bytealign_S (    0, w0[0], offset);
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 10:
-      w0[2] = w0[2]            | append0[0] << 16;
-      w0[3] = append0[0] >> 16 | append0[1] << 16;
-      w1[0] = append0[1] >> 16 | append0[2] << 16;
-      w1[1] = append0[2] >> 16 | append0[3] << 16;
-      w1[2] = append0[3] >> 16 | append1[0] << 16;
-      w1[3] = append1[0] >> 16 | append1[1] << 16;
-      w2[0] = append1[1] >> 16 | append1[2] << 16;
-      w2[1] = append1[2] >> 16 | append1[3] << 16;
-      w2[2] = append1[3] >> 16;
+      w3[2] = amd_bytealign_S (w0[3],     0, offset);
+      w3[1] = amd_bytealign_S (w0[2], w0[3], offset);
+      w3[0] = amd_bytealign_S (w0[1], w0[2], offset);
+      w2[3] = amd_bytealign_S (w0[0], w0[1], offset);
+      w2[2] = amd_bytealign_S (    0, w0[0], offset);
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 11:
-      w0[2] = w0[2]            | append0[0] << 24;
-      w0[3] = append0[0] >>  8 | append0[1] << 24;
-      w1[0] = append0[1] >>  8 | append0[2] << 24;
-      w1[1] = append0[2] >>  8 | append0[3] << 24;
-      w1[2] = append0[3] >>  8 | append1[0] << 24;
-      w1[3] = append1[0] >>  8 | append1[1] << 24;
-      w2[0] = append1[1] >>  8 | append1[2] << 24;
-      w2[1] = append1[2] >>  8 | append1[3] << 24;
-      w2[2] = append1[3] >>  8;
+      w3[2] = amd_bytealign_S (w0[2],     0, offset);
+      w3[1] = amd_bytealign_S (w0[1], w0[2], offset);
+      w3[0] = amd_bytealign_S (w0[0], w0[1], offset);
+      w2[3] = amd_bytealign_S (    0, w0[0], offset);
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 12:
-      w0[3] = append0[0];
-      w1[0] = append0[1];
-      w1[1] = append0[2];
-      w1[2] = append0[3];
-      w1[3] = append1[0];
-      w2[0] = append1[1];
-      w2[1] = append1[2];
-      w2[2] = append1[3];
+      w3[2] = amd_bytealign_S (w0[1],     0, offset);
+      w3[1] = amd_bytealign_S (w0[0], w0[1], offset);
+      w3[0] = amd_bytealign_S (    0, w0[0], offset);
+      w2[3] = 0;
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 13:
-      w0[3] = w0[3]            | append0[0] <<  8;
-      w1[0] = append0[0] >> 24 | append0[1] <<  8;
-      w1[1] = append0[1] >> 24 | append0[2] <<  8;
-      w1[2] = append0[2] >> 24 | append0[3] <<  8;
-      w1[3] = append0[3] >> 24 | append1[0] <<  8;
-      w2[0] = append1[0] >> 24 | append1[1] <<  8;
-      w2[1] = append1[1] >> 24 | append1[2] <<  8;
-      w2[2] = append1[2] >> 24 | append1[3] <<  8;
-      w2[3] = append1[3] >> 24;
-      break;
-
-    case 14:
-      w0[3] = w0[3]            | append0[0] << 16;
-      w1[0] = append0[0] >> 16 | append0[1] << 16;
-      w1[1] = append0[1] >> 16 | append0[2] << 16;
-      w1[2] = append0[2] >> 16 | append0[3] << 16;
-      w1[3] = append0[3] >> 16 | append1[0] << 16;
-      w2[0] = append1[0] >> 16 | append1[1] << 16;
-      w2[1] = append1[1] >> 16 | append1[2] << 16;
-      w2[2] = append1[2] >> 16 | append1[3] << 16;
-      w2[3] = append1[3] >> 16;
-      break;
-
-    case 15:
-      w0[3] = w0[3]            | append0[0] << 24;
-      w1[0] = append0[0] >>  8 | append0[1] << 24;
-      w1[1] = append0[1] >>  8 | append0[2] << 24;
-      w1[2] = append0[2] >>  8 | append0[3] << 24;
-      w1[3] = append0[3] >>  8 | append1[0] << 24;
-      w2[0] = append1[0] >>  8 | append1[1] << 24;
-      w2[1] = append1[1] >>  8 | append1[2] << 24;
-      w2[2] = append1[2] >>  8 | append1[3] << 24;
-      w2[3] = append1[3] >>  8;
-      break;
-
-    case 16:
-      w1[0] = append0[0];
-      w1[1] = append0[1];
-      w1[2] = append0[2];
-      w1[3] = append0[3];
-      w2[0] = append1[0];
-      w2[1] = append1[1];
-      w2[2] = append1[2];
-      w2[3] = append1[3];
-      break;
-
-    case 17:
-      w1[0] = w1[0]            | append0[0] <<  8;
-      w1[1] = append0[0] >> 24 | append0[1] <<  8;
-      w1[2] = append0[1] >> 24 | append0[2] <<  8;
-      w1[3] = append0[2] >> 24 | append0[3] <<  8;
-      w2[0] = append0[3] >> 24 | append1[0] <<  8;
-      w2[1] = append1[0] >> 24 | append1[1] <<  8;
-      w2[2] = append1[1] >> 24 | append1[2] <<  8;
-      w2[3] = append1[2] >> 24 | append1[3] <<  8;
-      w3[0] = append1[3] >> 24;
-      break;
-
-    case 18:
-      w1[0] = w1[0]            | append0[0] << 16;
-      w1[1] = append0[0] >> 16 | append0[1] << 16;
-      w1[2] = append0[1] >> 16 | append0[2] << 16;
-      w1[3] = append0[2] >> 16 | append0[3] << 16;
-      w2[0] = append0[3] >> 16 | append1[0] << 16;
-      w2[1] = append1[0] >> 16 | append1[1] << 16;
-      w2[2] = append1[1] >> 16 | append1[2] << 16;
-      w2[3] = append1[2] >> 16 | append1[3] << 16;
-      w3[0] = append1[3] >> 16;
-      break;
-
-    case 19:
-      w1[0] = w1[0]            | append0[0] << 24;
-      w1[1] = append0[0] >>  8 | append0[1] << 24;
-      w1[2] = append0[1] >>  8 | append0[2] << 24;
-      w1[3] = append0[2] >>  8 | append0[3] << 24;
-      w2[0] = append0[3] >>  8 | append1[0] << 24;
-      w2[1] = append1[0] >>  8 | append1[1] << 24;
-      w2[2] = append1[1] >>  8 | append1[2] << 24;
-      w2[3] = append1[2] >>  8 | append1[3] << 24;
-      w3[0] = append1[3] >>  8;
-      break;
-
-    case 20:
-      w1[1] = append0[0];
-      w1[2] = append0[1];
-      w1[3] = append0[2];
-      w2[0] = append0[3];
-      w2[1] = append1[0];
-      w2[2] = append1[1];
-      w2[3] = append1[2];
-      w3[0] = append1[3];
-      break;
-
-    case 21:
-      w1[1] = w1[1]            | append0[0] <<  8;
-      w1[2] = append0[0] >> 24 | append0[1] <<  8;
-      w1[3] = append0[1] >> 24 | append0[2] <<  8;
-      w2[0] = append0[2] >> 24 | append0[3] <<  8;
-      w2[1] = append0[3] >> 24 | append1[0] <<  8;
-      w2[2] = append1[0] >> 24 | append1[1] <<  8;
-      w2[3] = append1[1] >> 24 | append1[2] <<  8;
-      w3[0] = append1[2] >> 24 | append1[3] <<  8;
-      w3[1] = append1[3] >> 24;
-      break;
-
-    case 22:
-      w1[1] = w1[1]            | append0[0] << 16;
-      w1[2] = append0[0] >> 16 | append0[1] << 16;
-      w1[3] = append0[1] >> 16 | append0[2] << 16;
-      w2[0] = append0[2] >> 16 | append0[3] << 16;
-      w2[1] = append0[3] >> 16 | append1[0] << 16;
-      w2[2] = append1[0] >> 16 | append1[1] << 16;
-      w2[3] = append1[1] >> 16 | append1[2] << 16;
-      w3[0] = append1[2] >> 16 | append1[3] << 16;
-      w3[1] = append1[3] >> 16;
-      break;
-
-    case 23:
-      w1[1] = w1[1]            | append0[0] << 24;
-      w1[2] = append0[0] >>  8 | append0[1] << 24;
-      w1[3] = append0[1] >>  8 | append0[2] << 24;
-      w2[0] = append0[2] >>  8 | append0[3] << 24;
-      w2[1] = append0[3] >>  8 | append1[0] << 24;
-      w2[2] = append1[0] >>  8 | append1[1] << 24;
-      w2[3] = append1[1] >>  8 | append1[2] << 24;
-      w3[0] = append1[2] >>  8 | append1[3] << 24;
-      w3[1] = append1[3] >>  8;
-      break;
-
-    case 24:
-      w1[2] = append0[0];
-      w1[3] = append0[1];
-      w2[0] = append0[2];
-      w2[1] = append0[3];
-      w2[2] = append1[0];
-      w2[3] = append1[1];
-      w3[0] = append1[2];
-      w3[1] = append1[3];
-      break;
-
-    case 25:
-      w1[2] = w1[2]            | append0[0] <<  8;
-      w1[3] = append0[0] >> 24 | append0[1] <<  8;
-      w2[0] = append0[1] >> 24 | append0[2] <<  8;
-      w2[1] = append0[2] >> 24 | append0[3] <<  8;
-      w2[2] = append0[3] >> 24 | append1[0] <<  8;
-      w2[3] = append1[0] >> 24 | append1[1] <<  8;
-      w3[0] = append1[1] >> 24 | append1[2] <<  8;
-      w3[1] = append1[2] >> 24 | append1[3] <<  8;
-      break;
-
-    case 26:
-      w1[2] = w1[2]            | append0[0] << 16;
-      w1[3] = append0[0] >> 16 | append0[1] << 16;
-      w2[0] = append0[1] >> 16 | append0[2] << 16;
-      w2[1] = append0[2] >> 16 | append0[3] << 16;
-      w2[2] = append0[3] >> 16 | append1[0] << 16;
-      w2[3] = append1[0] >> 16 | append1[1] << 16;
-      w3[0] = append1[1] >> 16 | append1[2] << 16;
-      w3[1] = append1[2] >> 16 | append1[3] << 16;
-      break;
-
-    case 27:
-      w1[2] = w1[2]            | append0[0] << 24;
-      w1[3] = append0[0] >>  8 | append0[1] << 24;
-      w2[0] = append0[1] >>  8 | append0[2] << 24;
-      w2[1] = append0[2] >>  8 | append0[3] << 24;
-      w2[2] = append0[3] >>  8 | append1[0] << 24;
-      w2[3] = append1[0] >>  8 | append1[1] << 24;
-      w3[0] = append1[1] >>  8 | append1[2] << 24;
-      w3[1] = append1[2] >>  8 | append1[3] << 24;
-      break;
-
-    case 28:
-      w1[3] = append0[0];
-      w2[0] = append0[1];
-      w2[1] = append0[2];
-      w2[2] = append0[3];
-      w2[3] = append1[0];
-      w3[0] = append1[1];
-      w3[1] = append1[2];
-      break;
-
-    case 29:
-      w1[3] = w1[3]            | append0[0] <<  8;
-      w2[0] = append0[0] >> 24 | append0[1] <<  8;
-      w2[1] = append0[1] >> 24 | append0[2] <<  8;
-      w2[2] = append0[2] >> 24 | append0[3] <<  8;
-      w2[3] = append0[3] >> 24 | append1[0] <<  8;
-      w3[0] = append1[0] >> 24 | append1[1] <<  8;
-      w3[1] = append1[1] >> 24 | append1[2] <<  8;
-      break;
-
-    case 30:
-      w1[3] = w1[3]            | append0[0] << 16;
-      w2[0] = append0[0] >> 16 | append0[1] << 16;
-      w2[1] = append0[1] >> 16 | append0[2] << 16;
-      w2[2] = append0[2] >> 16 | append0[3] << 16;
-      w2[3] = append0[3] >> 16 | append1[0] << 16;
-      w3[0] = append1[0] >> 16 | append1[1] << 16;
-      w3[1] = append1[1] >> 16 | append1[2] << 16;
-      break;
-
-    case 31:
-      w1[3] = w1[3]            | append0[0] << 24;
-      w2[0] = append0[0] >>  8 | append0[1] << 24;
-      w2[1] = append0[1] >>  8 | append0[2] << 24;
-      w2[2] = append0[2] >>  8 | append0[3] << 24;
-      w2[3] = append0[3] >>  8 | append1[0] << 24;
-      w3[0] = append1[0] >>  8 | append1[1] << 24;
-      w3[1] = append1[1] >>  8 | append1[2] << 24;
-      break;
-
-    case 32:
-      w2[0] = append0[0];
-      w2[1] = append0[1];
-      w2[2] = append0[2];
-      w2[3] = append0[3];
-      w3[0] = append1[0];
-      w3[1] = append1[1];
+      w3[2] = amd_bytealign_S (w0[0],     0, offset);
+      w3[1] = amd_bytealign_S (    0, w0[0], offset);
+      w3[0] = 0;
+      w2[3] = 0;
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
   }
-}
+  #endif
 
-// before: memcat32_9
-static void memcat_c32_w4x4_a3x4 (u32 w0[4], u32 w1[4], u32 w2[4], u32 w3[4], const u32 append0[4], const u32 append1[4], const u32 append2[4], const u32 offset)
-{
-  switch (offset)
+  #ifdef IS_NV
+  const int selector = (0x76543210 >> ((offset & 3) * 4)) & 0xffff;
+
+  switch (offset / 4)
   {
     case 0:
-      w0[0] = append0[0];
-      w0[1] = append0[1];
-      w0[2] = append0[2];
-      w0[3] = append0[3];
-      w1[0] = append1[0];
-      w1[1] = append1[1];
-      w1[2] = append1[2];
-      w1[3] = append1[3];
-      w2[0] = append2[0];
+      w3[1] = __byte_perm_S (w3[1], w3[0], selector);
+      w3[0] = __byte_perm_S (w3[0], w2[3], selector);
+      w2[3] = __byte_perm_S (w2[3], w2[2], selector);
+      w2[2] = __byte_perm_S (w2[2], w2[1], selector);
+      w2[1] = __byte_perm_S (w2[1], w2[0], selector);
+      w2[0] = __byte_perm_S (w2[0], w1[3], selector);
+      w1[3] = __byte_perm_S (w1[3], w1[2], selector);
+      w1[2] = __byte_perm_S (w1[2], w1[1], selector);
+      w1[1] = __byte_perm_S (w1[1], w1[0], selector);
+      w1[0] = __byte_perm_S (w1[0], w0[3], selector);
+      w0[3] = __byte_perm_S (w0[3], w0[2], selector);
+      w0[2] = __byte_perm_S (w0[2], w0[1], selector);
+      w0[1] = __byte_perm_S (w0[1], w0[0], selector);
+      w0[0] = __byte_perm_S (w0[0],     0, selector);
       break;
 
     case 1:
-      w0[0] = w0[0]            | append0[0] <<  8;
-      w0[1] = append0[0] >> 24 | append0[1] <<  8;
-      w0[2] = append0[1] >> 24 | append0[2] <<  8;
-      w0[3] = append0[2] >> 24 | append0[3] <<  8;
-      w1[0] = append0[3] >> 24 | append1[0] <<  8;
-      w1[1] = append1[0] >> 24 | append1[1] <<  8;
-      w1[2] = append1[1] >> 24 | append1[2] <<  8;
-      w1[3] = append1[2] >> 24 | append1[3] <<  8;
-      w2[0] = append1[3] >> 24 | append2[0] <<  8;
-      w2[1] = append2[0] >> 24;
+      w3[1] = __byte_perm_S (w3[0], w2[3], selector);
+      w3[0] = __byte_perm_S (w2[3], w2[2], selector);
+      w2[3] = __byte_perm_S (w2[2], w2[1], selector);
+      w2[2] = __byte_perm_S (w2[1], w2[0], selector);
+      w2[1] = __byte_perm_S (w2[0], w1[3], selector);
+      w2[0] = __byte_perm_S (w1[3], w1[2], selector);
+      w1[3] = __byte_perm_S (w1[2], w1[1], selector);
+      w1[2] = __byte_perm_S (w1[1], w1[0], selector);
+      w1[1] = __byte_perm_S (w1[0], w0[3], selector);
+      w1[0] = __byte_perm_S (w0[3], w0[2], selector);
+      w0[3] = __byte_perm_S (w0[2], w0[1], selector);
+      w0[2] = __byte_perm_S (w0[1], w0[0], selector);
+      w0[1] = __byte_perm_S (w0[0],     0, selector);
+      w0[0] = 0;
       break;
 
     case 2:
-      w0[0] = w0[0]            | append0[0] << 16;
-      w0[1] = append0[0] >> 16 | append0[1] << 16;
-      w0[2] = append0[1] >> 16 | append0[2] << 16;
-      w0[3] = append0[2] >> 16 | append0[3] << 16;
-      w1[0] = append0[3] >> 16 | append1[0] << 16;
-      w1[1] = append1[0] >> 16 | append1[1] << 16;
-      w1[2] = append1[1] >> 16 | append1[2] << 16;
-      w1[3] = append1[2] >> 16 | append1[3] << 16;
-      w2[0] = append1[3] >> 16 | append2[0] << 16;
-      w2[1] = append2[0] >> 16;
+      w3[1] = __byte_perm_S (w2[3], w2[2], selector);
+      w3[0] = __byte_perm_S (w2[2], w2[1], selector);
+      w2[3] = __byte_perm_S (w2[1], w2[0], selector);
+      w2[2] = __byte_perm_S (w2[0], w1[3], selector);
+      w2[1] = __byte_perm_S (w1[3], w1[2], selector);
+      w2[0] = __byte_perm_S (w1[2], w1[1], selector);
+      w1[3] = __byte_perm_S (w1[1], w1[0], selector);
+      w1[2] = __byte_perm_S (w1[0], w0[3], selector);
+      w1[1] = __byte_perm_S (w0[3], w0[2], selector);
+      w1[0] = __byte_perm_S (w0[2], w0[1], selector);
+      w0[3] = __byte_perm_S (w0[1], w0[0], selector);
+      w0[2] = __byte_perm_S (w0[0],     0, selector);
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 3:
-      w0[0] = w0[0]            | append0[0] << 24;
-      w0[1] = append0[0] >>  8 | append0[1] << 24;
-      w0[2] = append0[1] >>  8 | append0[2] << 24;
-      w0[3] = append0[2] >>  8 | append0[3] << 24;
-      w1[0] = append0[3] >>  8 | append1[0] << 24;
-      w1[1] = append1[0] >>  8 | append1[1] << 24;
-      w1[2] = append1[1] >>  8 | append1[2] << 24;
-      w1[3] = append1[2] >>  8 | append1[3] << 24;
-      w2[0] = append1[3] >>  8 | append2[0] << 24;
-      w2[1] = append2[0] >>  8;
+      w3[1] = __byte_perm_S (w2[2], w2[1], selector);
+      w3[0] = __byte_perm_S (w2[1], w2[0], selector);
+      w2[3] = __byte_perm_S (w2[0], w1[3], selector);
+      w2[2] = __byte_perm_S (w1[3], w1[2], selector);
+      w2[1] = __byte_perm_S (w1[2], w1[1], selector);
+      w2[0] = __byte_perm_S (w1[1], w1[0], selector);
+      w1[3] = __byte_perm_S (w1[0], w0[3], selector);
+      w1[2] = __byte_perm_S (w0[3], w0[2], selector);
+      w1[1] = __byte_perm_S (w0[2], w0[1], selector);
+      w1[0] = __byte_perm_S (w0[1], w0[0], selector);
+      w0[3] = __byte_perm_S (w0[0],     0, selector);
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 4:
-      w0[1] = append0[0];
-      w0[2] = append0[1];
-      w0[3] = append0[2];
-      w1[0] = append0[3];
-      w1[1] = append1[0];
-      w1[2] = append1[1];
-      w1[3] = append1[2];
-      w2[0] = append1[3];
-      w2[1] = append2[0];
+      w3[1] = __byte_perm_S (w2[1], w2[0], selector);
+      w3[0] = __byte_perm_S (w2[0], w1[3], selector);
+      w2[3] = __byte_perm_S (w1[3], w1[2], selector);
+      w2[2] = __byte_perm_S (w1[2], w1[1], selector);
+      w2[1] = __byte_perm_S (w1[1], w1[0], selector);
+      w2[0] = __byte_perm_S (w1[0], w0[3], selector);
+      w1[3] = __byte_perm_S (w0[3], w0[2], selector);
+      w1[2] = __byte_perm_S (w0[2], w0[1], selector);
+      w1[1] = __byte_perm_S (w0[1], w0[0], selector);
+      w1[0] = __byte_perm_S (w0[0],     0, selector);
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 5:
-      w0[1] = w0[1]            | append0[0] <<  8;
-      w0[2] = append0[0] >> 24 | append0[1] <<  8;
-      w0[3] = append0[1] >> 24 | append0[2] <<  8;
-      w1[0] = append0[2] >> 24 | append0[3] <<  8;
-      w1[1] = append0[3] >> 24 | append1[0] <<  8;
-      w1[2] = append1[0] >> 24 | append1[1] <<  8;
-      w1[3] = append1[1] >> 24 | append1[2] <<  8;
-      w2[0] = append1[2] >> 24 | append1[3] <<  8;
-      w2[1] = append1[3] >> 24 | append2[0] <<  8;
-      w2[2] = append2[0] >> 24;
+      w3[1] = __byte_perm_S (w2[0], w1[3], selector);
+      w3[0] = __byte_perm_S (w1[3], w1[2], selector);
+      w2[3] = __byte_perm_S (w1[2], w1[1], selector);
+      w2[2] = __byte_perm_S (w1[1], w1[0], selector);
+      w2[1] = __byte_perm_S (w1[0], w0[3], selector);
+      w2[0] = __byte_perm_S (w0[3], w0[2], selector);
+      w1[3] = __byte_perm_S (w0[2], w0[1], selector);
+      w1[2] = __byte_perm_S (w0[1], w0[0], selector);
+      w1[1] = __byte_perm_S (w0[0],     0, selector);
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 6:
-      w0[1] = w0[1]            | append0[0] << 16;
-      w0[2] = append0[0] >> 16 | append0[1] << 16;
-      w0[3] = append0[1] >> 16 | append0[2] << 16;
-      w1[0] = append0[2] >> 16 | append0[3] << 16;
-      w1[1] = append0[3] >> 16 | append1[0] << 16;
-      w1[2] = append1[0] >> 16 | append1[1] << 16;
-      w1[3] = append1[1] >> 16 | append1[2] << 16;
-      w2[0] = append1[2] >> 16 | append1[3] << 16;
-      w2[1] = append1[3] >> 16 | append2[0] << 16;
-      w2[2] = append2[0] >> 16;
+      w3[1] = __byte_perm_S (w1[3], w1[2], selector);
+      w3[0] = __byte_perm_S (w1[2], w1[1], selector);
+      w2[3] = __byte_perm_S (w1[1], w1[0], selector);
+      w2[2] = __byte_perm_S (w1[0], w0[3], selector);
+      w2[1] = __byte_perm_S (w0[3], w0[2], selector);
+      w2[0] = __byte_perm_S (w0[2], w0[1], selector);
+      w1[3] = __byte_perm_S (w0[1], w0[0], selector);
+      w1[2] = __byte_perm_S (w0[0],     0, selector);
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 7:
-      w0[1] = w0[1]            | append0[0] << 24;
-      w0[2] = append0[0] >>  8 | append0[1] << 24;
-      w0[3] = append0[1] >>  8 | append0[2] << 24;
-      w1[0] = append0[2] >>  8 | append0[3] << 24;
-      w1[1] = append0[3] >>  8 | append1[0] << 24;
-      w1[2] = append1[0] >>  8 | append1[1] << 24;
-      w1[3] = append1[1] >>  8 | append1[2] << 24;
-      w2[0] = append1[2] >>  8 | append1[3] << 24;
-      w2[1] = append1[3] >>  8 | append2[0] << 24;
-      w2[2] = append2[0] >>  8;
+      w3[1] = __byte_perm_S (w1[2], w1[1], selector);
+      w3[0] = __byte_perm_S (w1[1], w1[0], selector);
+      w2[3] = __byte_perm_S (w1[0], w0[3], selector);
+      w2[2] = __byte_perm_S (w0[3], w0[2], selector);
+      w2[1] = __byte_perm_S (w0[2], w0[1], selector);
+      w2[0] = __byte_perm_S (w0[1], w0[0], selector);
+      w1[3] = __byte_perm_S (w0[0],     0, selector);
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 8:
-      w0[2] = append0[0];
-      w0[3] = append0[1];
-      w1[0] = append0[2];
-      w1[1] = append0[3];
-      w1[2] = append1[0];
-      w1[3] = append1[1];
-      w2[0] = append1[2];
-      w2[1] = append1[3];
-      w2[2] = append2[0];
+      w3[1] = __byte_perm_S (w1[1], w1[0], selector);
+      w3[0] = __byte_perm_S (w1[0], w0[3], selector);
+      w2[3] = __byte_perm_S (w0[3], w0[2], selector);
+      w2[2] = __byte_perm_S (w0[2], w0[1], selector);
+      w2[1] = __byte_perm_S (w0[1], w0[0], selector);
+      w2[0] = __byte_perm_S (w0[0],     0, selector);
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 9:
-      w0[2] = w0[2]            | append0[0] <<  8;
-      w0[3] = append0[0] >> 24 | append0[1] <<  8;
-      w1[0] = append0[1] >> 24 | append0[2] <<  8;
-      w1[1] = append0[2] >> 24 | append0[3] <<  8;
-      w1[2] = append0[3] >> 24 | append1[0] <<  8;
-      w1[3] = append1[0] >> 24 | append1[1] <<  8;
-      w2[0] = append1[1] >> 24 | append1[2] <<  8;
-      w2[1] = append1[2] >> 24 | append1[3] <<  8;
-      w2[2] = append1[3] >> 24 | append2[0] <<  8;
-      w2[3] = append2[0] >> 24;
+      w3[1] = __byte_perm_S (w1[0], w0[3], selector);
+      w3[0] = __byte_perm_S (w0[3], w0[2], selector);
+      w2[3] = __byte_perm_S (w0[2], w0[1], selector);
+      w2[2] = __byte_perm_S (w0[1], w0[0], selector);
+      w2[1] = __byte_perm_S (w0[0],     0, selector);
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 10:
-      w0[2] = w0[2]            | append0[0] << 16;
-      w0[3] = append0[0] >> 16 | append0[1] << 16;
-      w1[0] = append0[1] >> 16 | append0[2] << 16;
-      w1[1] = append0[2] >> 16 | append0[3] << 16;
-      w1[2] = append0[3] >> 16 | append1[0] << 16;
-      w1[3] = append1[0] >> 16 | append1[1] << 16;
-      w2[0] = append1[1] >> 16 | append1[2] << 16;
-      w2[1] = append1[2] >> 16 | append1[3] << 16;
-      w2[2] = append1[3] >> 16 | append2[0] << 16;
-      w2[3] = append2[0] >> 16;
+      w3[1] = __byte_perm_S (w0[3], w0[2], selector);
+      w3[0] = __byte_perm_S (w0[2], w0[1], selector);
+      w2[3] = __byte_perm_S (w0[1], w0[0], selector);
+      w2[2] = __byte_perm_S (w0[0],     0, selector);
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 11:
-      w0[2] = w0[2]            | append0[0] << 24;
-      w0[3] = append0[0] >>  8 | append0[1] << 24;
-      w1[0] = append0[1] >>  8 | append0[2] << 24;
-      w1[1] = append0[2] >>  8 | append0[3] << 24;
-      w1[2] = append0[3] >>  8 | append1[0] << 24;
-      w1[3] = append1[0] >>  8 | append1[1] << 24;
-      w2[0] = append1[1] >>  8 | append1[2] << 24;
-      w2[1] = append1[2] >>  8 | append1[3] << 24;
-      w2[2] = append1[3] >>  8 | append2[0] << 24;
-      w2[3] = append2[0] >>  8;
+      w3[1] = __byte_perm_S (w0[2], w0[1], selector);
+      w3[0] = __byte_perm_S (w0[1], w0[0], selector);
+      w2[3] = __byte_perm_S (w0[0],     0, selector);
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 12:
-      w0[3] = append0[0];
-      w1[0] = append0[1];
-      w1[1] = append0[2];
-      w1[2] = append0[3];
-      w1[3] = append1[0];
-      w2[0] = append1[1];
-      w2[1] = append1[2];
-      w2[2] = append1[3];
-      w2[3] = append2[0];
+      w3[1] = __byte_perm_S (w0[1], w0[0], selector);
+      w3[0] = __byte_perm_S (w0[0],     0, selector);
+      w2[3] = 0;
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
 
     case 13:
-      w0[3] = w0[3]            | append0[0] <<  8;
-      w1[0] = append0[0] >> 24 | append0[1] <<  8;
-      w1[1] = append0[1] >> 24 | append0[2] <<  8;
-      w1[2] = append0[2] >> 24 | append0[3] <<  8;
-      w1[3] = append0[3] >> 24 | append1[0] <<  8;
-      w2[0] = append1[0] >> 24 | append1[1] <<  8;
-      w2[1] = append1[1] >> 24 | append1[2] <<  8;
-      w2[2] = append1[2] >> 24 | append1[3] <<  8;
-      w2[3] = append1[3] >> 24 | append2[0] <<  8;
-      w3[0] = append2[0] >> 24;
+      w3[1] = __byte_perm_S (w0[0],     0, selector);
+      w3[0] = 0;
+      w2[3] = 0;
+      w2[2] = 0;
+      w2[1] = 0;
+      w2[0] = 0;
+      w1[3] = 0;
+      w1[2] = 0;
+      w1[1] = 0;
+      w1[0] = 0;
+      w0[3] = 0;
+      w0[2] = 0;
+      w0[1] = 0;
+      w0[0] = 0;
       break;
+  }
+  #endif
+}
 
-    case 14:
-      w0[3] = w0[3]            | append0[0] << 16;
-      w1[0] = append0[0] >> 16 | append0[1] << 16;
-      w1[1] = append0[1] >> 16 | append0[2] << 16;
-      w1[2] = append0[2] >> 16 | append0[3] << 16;
-      w1[3] = append0[3] >> 16 | append1[0] << 16;
-      w2[0] = append1[0] >> 16 | append1[1] << 16;
-      w2[1] = append1[1] >> 16 | append1[2] << 16;
-      w2[2] = append1[2] >> 16 | append1[3] << 16;
-      w2[3] = append1[3] >> 16 | append2[0] << 16;
-      w3[0] = append2[0] >> 16;
-      break;
+/**
+ * vector functions on scalar types (for inner loop usage)
+ */
 
-    case 15:
-      w0[3] = w0[3]            | append0[0] << 24;
-      w1[0] = append0[0] >>  8 | append0[1] << 24;
-      w1[1] = append0[1] >>  8 | append0[2] << 24;
-      w1[2] = append0[2] >>  8 | append0[3] << 24;
-      w1[3] = append0[3] >>  8 | append1[0] << 24;
-      w2[0] = append1[0] >>  8 | append1[1] << 24;
-      w2[1] = append1[1] >>  8 | append1[2] << 24;
-      w2[2] = append1[2] >>  8 | append1[3] << 24;
-      w2[3] = append1[3] >>  8 | append2[0] << 24;
-      w3[0] = append2[0] >>  8;
-      break;
+#define PACKVS2(sn,vn,e)  \
+  sn[0] = vn[0].s##e;     \
+  sn[1] = vn[1].s##e;
+
+#define PACKSV2(sn,vn,e)  \
+  vn[0].s##e = sn[0];     \
+  vn[1].s##e = sn[1];
+
+#define PACKVS24(s0,s1,v0,v1,e) \
+  PACKVS4 (s0, v0, e);          \
+  PACKVS4 (s1, v1, e);
+
+#define PACKSV24(s0,s1,v0,v1,e) \
+  PACKSV4 (s0, v0, e);          \
+  PACKSV4 (s1, v1, e);
+
+#define PACKVS4(sn,vn,e)  \
+  sn[0] = vn[0].s##e;     \
+  sn[1] = vn[1].s##e;     \
+  sn[2] = vn[2].s##e;     \
+  sn[3] = vn[3].s##e;
+
+#define PACKSV4(sn,vn,e)  \
+  vn[0].s##e = sn[0];     \
+  vn[1].s##e = sn[1];     \
+  vn[2].s##e = sn[2];     \
+  vn[3].s##e = sn[3];
+
+#define PACKVS44(s0,s1,s2,s3,v0,v1,v2,v3,e) \
+  PACKVS4 (s0, v0, e);                      \
+  PACKVS4 (s1, v1, e);                      \
+  PACKVS4 (s2, v2, e);                      \
+  PACKVS4 (s3, v3, e);
+
+#define PACKSV44(s0,s1,s2,s3,v0,v1,v2,v3,e) \
+  PACKSV4 (s0, v0, e);                      \
+  PACKSV4 (s1, v1, e);                      \
+  PACKSV4 (s2, v2, e);                      \
+  PACKSV4 (s3, v3, e);
+
+inline void switch_buffer_by_offset_le_VV (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32x offset)
+{
+  #if VECT_SIZE == 1
 
-    case 16:
-      w1[0] = append0[0];
-      w1[1] = append0[1];
-      w1[2] = append0[2];
-      w1[3] = append0[3];
-      w2[0] = append1[0];
-      w2[1] = append1[1];
-      w2[2] = append1[2];
-      w2[3] = append1[3];
-      w3[0] = append2[0];
-      break;
+  switch_buffer_by_offset_le_S (w0, w1, w2, w3, offset);
 
-    case 17:
-      w1[0] = w1[0]            | append0[0] <<  8;
-      w1[1] = append0[0] >> 24 | append0[1] <<  8;
-      w1[2] = append0[1] >> 24 | append0[2] <<  8;
-      w1[3] = append0[2] >> 24 | append0[3] <<  8;
-      w2[0] = append0[3] >> 24 | append1[0] <<  8;
-      w2[1] = append1[0] >> 24 | append1[1] <<  8;
-      w2[2] = append1[1] >> 24 | append1[2] <<  8;
-      w2[3] = append1[2] >> 24 | append1[3] <<  8;
-      w3[0] = append1[3] >> 24 | append2[0] <<  8;
-      w3[1] = append2[0] >> 24;
-      break;
+  #else
 
-    case 18:
-      w1[0] = w1[0]            | append0[0] << 16;
-      w1[1] = append0[0] >> 16 | append0[1] << 16;
-      w1[2] = append0[1] >> 16 | append0[2] << 16;
-      w1[3] = append0[2] >> 16 | append0[3] << 16;
-      w2[0] = append0[3] >> 16 | append1[0] << 16;
-      w2[1] = append1[0] >> 16 | append1[1] << 16;
-      w2[2] = append1[1] >> 16 | append1[2] << 16;
-      w2[3] = append1[2] >> 16 | append1[3] << 16;
-      w3[0] = append1[3] >> 16 | append2[0] << 16;
-      w3[1] = append2[0] >> 16;
-      break;
+  u32 t0[4];
+  u32 t1[4];
+  u32 t2[4];
+  u32 t3[4];
 
-    case 19:
-      w1[0] = w1[0]            | append0[0] << 24;
-      w1[1] = append0[0] >>  8 | append0[1] << 24;
-      w1[2] = append0[1] >>  8 | append0[2] << 24;
-      w1[3] = append0[2] >>  8 | append0[3] << 24;
-      w2[0] = append0[3] >>  8 | append1[0] << 24;
-      w2[1] = append1[0] >>  8 | append1[1] << 24;
-      w2[2] = append1[1] >>  8 | append1[2] << 24;
-      w2[3] = append1[2] >>  8 | append1[3] << 24;
-      w3[0] = append1[3] >>  8 | append2[0] << 24;
-      w3[1] = append2[0] >>  8;
-      break;
+  #endif
 
-    case 20:
-      w1[1] = append0[0];
-      w1[2] = append0[1];
-      w1[3] = append0[2];
-      w2[0] = append0[3];
-      w2[1] = append1[0];
-      w2[2] = append1[1];
-      w2[3] = append1[2];
-      w3[0] = append1[3];
-      w3[1] = append2[0];
-      break;
+  #if   VECT_SIZE == 2
+
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 0); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s0); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 0);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 1); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s1); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 1);
+
+  #elif VECT_SIZE == 4
+
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 0); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s0); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 0);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 1); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s1); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 1);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 2); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s2); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 2);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 3); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s3); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 3);
+
+  #elif VECT_SIZE == 8
+
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 0); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s0); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 0);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 1); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s1); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 1);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 2); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s2); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 2);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 3); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s3); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 3);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 4); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s4); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 4);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 5); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s5); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 5);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 6); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s6); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 6);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 7); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s7); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 7);
+
+  #elif VECT_SIZE == 16
+
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 0); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s0); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 0);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 1); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s1); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 1);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 2); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s2); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 2);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 3); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s3); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 3);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 4); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s4); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 4);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 5); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s5); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 5);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 6); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s6); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 6);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 7); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s7); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 7);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 8); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s8); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 8);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 9); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.s9); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 9);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, a); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.sa); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, a);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, b); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.sb); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, b);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, c); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.sc); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, c);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, d); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.sd); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, d);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, e); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.se); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, e);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, f); switch_buffer_by_offset_le_S (t0, t1, t2, t3, offset.sf); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, f);
 
-    case 21:
-      w1[1] = w1[1]            | append0[0] <<  8;
-      w1[2] = append0[0] >> 24 | append0[1] <<  8;
-      w1[3] = append0[1] >> 24 | append0[2] <<  8;
-      w2[0] = append0[2] >> 24 | append0[3] <<  8;
-      w2[1] = append0[3] >> 24 | append1[0] <<  8;
-      w2[2] = append1[0] >> 24 | append1[1] <<  8;
-      w2[3] = append1[1] >> 24 | append1[2] <<  8;
-      w3[0] = append1[2] >> 24 | append1[3] <<  8;
-      w3[1] = append1[3] >> 24 | append2[0] <<  8;
-      break;
+  #endif
+}
 
-    case 22:
-      w1[1] = w1[1]            | append0[0] << 16;
-      w1[2] = append0[0] >> 16 | append0[1] << 16;
-      w1[3] = append0[1] >> 16 | append0[2] << 16;
-      w2[0] = append0[2] >> 16 | append0[3] << 16;
-      w2[1] = append0[3] >> 16 | append1[0] << 16;
-      w2[2] = append1[0] >> 16 | append1[1] << 16;
-      w2[3] = append1[1] >> 16 | append1[2] << 16;
-      w3[0] = append1[2] >> 16 | append1[3] << 16;
-      w3[1] = append1[3] >> 16 | append2[0] << 16;
-      break;
+inline void append_0x01_2x4_VV (u32x w0[4], u32x w1[4], const u32x offset)
+{
+  #if VECT_SIZE == 1
 
-    case 23:
-      w1[1] = w1[1]            | append0[0] << 24;
-      w1[2] = append0[0] >>  8 | append0[1] << 24;
-      w1[3] = append0[1] >>  8 | append0[2] << 24;
-      w2[0] = append0[2] >>  8 | append0[3] << 24;
-      w2[1] = append0[3] >>  8 | append1[0] << 24;
-      w2[2] = append1[0] >>  8 | append1[1] << 24;
-      w2[3] = append1[1] >>  8 | append1[2] << 24;
-      w3[0] = append1[2] >>  8 | append1[3] << 24;
-      w3[1] = append1[3] >>  8 | append2[0] << 24;
-      break;
+  append_0x01_2x4_S (w0, w1, offset);
 
-    case 24:
-      w1[2] = append0[0];
-      w1[3] = append0[1];
-      w2[0] = append0[2];
-      w2[1] = append0[3];
-      w2[2] = append1[0];
-      w2[3] = append1[1];
-      w3[0] = append1[2];
-      w3[1] = append1[3];
-      break;
+  #else
 
-    case 25:
-      w1[2] = w1[2]            | append0[0] <<  8;
-      w1[3] = append0[0] >> 24 | append0[1] <<  8;
-      w2[0] = append0[1] >> 24 | append0[2] <<  8;
-      w2[1] = append0[2] >> 24 | append0[3] <<  8;
-      w2[2] = append0[3] >> 24 | append1[0] <<  8;
-      w2[3] = append1[0] >> 24 | append1[1] <<  8;
-      w3[0] = append1[1] >> 24 | append1[2] <<  8;
-      w3[1] = append1[2] >> 24 | append1[3] <<  8;
-      break;
+  u32 t0[4];
+  u32 t1[4];
 
-    case 26:
-      w1[2] = w1[2]            | append0[0] << 16;
-      w1[3] = append0[0] >> 16 | append0[1] << 16;
-      w2[0] = append0[1] >> 16 | append0[2] << 16;
-      w2[1] = append0[2] >> 16 | append0[3] << 16;
-      w2[2] = append0[3] >> 16 | append1[0] << 16;
-      w2[3] = append1[0] >> 16 | append1[1] << 16;
-      w3[0] = append1[1] >> 16 | append1[2] << 16;
-      w3[1] = append1[2] >> 16 | append1[3] << 16;
-      break;
+  #endif
 
-    case 27:
-      w1[2] = w1[2]            | append0[0] << 24;
-      w1[3] = append0[0] >>  8 | append0[1] << 24;
-      w2[0] = append0[1] >>  8 | append0[2] << 24;
-      w2[1] = append0[2] >>  8 | append0[3] << 24;
-      w2[2] = append0[3] >>  8 | append1[0] << 24;
-      w2[3] = append1[0] >>  8 | append1[1] << 24;
-      w3[0] = append1[1] >>  8 | append1[2] << 24;
-      w3[1] = append1[2] >>  8 | append1[3] << 24;
-      break;
+  #if   VECT_SIZE == 2
+
+  PACKVS24 (t0, t1, w0, w1, 0); append_0x01_2x4_S (t0, t1, offset.s0); PACKSV24 (t0, t1, w0, w1, 0);
+  PACKVS24 (t0, t1, w0, w1, 1); append_0x01_2x4_S (t0, t1, offset.s1); PACKSV24 (t0, t1, w0, w1, 1);
+
+  #elif VECT_SIZE == 4
+
+  PACKVS24 (t0, t1, w0, w1, 0); append_0x01_2x4_S (t0, t1, offset.s0); PACKSV24 (t0, t1, w0, w1, 0);
+  PACKVS24 (t0, t1, w0, w1, 1); append_0x01_2x4_S (t0, t1, offset.s1); PACKSV24 (t0, t1, w0, w1, 1);
+  PACKVS24 (t0, t1, w0, w1, 2); append_0x01_2x4_S (t0, t1, offset.s2); PACKSV24 (t0, t1, w0, w1, 2);
+  PACKVS24 (t0, t1, w0, w1, 3); append_0x01_2x4_S (t0, t1, offset.s3); PACKSV24 (t0, t1, w0, w1, 3);
+
+  #elif VECT_SIZE == 8
+
+  PACKVS24 (t0, t1, w0, w1, 0); append_0x01_2x4_S (t0, t1, offset.s0); PACKSV24 (t0, t1, w0, w1, 0);
+  PACKVS24 (t0, t1, w0, w1, 1); append_0x01_2x4_S (t0, t1, offset.s1); PACKSV24 (t0, t1, w0, w1, 1);
+  PACKVS24 (t0, t1, w0, w1, 2); append_0x01_2x4_S (t0, t1, offset.s2); PACKSV24 (t0, t1, w0, w1, 2);
+  PACKVS24 (t0, t1, w0, w1, 3); append_0x01_2x4_S (t0, t1, offset.s3); PACKSV24 (t0, t1, w0, w1, 3);
+  PACKVS24 (t0, t1, w0, w1, 4); append_0x01_2x4_S (t0, t1, offset.s4); PACKSV24 (t0, t1, w0, w1, 4);
+  PACKVS24 (t0, t1, w0, w1, 5); append_0x01_2x4_S (t0, t1, offset.s5); PACKSV24 (t0, t1, w0, w1, 5);
+  PACKVS24 (t0, t1, w0, w1, 6); append_0x01_2x4_S (t0, t1, offset.s6); PACKSV24 (t0, t1, w0, w1, 6);
+  PACKVS24 (t0, t1, w0, w1, 7); append_0x01_2x4_S (t0, t1, offset.s7); PACKSV24 (t0, t1, w0, w1, 7);
+
+  #elif VECT_SIZE == 16
+
+  PACKVS24 (t0, t1, w0, w1, 0); append_0x01_2x4_S (t0, t1, offset.s0); PACKSV24 (t0, t1, w0, w1, 0);
+  PACKVS24 (t0, t1, w0, w1, 1); append_0x01_2x4_S (t0, t1, offset.s1); PACKSV24 (t0, t1, w0, w1, 1);
+  PACKVS24 (t0, t1, w0, w1, 2); append_0x01_2x4_S (t0, t1, offset.s2); PACKSV24 (t0, t1, w0, w1, 2);
+  PACKVS24 (t0, t1, w0, w1, 3); append_0x01_2x4_S (t0, t1, offset.s3); PACKSV24 (t0, t1, w0, w1, 3);
+  PACKVS24 (t0, t1, w0, w1, 4); append_0x01_2x4_S (t0, t1, offset.s4); PACKSV24 (t0, t1, w0, w1, 4);
+  PACKVS24 (t0, t1, w0, w1, 5); append_0x01_2x4_S (t0, t1, offset.s5); PACKSV24 (t0, t1, w0, w1, 5);
+  PACKVS24 (t0, t1, w0, w1, 6); append_0x01_2x4_S (t0, t1, offset.s6); PACKSV24 (t0, t1, w0, w1, 6);
+  PACKVS24 (t0, t1, w0, w1, 7); append_0x01_2x4_S (t0, t1, offset.s7); PACKSV24 (t0, t1, w0, w1, 7);
+  PACKVS24 (t0, t1, w0, w1, 8); append_0x01_2x4_S (t0, t1, offset.s8); PACKSV24 (t0, t1, w0, w1, 8);
+  PACKVS24 (t0, t1, w0, w1, 9); append_0x01_2x4_S (t0, t1, offset.s9); PACKSV24 (t0, t1, w0, w1, 9);
+  PACKVS24 (t0, t1, w0, w1, a); append_0x01_2x4_S (t0, t1, offset.sa); PACKSV24 (t0, t1, w0, w1, a);
+  PACKVS24 (t0, t1, w0, w1, b); append_0x01_2x4_S (t0, t1, offset.sb); PACKSV24 (t0, t1, w0, w1, b);
+  PACKVS24 (t0, t1, w0, w1, c); append_0x01_2x4_S (t0, t1, offset.sc); PACKSV24 (t0, t1, w0, w1, c);
+  PACKVS24 (t0, t1, w0, w1, d); append_0x01_2x4_S (t0, t1, offset.sd); PACKSV24 (t0, t1, w0, w1, d);
+  PACKVS24 (t0, t1, w0, w1, e); append_0x01_2x4_S (t0, t1, offset.se); PACKSV24 (t0, t1, w0, w1, e);
+  PACKVS24 (t0, t1, w0, w1, f); append_0x01_2x4_S (t0, t1, offset.sf); PACKSV24 (t0, t1, w0, w1, f);
 
-    case 28:
-      w1[3] = append0[0];
-      w2[0] = append0[1];
-      w2[1] = append0[2];
-      w2[2] = append0[3];
-      w2[3] = append1[0];
-      w3[0] = append1[1];
-      w3[1] = append1[2];
-      break;
+  #endif
+}
 
-    case 29:
-      w1[3] = w1[3]            | append0[0] <<  8;
-      w2[0] = append0[0] >> 24 | append0[1] <<  8;
-      w2[1] = append0[1] >> 24 | append0[2] <<  8;
-      w2[2] = append0[2] >> 24 | append0[3] <<  8;
-      w2[3] = append0[3] >> 24 | append1[0] <<  8;
-      w3[0] = append1[0] >> 24 | append1[1] <<  8;
-      w3[1] = append1[1] >> 24 | append1[2] <<  8;
-      break;
+inline void append_0x80_2x4_VV (u32x w0[4], u32x w1[4], const u32x offset)
+{
+  #if VECT_SIZE == 1
 
-    case 30:
-      w1[3] = w1[3]            | append0[0] << 16;
-      w2[0] = append0[0] >> 16 | append0[1] << 16;
-      w2[1] = append0[1] >> 16 | append0[2] << 16;
-      w2[2] = append0[2] >> 16 | append0[3] << 16;
-      w2[3] = append0[3] >> 16 | append1[0] << 16;
-      w3[0] = append1[0] >> 16 | append1[1] << 16;
-      w3[1] = append1[1] >> 16 | append1[2] << 16;
-      break;
+  append_0x80_2x4_S (w0, w1, offset);
 
-    case 31:
-      w1[3] = w1[3]            | append0[0] << 24;
-      w2[0] = append0[0] >>  8 | append0[1] << 24;
-      w2[1] = append0[1] >>  8 | append0[2] << 24;
-      w2[2] = append0[2] >>  8 | append0[3] << 24;
-      w2[3] = append0[3] >>  8 | append1[0] << 24;
-      w3[0] = append1[0] >>  8 | append1[1] << 24;
-      w3[1] = append1[1] >>  8 | append1[2] << 24;
-      break;
+  #else
 
-    case 32:
-      w2[0] = append0[0];
-      w2[1] = append0[1];
-      w2[2] = append0[2];
-      w2[3] = append0[3];
-      w3[0] = append1[0];
-      w3[1] = append1[1];
-      break;
-  }
+  u32 t0[4];
+  u32 t1[4];
+
+  #endif
+
+  #if   VECT_SIZE == 2
+
+  PACKVS24 (t0, t1, w0, w1, 0); append_0x80_2x4_S (t0, t1, offset.s0); PACKSV24 (t0, t1, w0, w1, 0);
+  PACKVS24 (t0, t1, w0, w1, 1); append_0x80_2x4_S (t0, t1, offset.s1); PACKSV24 (t0, t1, w0, w1, 1);
+
+  #elif VECT_SIZE == 4
+
+  PACKVS24 (t0, t1, w0, w1, 0); append_0x80_2x4_S (t0, t1, offset.s0); PACKSV24 (t0, t1, w0, w1, 0);
+  PACKVS24 (t0, t1, w0, w1, 1); append_0x80_2x4_S (t0, t1, offset.s1); PACKSV24 (t0, t1, w0, w1, 1);
+  PACKVS24 (t0, t1, w0, w1, 2); append_0x80_2x4_S (t0, t1, offset.s2); PACKSV24 (t0, t1, w0, w1, 2);
+  PACKVS24 (t0, t1, w0, w1, 3); append_0x80_2x4_S (t0, t1, offset.s3); PACKSV24 (t0, t1, w0, w1, 3);
+
+  #elif VECT_SIZE == 8
+
+  PACKVS24 (t0, t1, w0, w1, 0); append_0x80_2x4_S (t0, t1, offset.s0); PACKSV24 (t0, t1, w0, w1, 0);
+  PACKVS24 (t0, t1, w0, w1, 1); append_0x80_2x4_S (t0, t1, offset.s1); PACKSV24 (t0, t1, w0, w1, 1);
+  PACKVS24 (t0, t1, w0, w1, 2); append_0x80_2x4_S (t0, t1, offset.s2); PACKSV24 (t0, t1, w0, w1, 2);
+  PACKVS24 (t0, t1, w0, w1, 3); append_0x80_2x4_S (t0, t1, offset.s3); PACKSV24 (t0, t1, w0, w1, 3);
+  PACKVS24 (t0, t1, w0, w1, 4); append_0x80_2x4_S (t0, t1, offset.s4); PACKSV24 (t0, t1, w0, w1, 4);
+  PACKVS24 (t0, t1, w0, w1, 5); append_0x80_2x4_S (t0, t1, offset.s5); PACKSV24 (t0, t1, w0, w1, 5);
+  PACKVS24 (t0, t1, w0, w1, 6); append_0x80_2x4_S (t0, t1, offset.s6); PACKSV24 (t0, t1, w0, w1, 6);
+  PACKVS24 (t0, t1, w0, w1, 7); append_0x80_2x4_S (t0, t1, offset.s7); PACKSV24 (t0, t1, w0, w1, 7);
+
+  #elif VECT_SIZE == 16
+
+  PACKVS24 (t0, t1, w0, w1, 0); append_0x80_2x4_S (t0, t1, offset.s0); PACKSV24 (t0, t1, w0, w1, 0);
+  PACKVS24 (t0, t1, w0, w1, 1); append_0x80_2x4_S (t0, t1, offset.s1); PACKSV24 (t0, t1, w0, w1, 1);
+  PACKVS24 (t0, t1, w0, w1, 2); append_0x80_2x4_S (t0, t1, offset.s2); PACKSV24 (t0, t1, w0, w1, 2);
+  PACKVS24 (t0, t1, w0, w1, 3); append_0x80_2x4_S (t0, t1, offset.s3); PACKSV24 (t0, t1, w0, w1, 3);
+  PACKVS24 (t0, t1, w0, w1, 4); append_0x80_2x4_S (t0, t1, offset.s4); PACKSV24 (t0, t1, w0, w1, 4);
+  PACKVS24 (t0, t1, w0, w1, 5); append_0x80_2x4_S (t0, t1, offset.s5); PACKSV24 (t0, t1, w0, w1, 5);
+  PACKVS24 (t0, t1, w0, w1, 6); append_0x80_2x4_S (t0, t1, offset.s6); PACKSV24 (t0, t1, w0, w1, 6);
+  PACKVS24 (t0, t1, w0, w1, 7); append_0x80_2x4_S (t0, t1, offset.s7); PACKSV24 (t0, t1, w0, w1, 7);
+  PACKVS24 (t0, t1, w0, w1, 8); append_0x80_2x4_S (t0, t1, offset.s8); PACKSV24 (t0, t1, w0, w1, 8);
+  PACKVS24 (t0, t1, w0, w1, 9); append_0x80_2x4_S (t0, t1, offset.s9); PACKSV24 (t0, t1, w0, w1, 9);
+  PACKVS24 (t0, t1, w0, w1, a); append_0x80_2x4_S (t0, t1, offset.sa); PACKSV24 (t0, t1, w0, w1, a);
+  PACKVS24 (t0, t1, w0, w1, b); append_0x80_2x4_S (t0, t1, offset.sb); PACKSV24 (t0, t1, w0, w1, b);
+  PACKVS24 (t0, t1, w0, w1, c); append_0x80_2x4_S (t0, t1, offset.sc); PACKSV24 (t0, t1, w0, w1, c);
+  PACKVS24 (t0, t1, w0, w1, d); append_0x80_2x4_S (t0, t1, offset.sd); PACKSV24 (t0, t1, w0, w1, d);
+  PACKVS24 (t0, t1, w0, w1, e); append_0x80_2x4_S (t0, t1, offset.se); PACKSV24 (t0, t1, w0, w1, e);
+  PACKVS24 (t0, t1, w0, w1, f); append_0x80_2x4_S (t0, t1, offset.sf); PACKSV24 (t0, t1, w0, w1, f);
+
+  #endif
 }
 
-*/
+inline void append_0x80_4x4_VV (u32x w0[4], u32x w1[4], u32x w2[4], u32x w3[4], const u32x offset)
+{
+  #if VECT_SIZE == 1
+
+  append_0x80_4x4_S (w0, w1, w2, w3, offset);
+
+  #else
+
+  u32 t0[4];
+  u32 t1[4];
+  u32 t2[4];
+  u32 t3[4];
+
+  #endif
+
+  #if   VECT_SIZE == 2
+
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 0); append_0x80_4x4_S (t0, t1, t2, t3, offset.s0); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 0);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 1); append_0x80_4x4_S (t0, t1, t2, t3, offset.s1); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 1);
+
+  #elif VECT_SIZE == 4
+
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 0); append_0x80_4x4_S (t0, t1, t2, t3, offset.s0); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 0);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 1); append_0x80_4x4_S (t0, t1, t2, t3, offset.s1); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 1);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 2); append_0x80_4x4_S (t0, t1, t2, t3, offset.s2); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 2);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 3); append_0x80_4x4_S (t0, t1, t2, t3, offset.s3); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 3);
+
+  #elif VECT_SIZE == 8
+
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 0); append_0x80_4x4_S (t0, t1, t2, t3, offset.s0); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 0);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 1); append_0x80_4x4_S (t0, t1, t2, t3, offset.s1); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 1);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 2); append_0x80_4x4_S (t0, t1, t2, t3, offset.s2); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 2);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 3); append_0x80_4x4_S (t0, t1, t2, t3, offset.s3); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 3);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 4); append_0x80_4x4_S (t0, t1, t2, t3, offset.s4); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 4);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 5); append_0x80_4x4_S (t0, t1, t2, t3, offset.s5); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 5);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 6); append_0x80_4x4_S (t0, t1, t2, t3, offset.s6); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 6);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 7); append_0x80_4x4_S (t0, t1, t2, t3, offset.s7); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 7);
+
+  #elif VECT_SIZE == 16
+
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 0); append_0x80_4x4_S (t0, t1, t2, t3, offset.s0); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 0);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 1); append_0x80_4x4_S (t0, t1, t2, t3, offset.s1); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 1);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 2); append_0x80_4x4_S (t0, t1, t2, t3, offset.s2); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 2);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 3); append_0x80_4x4_S (t0, t1, t2, t3, offset.s3); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 3);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 4); append_0x80_4x4_S (t0, t1, t2, t3, offset.s4); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 4);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 5); append_0x80_4x4_S (t0, t1, t2, t3, offset.s5); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 5);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 6); append_0x80_4x4_S (t0, t1, t2, t3, offset.s6); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 6);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 7); append_0x80_4x4_S (t0, t1, t2, t3, offset.s7); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 7);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 8); append_0x80_4x4_S (t0, t1, t2, t3, offset.s8); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 8);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, 9); append_0x80_4x4_S (t0, t1, t2, t3, offset.s9); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, 9);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, a); append_0x80_4x4_S (t0, t1, t2, t3, offset.sa); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, a);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, b); append_0x80_4x4_S (t0, t1, t2, t3, offset.sb); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, b);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, c); append_0x80_4x4_S (t0, t1, t2, t3, offset.sc); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, c);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, d); append_0x80_4x4_S (t0, t1, t2, t3, offset.sd); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, d);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, e); append_0x80_4x4_S (t0, t1, t2, t3, offset.se); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, e);
+  PACKVS44 (t0, t1, t2, t3, w0, w1, w2, w3, f); append_0x80_4x4_S (t0, t1, t2, t3, offset.sf); PACKSV44 (t0, t1, t2, t3, w0, w1, w2, w3, f);
+
+  #endif
+}