Andy,

This patch implements an optimization of round2 of the AMD64
implementation of MD5. It improves the global throughput of MD5 by
about 6%. Credit should be given to Charles Liu for this. See
  http://epita.fr/~bevand_m/papers/md5-amd64.html
  for more information.

-- 
 Marc Bevand                              http://epita.fr/~bevand_m
 Computer Science School EPITA - System, Network and Security Dept.
This patch implements an optimization of round2 of the AMD64
implementation of MD5. It improves the global throughput of MD5 by
about 6%. Credit should be given to Charles Liu for this. See
  http://epita.fr/~bevand_m/papers/md5-amd64.html
for more information.

Index: crypto/md5/asm/md5-x86_64.pl
===================================================================
RCS file: 
/home/after/projects/cvsroot.openssl/openssl/crypto/md5/asm/md5-x86_64.pl,v
retrieving revision 1.2
diff -u -r1.2 md5-x86_64.pl
--- crypto/md5/asm/md5-x86_64.pl        3 May 2005 23:03:31 -0000       1.2
+++ crypto/md5/asm/md5-x86_64.pl        19 Aug 2005 07:18:31 -0000
@@ -15,7 +15,7 @@
 #   dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s)
 #   %r10d = X[k_next]
 #   %r11d = z' (copy of z for the next step)
-# Each round1_step() takes about 5.71 clocks (9 instructions, 1.58 IPC)
+# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC)
 sub round1_step
 {
     my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
@@ -37,22 +37,26 @@
 # round2_step() does:
 #   dst = x + ((dst + G(x,y,z) + X[k] + T_i) <<< s)
 #   %r10d = X[k_next]
-#   %r11d = y' (copy of y for the next step)
-# Each round2_step() takes about 6.22 clocks (9 instructions, 1.45 IPC)
+#   %r11d = z' (copy of z for the next step)
+#   %r12d = z' (copy of z for the next step)
+# Each round2_step() takes about 5.4 clocks (11 instructions, 2.0 IPC)
 sub round2_step
 {
     my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
     $code .= " mov     1*4(%rsi),      %r10d           /* (NEXT STEP) X[1] 
*/\n" if ($pos == -1);
-    $code .= " mov     %ecx,           %r11d           /* (NEXT STEP) y' = 
%ecx */\n" if ($pos == -1);
+    $code .= " mov     %edx,           %r11d           /* (NEXT STEP) z' = 
%edx */\n" if ($pos == -1);
+    $code .= " mov     %edx,           %r12d           /* (NEXT STEP) z' = 
%edx */\n" if ($pos == -1);
     $code .= <<EOF;
-       xor     $x,             %r11d           /* x ^ ... */
+       not     %r11d                           /* not z */
        lea     $T_i($dst,%r10d),$dst           /* Const + dst + ... */
-       and     $z,             %r11d           /* z & ... */
-       xor     $y,             %r11d           /* y ^ ... */
+       and     $x,             %r12d           /* x & z */
+       and     $y,             %r11d           /* y & (not z) */
        mov     $k_next*4(%rsi),%r10d           /* (NEXT STEP) X[$k_next] */
-       add     %r11d,          $dst            /* dst += ... */
+       or      %r11d,          %r12d           /* (y & (not z)) | (x & z) */
+       mov     $y,             %r11d           /* (NEXT STEP) z' = $y */
+       add     %r12d,          $dst            /* dst += ... */
+       mov     $y,             %r12d           /* (NEXT STEP) z' = $y */
        rol     \$$s,           $dst            /* dst <<< s */
-       mov     $x,             %r11d           /* (NEXT STEP) y' = $x */
        add     $x,             $dst            /* dst += x */
 EOF
 }
@@ -61,7 +65,7 @@
 #   dst = x + ((dst + H(x,y,z) + X[k] + T_i) <<< s)
 #   %r10d = X[k_next]
 #   %r11d = y' (copy of y for the next step)
-# Each round3_step() takes about 4.26 clocks (8 instructions, 1.88 IPC)
+# Each round3_step() takes about 4.2 clocks (8 instructions, 1.9 IPC)
 sub round3_step
 {
     my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
@@ -83,7 +87,7 @@
 #   dst = x + ((dst + I(x,y,z) + X[k] + T_i) <<< s)
 #   %r10d = X[k_next]
 #   %r11d = not z' (copy of not z for the next step)
-# Each round4_step() takes about 5.27 clocks (9 instructions, 1.71 IPC)
+# Each round4_step() takes about 5.2 clocks (9 instructions, 1.7 IPC)
 sub round4_step
 {
     my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_;
@@ -116,6 +120,7 @@
 md5_block_asm_host_order:
        push    %rbp
        push    %rbx
+       push    %r12
        push    %r14
        push    %r15
 
@@ -234,6 +239,7 @@
 
        pop     %r15
        pop     %r14
+       pop     %r12
        pop     %rbx
        pop     %rbp
        ret

Reply via email to