sha1-586.pl: update from master.
authorAndy Polyakov <appro@openssl.org>
Sun, 19 May 2013 19:32:29 +0000 (21:32 +0200)
committerAndy Polyakov <appro@openssl.org>
Sun, 19 May 2013 19:32:29 +0000 (21:32 +0200)
crypto/sha/asm/sha1-586.pl

index 1084d227fe0608b7e2ac61aa92334ff195f42e3f..632dbbe122bd3310c76af61e9b5d10b4ce35bdbb 100644 (file)
@@ -1,7 +1,7 @@
 #!/usr/bin/env perl
 
 # ====================================================================
 #!/usr/bin/env perl
 
 # ====================================================================
-# [Re]written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+# [Re]written by Andy Polyakov <appro@openssl.org> for the OpenSSL
 # project. The module is, however, dual licensed under OpenSSL and
 # CRYPTOGAMS licenses depending on where you obtain it. For further
 # details see http://www.openssl.org/~appro/cryptogams/.
 # project. The module is, however, dual licensed under OpenSSL and
 # CRYPTOGAMS licenses depending on where you obtain it. For further
 # details see http://www.openssl.org/~appro/cryptogams/.
 # PIII         11.5            -
 # P4           10.6            -
 # AMD K8       7.1             -
 # PIII         11.5            -
 # P4           10.6            -
 # AMD K8       7.1             -
-# Core2                7.3             6.1/+20%        -
-# Atom         12.5            9.5(*)/+32%     -
-# Westmere     7.3             5.6/+30%        -
-# Sandy Bridge 8.8             6.2/+40%        5.1(**)/+70%
+# Core2                7.3             6.0/+22%        -
+# Atom         12.5            9.3(*)/+35%     -
+# Westmere     7.3             5.5/+33%        -
+# Sandy Bridge 8.8             6.2/+40%        5.1(**)/+73%
+# Ivy Bridge   7.2             4.8/+51%        4.7(**)/+53%
+# Bulldozer    11.6            6.0/+92%
+# VIA Nano     10.6            7.4/+43%
 #
 # (*)  Loop is 1056 instructions long and expected result is ~8.25.
 #      It remains mystery [to me] why ILP is limited to 1.7.
 #
 # (*)  Loop is 1056 instructions long and expected result is ~8.25.
 #      It remains mystery [to me] why ILP is limited to 1.7.
@@ -116,6 +119,10 @@ $ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" &&
                `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
                $1>=2.03);      # first version supporting AVX
 
                `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ &&
                $1>=2.03);      # first version supporting AVX
 
+$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32" &&
+               `ml 2>&1` =~ /Version ([0-9]+)\./ &&
+               $1>=10);        # first version supporting AVX
+
 &external_label("OPENSSL_ia32cap_P") if ($xmm);
 
 
 &external_label("OPENSSL_ia32cap_P") if ($xmm);
 
 
@@ -416,6 +423,7 @@ my $Xi=4;                   # 4xSIMD Xupdate round, start pre-seeded
 my @X=map("xmm$_",(4..7,0..3));        # pre-seeded for $Xi=4
 my @V=($A,$B,$C,$D,$E);
 my $j=0;                       # hash round
 my @X=map("xmm$_",(4..7,0..3));        # pre-seeded for $Xi=4
 my @V=($A,$B,$C,$D,$E);
 my $j=0;                       # hash round
+my $rx=0;
 my @T=($T,$tmp1);
 my $inp;
 
 my @T=($T,$tmp1);
 my $inp;
 
@@ -501,8 +509,11 @@ my $_ror=sub { &ror(@_) };
        &movdqa (&QWP(0+16,"esp"),@X[-3&7]);
        &psubd  (@X[-3&7],@X[3]);
        &movdqa (&QWP(0+32,"esp"),@X[-2&7]);
        &movdqa (&QWP(0+16,"esp"),@X[-3&7]);
        &psubd  (@X[-3&7],@X[3]);
        &movdqa (&QWP(0+32,"esp"),@X[-2&7]);
+       &mov    (@T[1],$C);
        &psubd  (@X[-2&7],@X[3]);
        &psubd  (@X[-2&7],@X[3]);
+       &xor    (@T[1],$D);
        &movdqa (@X[0],@X[-3&7]);
        &movdqa (@X[0],@X[-3&7]);
+       &and    (@T[0],@T[1]);
        &jmp    (&label("loop"));
 
 ######################################################################
        &jmp    (&label("loop"));
 
 ######################################################################
@@ -609,7 +620,7 @@ sub Xupdate_ssse3_16_31()           # recall that $Xi starts wtih 4
 sub Xupdate_ssse3_32_79()
 { use integer;
   my $body = shift;
 sub Xupdate_ssse3_32_79()
 { use integer;
   my $body = shift;
-  my @insns = (&$body,&$body,&$body,&$body);   # 32 to 48 instructions
+  my @insns = (&$body,&$body,&$body,&$body);   # 32 to 44 instructions
   my ($a,$b,$c,$d,$e);
 
        &movdqa (@X[2],@X[-1&7])        if ($Xi==8);
   my ($a,$b,$c,$d,$e);
 
        &movdqa (@X[2],@X[-1&7])        if ($Xi==8);
@@ -743,51 +754,66 @@ sub Xtail_ssse3()
        foreach (@insns) { eval; }
 }
 
        foreach (@insns) { eval; }
 }
 
-sub body_00_19 () {
+sub body_00_19 () {    # ((c^d)&b)^d
+       # on start @T[0]=(c^d)&b
+       return &body_20_39()    if ($rx==19);   $rx++;
        (
        '($a,$b,$c,$d,$e)=@V;'.
        (
        '($a,$b,$c,$d,$e)=@V;'.
-       '&add   ($e,&DWP(4*($j&15),"esp"));',   # X[]+K xfer
-       '&xor   ($c,$d);',
+       '&$_ror ($b,$j?7:2);',  # $b>>>2
+       '&xor   (@T[0],$d);',
        '&mov   (@T[1],$a);',   # $b in next round
        '&mov   (@T[1],$a);',   # $b in next round
+
+       '&add   ($e,&DWP(4*($j&15),"esp"));',   # X[]+K xfer
+       '&xor   ($b,$c);',      # $c^$d for next round
+
        '&$_rol ($a,5);',
        '&$_rol ($a,5);',
-       '&and   (@T[0],$c);',   # ($b&($c^$d))
-       '&xor   ($c,$d);',      # restore $c
-       '&xor   (@T[0],$d);',
-       '&add   ($e,$a);',
-       '&$_ror ($b,$j?7:2);',  # $b>>>2
-       '&add   ($e,@T[0]);'    .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+       '&add   ($e,@T[0]);',
+       '&and   (@T[1],$b);',   # ($b&($c^$d)) for next round
+
+       '&xor   ($b,$c);',      # restore $b
+       '&add   ($e,$a);'       .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        );
 }
 
        );
 }
 
-sub body_20_39 () {
+sub body_20_39 () {    # b^d^c
+       # on entry @T[0]=b^d
+       return &body_40_59()    if ($rx==39);   $rx++;
        (
        '($a,$b,$c,$d,$e)=@V;'.
        (
        '($a,$b,$c,$d,$e)=@V;'.
-       '&add   ($e,&DWP(4*($j++&15),"esp"));', # X[]+K xfer
-       '&xor   (@T[0],$d);',   # ($b^$d)
+       '&add   ($e,&DWP(4*($j&15),"esp"));',   # X[]+K xfer
+       '&xor   (@T[0],$d)      if($j==19);'.
+       '&xor   (@T[0],$c)      if($j> 19);',   # ($b^$d^$c)
        '&mov   (@T[1],$a);',   # $b in next round
        '&mov   (@T[1],$a);',   # $b in next round
+
        '&$_rol ($a,5);',
        '&$_rol ($a,5);',
-       '&xor   (@T[0],$c);',   # ($b^$d^$c)
-       '&add   ($e,$a);',
+       '&add   ($e,@T[0]);',
+       '&xor   (@T[1],$c)      if ($j< 79);',  # $b^$d for next round
+
        '&$_ror ($b,7);',       # $b>>>2
        '&$_ror ($b,7);',       # $b>>>2
-       '&add   ($e,@T[0]);'    .'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+       '&add   ($e,$a);'       .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        );
 }
 
        );
 }
 
-sub body_40_59 () {
+sub body_40_59 () {    # ((b^c)&(c^d))^c
+       # on entry @T[0]=(b^c), (c^=d)
+       $rx++;
        (
        '($a,$b,$c,$d,$e)=@V;'.
        (
        '($a,$b,$c,$d,$e)=@V;'.
-       '&mov   (@T[1],$c);',
-       '&xor   ($c,$d);',
-       '&add   ($e,&DWP(4*($j++&15),"esp"));', # X[]+K xfer
-       '&and   (@T[1],$d);',
-       '&and   (@T[0],$c);',   # ($b&($c^$d))
+       '&add   ($e,&DWP(4*($j&15),"esp"));',   # X[]+K xfer
+       '&and   (@T[0],$c)      if ($j>=40);',  # (b^c)&(c^d)
+       '&xor   ($c,$d)         if ($j>=40);',  # restore $c
+
        '&$_ror ($b,7);',       # $b>>>2
        '&$_ror ($b,7);',       # $b>>>2
-       '&add   ($e,@T[1]);',
-       '&mov   (@T[1],$a);',   # $b in next round
+       '&mov   (@T[1],$a);',   # $b for next round
+       '&xor   (@T[0],$c);',
+
        '&$_rol ($a,5);',
        '&add   ($e,@T[0]);',
        '&$_rol ($a,5);',
        '&add   ($e,@T[0]);',
-       '&xor   ($c,$d);',      # restore $c
-       '&add   ($e,$a);'       .'unshift(@V,pop(@V)); unshift(@T,pop(@T));'
+       '&xor   (@T[1],$c)      if ($j==59);'.
+       '&xor   (@T[1],$b)      if ($j< 59);',  # b^c for next round
+
+       '&xor   ($b,$c)         if ($j< 59);',  # c^d for next round
+       '&add   ($e,$a);'       .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));'
        );
 }
 
        );
 }
 
@@ -825,10 +851,13 @@ sub body_40_59 () {
        &mov    (&DWP(4,@T[1]),@T[0]);
        &add    ($E,&DWP(16,@T[1]));
        &mov    (&DWP(8,@T[1]),$C);
        &mov    (&DWP(4,@T[1]),@T[0]);
        &add    ($E,&DWP(16,@T[1]));
        &mov    (&DWP(8,@T[1]),$C);
-       &mov    ($B,@T[0]);
+       &mov    ($B,$C);
        &mov    (&DWP(12,@T[1]),$D);
        &mov    (&DWP(12,@T[1]),$D);
+       &xor    ($B,$D);
        &mov    (&DWP(16,@T[1]),$E);
        &mov    (&DWP(16,@T[1]),$E);
+       &and    ($B,@T[0]);
        &movdqa (@X[0],@X[-3&7]);
        &movdqa (@X[0],@X[-3&7]);
+       &xchg   ($B,@T[0]);
 
        &jmp    (&label("loop"));
 
 
        &jmp    (&label("loop"));
 
@@ -853,6 +882,8 @@ sub body_40_59 () {
 
 &function_end("_sha1_block_data_order_ssse3");
 
 
 &function_end("_sha1_block_data_order_ssse3");
 
+$rx=0; # reset
+
 if ($ymm) {
 my $Xi=4;                      # 4xSIMD Xupdate round, start pre-seeded
 my @X=map("xmm$_",(4..7,0..3));        # pre-seeded for $Xi=4
 if ($ymm) {
 my $Xi=4;                      # 4xSIMD Xupdate round, start pre-seeded
 my @X=map("xmm$_",(4..7,0..3));        # pre-seeded for $Xi=4
@@ -940,8 +971,11 @@ my $_ror=sub { &shrd(@_[0],@_) };
        &vpaddd (@X[1],@X[-3&7],@X[3]);
        &vpaddd (@X[2],@X[-2&7],@X[3]);
        &vmovdqa(&QWP(0,"esp"),@X[0]);          # X[]+K xfer to IALU
        &vpaddd (@X[1],@X[-3&7],@X[3]);
        &vpaddd (@X[2],@X[-2&7],@X[3]);
        &vmovdqa(&QWP(0,"esp"),@X[0]);          # X[]+K xfer to IALU
+       &mov    (@T[1],$C);
        &vmovdqa(&QWP(0+16,"esp"),@X[1]);
        &vmovdqa(&QWP(0+16,"esp"),@X[1]);
+       &xor    (@T[1],$D);
        &vmovdqa(&QWP(0+32,"esp"),@X[2]);
        &vmovdqa(&QWP(0+32,"esp"),@X[2]);
+       &and    (@T[0],@T[1]);
        &jmp    (&label("loop"));
 
 sub Xupdate_avx_16_31()                # recall that $Xi starts wtih 4
        &jmp    (&label("loop"));
 
 sub Xupdate_avx_16_31()                # recall that $Xi starts wtih 4
@@ -1025,7 +1059,7 @@ sub Xupdate_avx_16_31()           # recall that $Xi starts wtih 4
 sub Xupdate_avx_32_79()
 { use integer;
   my $body = shift;
 sub Xupdate_avx_32_79()
 { use integer;
   my $body = shift;
-  my @insns = (&$body,&$body,&$body,&$body);   # 32 to 48 instructions
+  my @insns = (&$body,&$body,&$body,&$body);   # 32 to 44 instructions
   my ($a,$b,$c,$d,$e);
 
        &vpalignr(@X[2],@X[-1&7],@X[-2&7],8);   # compose "X[-6]"
   my ($a,$b,$c,$d,$e);
 
        &vpalignr(@X[2],@X[-1&7],@X[-2&7],8);   # compose "X[-6]"
@@ -1188,10 +1222,13 @@ sub Xtail_avx()
        &add    ($D,&DWP(12,@T[1]));
        &mov    (&DWP(4,@T[1]),@T[0]);
        &add    ($E,&DWP(16,@T[1]));
        &add    ($D,&DWP(12,@T[1]));
        &mov    (&DWP(4,@T[1]),@T[0]);
        &add    ($E,&DWP(16,@T[1]));
+       &mov    ($B,$C);
        &mov    (&DWP(8,@T[1]),$C);
        &mov    (&DWP(8,@T[1]),$C);
-       &mov    ($B,@T[0]);
+       &xor    ($B,$D);
        &mov    (&DWP(12,@T[1]),$D);
        &mov    (&DWP(12,@T[1]),$D);
+       &and    ($B,@T[0]);
        &mov    (&DWP(16,@T[1]),$E);
        &mov    (&DWP(16,@T[1]),$E);
+       &xchg   ($B,@T[0]);
 
        &jmp    (&label("loop"));
 
 
        &jmp    (&label("loop"));