Converted _a3 kernels, use SIMD for CPU and GPU
[hashcat.git] / OpenCL / common.c
index 7c5d45d..6e78486 100644 (file)
@@ -3,6 +3,10 @@
  * License.....: MIT
  */
 
+/**
+ * pure scalar functions
+ */
+
 static int hash_comp (const u32 d1[4], __global u32 *d2)
 {
   if (d1[3] > d2[DGST_R3]) return ( 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
+ */
+
+static void truncate_block (u32x w[4], const u32 len)
 {
   switch (len)
   {
@@ -131,31 +139,6 @@ 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])
 {
   #ifdef IS_NV
@@ -181,27 +164,6 @@ 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])
 {
   #ifdef IS_NV
@@ -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)
+static 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)
+static 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)
+static 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)
+static 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)
+static 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)
+static 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)
+static 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)
+static 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)
+static 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)
+static 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)
+static void append_0x80_1x4 (u32x w0[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)
+static 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)
+static 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)
+static 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)
+static 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)
+static 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,12 +4309,12 @@ 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);
+      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;
@@ -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)
+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_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,2284 @@ 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)
+static 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;
+static 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 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)
-  {
-    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;
-  }
-  #endif
-}
-
-/* not needed anymore?
-
-// before: append_0x80_2_be
-static void append_0x80_2x4_be (u32 w0[4], u32 w1[4], const u32 offset)
-{
-  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;
-
-    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;
-  }
-}
-
-// before: append_0x80_8
-static void append_0x80_1x32 (u32 w[32], const u32 offset)
-{
-  switch (offset)
-  {
-    case 0:
-      w[ 0] = 0x80;
-      break;
-
-    case 1:
-      w[ 0] = w[ 0] | 0x8000;
-      break;
-
-    case 2:
-      w[ 0] = w[ 0] | 0x800000;
-      break;
-
-    case 3:
-      w[ 0] = w[ 0] | 0x80000000;
-      break;
-
-    case 4:
-      w[ 1] = 0x80;
-      break;
-
-    case 5:
-      w[ 1] = w[ 1] | 0x8000;
-      break;
-
-    case 6:
-      w[ 1] = w[ 1] | 0x800000;
-      break;
-
-    case 7:
-      w[ 1] = w[ 1] | 0x80000000;
-      break;
-
-    case 8:
-      w[ 2] = 0x80;
-      break;
-
-    case 9:
-      w[ 2] = w[ 2] | 0x8000;
-      break;
-
-    case 10:
-      w[ 2] = w[ 2] | 0x800000;
-      break;
-
-    case 11:
-      w[ 2] = w[ 2] | 0x80000000;
-      break;
-
-    case 12:
-      w[ 3] = 0x80;
-      break;
-
-    case 13:
-      w[ 3] = w[ 3] | 0x8000;
-      break;
-
-    case 14:
-      w[ 3] = w[ 3] | 0x800000;
-      break;
-
-    case 15:
-      w[ 3] = w[ 3] | 0x80000000;
-      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;
-      break;
-
-    case 72:
-      w[18] = 0x80;
-      break;
-
-    case 73:
-      w[18] = w[18] | 0x8000;
-      break;
-
-    case 74:
-      w[18] = w[18] | 0x800000;
-      break;
-
-    case 75:
-      w[18] = w[18] | 0x80000000;
-      break;
-
-    case 76:
-      w[19] = 0x80;
-      break;
-
-    case 77:
-      w[19] = w[19] | 0x8000;
-      break;
-
-    case 78:
-      w[19] = w[19] | 0x800000;
-      break;
-
-    case 79:
-      w[19] = w[19] | 0x80000000;
-      break;
-
-    case 80:
-      w[20] = 0x80;
-      break;
-
-    case 81:
-      w[20] = w[20] | 0x8000;
-      break;
-
-    case 82:
-      w[20] = w[20] | 0x800000;
-      break;
-
-    case 83:
-      w[20] = w[20] | 0x80000000;
-      break;
-
-    case 84:
-      w[21] = 0x80;
-      break;
-
-    case 85:
-      w[21] = w[21] | 0x8000;
-      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 86:
-      w[21] = w[21] | 0x800000;
-      break;
+/**
+ * vector functions as scalar (for outer loop usage)
+ */
 
-    case 87:
-      w[21] = w[21] | 0x80000000;
+static 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;
+static 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])
+static void append_0x80_3x4_S (u32 w0[4], u32 w1[4], u32 w2[4], const u32 offset)
 {
   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;
-      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;
-      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;
-      break;
-
-    case 4:
-      dst0[1] = src_r0[0];
-      dst0[2] = src_r0[1];
-      dst0[3] = src_r0[2];
-      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;
-      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;
-      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;
-      break;
-
-    case 8:
-      dst0[2] = src_r0[0];
-      dst0[3] = src_r0[1];
-      break;
-
-    case 9:
-      dst0[2] = src_l0[2]       | src_r0[0] <<  8;
-      dst0[3] = src_r0[0] >> 24 | src_r0[1] <<  8;
-      break;
-
-    case 10:
-      dst0[2] = src_l0[2]       | src_r0[0] << 16;
-      dst0[3] = src_r0[0] >> 16 | src_r0[1] << 16;
-      break;
-
-    case 11:
-      dst0[2] = src_l0[2]       | src_r0[0] << 24;
-      dst0[3] = src_r0[0] >>  8 | src_r0[1] << 24;
-      break;
-
-    case 12:
-      dst0[3] = src_r0[0];
-      break;
-
-    case 13:
-      dst0[3] = src_l0[3]       | src_r0[0] <<  8;
-      break;
-
-    case 14:
-      dst0[3] = src_l0[3]       | src_r0[0] << 16;
-      break;
-
-    case 15:
-      dst0[3] = src_l0[3]       | src_r0[0] << 24;
+    case 0:
+      w0[0] = 0x80;
       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;
+      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;
+      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;
+      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;
+      w1[0] = w1[0] | 0x80000000;
       break;
 
     case 20:
-      dst1[1] = src_r0[0];
-      dst1[2] = src_r0[1];
-      dst1[3] = src_r0[2];
+      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;
+      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;
+      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;
+      w1[1] = w1[1] | 0x80000000;
       break;
 
     case 24:
-      dst1[2] = src_r0[0];
-      dst1[3] = src_r0[1];
+      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;
+      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;
+      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;
+      w1[2] = w1[2] | 0x80000000;
       break;
 
     case 28:
-      dst1[3] = src_r0[0];
+      w1[3] = 0x80;
       break;
 
     case 29:
-      dst1[3] = src_l1[3]       | src_r0[0] <<  8;
+      w1[3] = w1[3] | 0x8000;
       break;
 
     case 30:
-      dst1[3] = src_l1[3]       | src_r0[0] << 16;
+      w1[3] = w1[3] | 0x800000;
       break;
 
     case 31:
-      dst1[3] = src_l1[3]       | src_r0[0] << 24;
+      w1[3] = w1[3] | 0x80000000;
+      break;
+
+    case 32:
+      w2[0] = 0x80;
+      break;
+
+    case 33:
+      w2[0] = w2[0] | 0x8000;
+      break;
+
+    case 34:
+      w2[0] = w2[0] | 0x800000;
+      break;
+
+    case 35:
+      w2[0] = w2[0] | 0x80000000;
+      break;
+
+    case 36:
+      w2[1] = 0x80;
+      break;
+
+    case 37:
+      w2[1] = w2[1] | 0x8000;
+      break;
+
+    case 38:
+      w2[1] = w2[1] | 0x800000;
+      break;
+
+    case 39:
+      w2[1] = w2[1] | 0x80000000;
+      break;
+
+    case 40:
+      w2[2] = 0x80;
+      break;
+
+    case 41:
+      w2[2] = w2[2] | 0x8000;
+      break;
+
+    case 42:
+      w2[2] = w2[2] | 0x800000;
+      break;
+
+    case 43:
+      w2[2] = w2[2] | 0x80000000;
+      break;
+
+    case 44:
+      w2[3] = 0x80;
+      break;
+
+    case 45:
+      w2[3] = w2[3] | 0x8000;
+      break;
+
+    case 46:
+      w2[3] = w2[3] | 0x800000;
+      break;
+
+    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])
+static 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:
-      dst2[3] = src_l2[3]       | src_r0[0] << 24;
+      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;
   }
 }
 
-// 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])
+static 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;
+  }
+}
+
+static void make_unicode_S (const u32 in[4], u32 out1[4], u32 out2[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;
+  #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 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;
+  #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
+}
 
-    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;
+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
 
-    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;
+static 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)
+static 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;
-      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 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;
-
-    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;
-
-    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;
-
-    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;
-
-    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;
-
-    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;
-
-    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;
-
-    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;
-
-    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;
-
-    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[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
 }
-
-*/