x86_64: Don't assume 8-byte pointer size
[openssl.git] / crypto / sha / asm / sha256-mb-x86_64.pl
index b2dba456b9bd6ab4dfa775e37547f7b394080e83..500a581a26265dbd1fbab6725347927609c13ff2 100644 (file)
 #      in real-life application are somewhat lower, e.g. for 2KB
 #      fragments they range from 75% to 130% (on Haswell);
 
-$flavour = shift;
-$output  = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
 
 $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
 
@@ -50,6 +51,11 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
+push(@INC,"${dir}","${dir}../../perlasm");
+require "x86_64-support.pl";
+
+$ptr_size=&pointer_size($flavour);
+
 $avx=0;
 
 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
@@ -67,11 +73,12 @@ if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
        $avx = ($1>=10) + ($1>=11);
 }
 
-if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([3-9]\.[0-9]+)/) {
+if (!$avx && `$ENV{CC} -v 2>&1` =~ /((?:^clang|LLVM) version|.*based on LLVM) ([0-9]+\.[0-9]+)/) {
        $avx = ($2>=3.0) + ($2>3.0);
 }
 
-open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\""
+    or die "can't call $xlate: $!";
 *STDOUT=*OUT;
 
 # void sha256_multi_block (
@@ -91,6 +98,7 @@ $inp="%rsi";  # 2nd arg
 $num="%edx";   # 3rd arg
 @ptr=map("%r$_",(8..11));
 $Tbl="%rbp";
+$inp_elm_size=2*$ptr_size;
 
 @V=($A,$B,$C,$D,$E,$F,$G,$H)=map("%xmm$_",(8..15));
 ($t1,$t2,$t3,$axb,$bxc,$Xi,$Xn,$sigma)=map("%xmm$_",(0..7));
@@ -289,9 +297,12 @@ $code.=<<___;
        xor     $num,$num
 ___
 for($i=0;$i<4;$i++) {
+    $ptr_reg=&pointer_register($flavour,@ptr[$i]);
     $code.=<<___;
-       mov     `16*$i+0`($inp),@ptr[$i]        # input pointer
-       mov     `16*$i+8`($inp),%ecx            # number of blocks
+       # input pointer
+       mov     `$inp_elm_size*$i+0`($inp),$ptr_reg
+       # number of blocks
+       mov     `$inp_elm_size*$i+$ptr_size`($inp),%ecx
        cmp     $num,%ecx
        cmovg   %ecx,$num                       # find maximum
        test    %ecx,%ecx
@@ -390,7 +401,7 @@ $code.=<<___;
 
        mov     `$REG_SZ*17+8`(%rsp),$num
        lea     $REG_SZ($ctx),$ctx
-       lea     `16*$REG_SZ/4`($inp),$inp
+       lea     `$inp_elm_size*$REG_SZ/4`($inp),$inp
        dec     $num
        jnz     .Loop_grande
 
@@ -468,9 +479,12 @@ $code.=<<___;
        xor     $num,$num
 ___
 for($i=0;$i<2;$i++) {
+    $ptr_reg=&pointer_register($flavour,@ptr[$i]);
     $code.=<<___;
-       mov     `16*$i+0`($inp),@ptr[$i]        # input pointer
-       mov     `16*$i+8`($inp),%ecx            # number of blocks
+       # input pointer
+       mov     `$inp_elm_size*$i+0`($inp),$ptr_reg
+       # number of blocks
+       mov     `$inp_elm_size*$i+$ptr_size`($inp),%ecx
        cmp     $num,%ecx
        cmovg   %ecx,$num                       # find maximum
        test    %ecx,%ecx
@@ -751,7 +765,7 @@ $code.=<<___;
        movq            @MSG0[1],0xe0-0x80($ctx)        # H1.H0
 
        lea     `$REG_SZ/2`($ctx),$ctx
-       lea     `16*2`($inp),$inp
+       lea     `$inp_elm_size*2`($inp),$inp
        dec     $num
        jnz     .Loop_grande_shaext
 
@@ -988,9 +1002,12 @@ $code.=<<___;
        xor     $num,$num
 ___
 for($i=0;$i<4;$i++) {
+    $ptr_reg=&pointer_register($flavour,@ptr[$i]);
     $code.=<<___;
-       mov     `16*$i+0`($inp),@ptr[$i]        # input pointer
-       mov     `16*$i+8`($inp),%ecx            # number of blocks
+       # input pointer
+       mov     `$inp_elm_size*$i+0`($inp),$ptr_reg
+       # number of blocks
+       mov     `$inp_elm_size*$i+$ptr_size`($inp),%ecx
        cmp     $num,%ecx
        cmovg   %ecx,$num                       # find maximum
        test    %ecx,%ecx
@@ -1087,7 +1104,7 @@ $code.=<<___;
 
        mov     `$REG_SZ*17+8`(%rsp),$num
        lea     $REG_SZ($ctx),$ctx
-       lea     `16*$REG_SZ/4`($inp),$inp
+       lea     `$inp_elm_size*$REG_SZ/4`($inp),$inp
        dec     $num
        jnz     .Loop_grande_avx
 
@@ -1178,9 +1195,12 @@ $code.=<<___;
        lea     `$REG_SZ*16`(%rsp),%rbx
 ___
 for($i=0;$i<8;$i++) {
+    $ptr_reg=&pointer_register($flavour,@ptr[$i]);
     $code.=<<___;
-       mov     `16*$i+0`($inp),@ptr[$i]        # input pointer
-       mov     `16*$i+8`($inp),%ecx            # number of blocks
+       # input pointer
+       mov     `$inp_elm_size*$i+0`($inp),$ptr_reg
+       # number of blocks
+       mov     `$inp_elm_size*$i+$ptr_size`($inp),%ecx
        cmp     $num,%ecx
        cmovg   %ecx,$num                       # find maximum
        test    %ecx,%ecx
@@ -1277,7 +1297,7 @@ $code.=<<___;
 
        #mov    `$REG_SZ*17+8`(%rsp),$num
        #lea    $REG_SZ($ctx),$ctx
-       #lea    `16*$REG_SZ/4`($inp),$inp
+       #lea    `$inp_elm_size*$REG_SZ/4`($inp),$inp
        #dec    $num
        #jnz    .Loop_grande_avx2
 
@@ -1611,4 +1631,4 @@ foreach (split("\n",$code)) {
        print $_,"\n";
 }
 
-close STDOUT;
+close STDOUT or die "error closing STDOUT: $!";