symm/salsa20-arm-neon.S: Indent some reordered instructions.
[catacomb] / symm / salsa20-arm-neon.S
index 9d553d3..ce37948 100644 (file)
 /// MA 02111-1307, USA.
 
 ///--------------------------------------------------------------------------
-/// External definitions.
+/// Preliminaries.
 
 #include "config.h"
 #include "asm-common.h"
 
-///--------------------------------------------------------------------------
-/// Main.code.
-
        .arch   armv7-a
        .fpu    neon
+
        .text
 
+///--------------------------------------------------------------------------
+/// Main code.
+
 FUNC(salsa20_core_arm_neon)
 
        // Arguments are in registers.
@@ -71,11 +72,6 @@ FUNC(salsa20_core_arm_neon)
        //      [ 8  9 10 11]           [ 8 13  2  7] (c, q10)
        //      [12 13 14 15]           [12  1  6 11] (d, q11)
        //
-       //      [ 0  1  2  3] (a, q8)
-       //      [ 4  5  6  7] (b, q9)
-       //      [ 8  9 10 11] (c, q10)
-       //      [12 13 14 15] (d, q11)
-       //
        // We need a copy for later.  Rather than waste time copying them by
        // hand, we'll use the three-address nature of the instruction set.
        // But this means that the main loop is offset by a bit.
@@ -102,7 +98,7 @@ FUNC(salsa20_core_arm_neon)
 
        // d ^= (c + b) <<< 13
        vadd.u32 q0, q10, q9
-       vext.32 q9, q9, q9, #3
+        vext.32 q9, q9, q9, #3
        vshl.u32 q1, q0, #13
        vshr.u32 q0, q0, #19
        vorr    q0, q0, q1
@@ -110,8 +106,8 @@ FUNC(salsa20_core_arm_neon)
 
        // a ^= (d + c) <<< 18
        vadd.u32 q0, q11, q10
-       vext.32 q10, q10, q10, #2
-       vext.32 q11, q11, q11, #1
+        vext.32 q10, q10, q10, #2
+        vext.32 q11, q11, q11, #1
        vshl.u32 q1, q0, #18
        vshr.u32 q0, q0, #14
        vorr    q0, q0, q1
@@ -205,33 +201,28 @@ FUNC(salsa20_core_arm_neon)
 
        b       0b
 
-       // Almost there.  Firstly the feedfoward addition.
+       // Almost there.  Firstly the feedfoward addition.  Also, establish a
+       // constant which will be useful later.
 9:     vadd.u32 q0, q8, q12                    //  0,  5, 10, 15
-       vadd.u32 q9, q9, q13                    //  4,  9, 14,  3
-       vadd.u32 q10, q10, q14                  //  8, 13,  2,  7
-       vadd.u32 q11, q11, q15                  // 12,  1,  6, 11
+        vmov.i64 q12, #0xffffffff              // = (0, -1; 0, -1)
+       vadd.u32 q1, q9, q13                    //  4,  9, 14,  3
+       vadd.u32 q2, q10, q14                   //  8, 13,  2,  7
+       vadd.u32 q3, q11, q15                   // 12,  1,  6, 11
 
        // Next we must undo the permutation which was already applied to the
-       // input.  This can be done juggling values in registers, with the
-       // following fancy footwork: some row rotations, a transpose, and
-       // some more rotations.
-       vext.32 q9, q9, q9, #3                  //  3,  4,  9, 14
-       vext.32 q10, q10, q10, #2               //  2,  7,  8, 13
-       vext.32 q11, q11, q11, #1               //  1,  6, 11, 12
-
-       vzip.32 q0, q10                         //  0,  2,  5,  7
-                                               // 10,  8, 15, 13
-       vzip.32 q11, q9                         //  1,  3,  6,  4
-                                               // 11,  9, 12, 14
-
-       vzip.32 q0, q11                         //  0,  1,  2,  3
-                                               //  5,  6,  7,  4
-       vzip.32 q10, q9                         // 10, 11,  8,  9
-                                               // 15, 12, 13, 14
-
-       vext.32 q1, q11, q11, #3                //  4,  5,  6,  7
-       vext.32 q2, q10, q10, #2                //  8,  9, 10, 11
-       vext.32 q3, q9, q9, #1                  // 12, 13, 14, 15
+       // input.  The core trick is from Dan Bernstein's `armneon3'
+       // implementation, but with a lot of liposuction.
+       vmov    q15, q0
+
+       // Sort out the columns by pairs.
+       vbif    q0, q3, q12                     //  0,  1, 10, 11
+       vbif    q3, q2, q12                     // 12, 13,  6,  7
+       vbif    q2, q1, q12                     //  8,  9,  2,  3
+       vbif    q1, q15, q12                    //  4,  5, 14, 15
+
+       // Now fix up the remaining discrepancies.
+       vswp    D1(q0), D1(q2)
+       vswp    D1(q1), D1(q3)
 
        // And with that, we're done.
        vstmia  r2, {QQ(q0, q3)}