x86_64: Don't assume 8-byte pointer size
[openssl.git] / crypto / sha / asm / sha1-mb-x86_64.pl
index 2f6b35f3559ca4edadc75bfbfd594c904065894b..ef1228786f73577d3696775cdc391f6516509b8e 100644 (file)
@@ -1,7 +1,7 @@
 #! /usr/bin/env perl
 # Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved.
 #
-# Licensed under the OpenSSL license (the "License").  You may not use
+# Licensed under the Apache License 2.0 (the "License").  You may not use
 # this file except in compliance with the License.  You can obtain a copy
 # in the file LICENSE in the source distribution or at
 # https://www.openssl.org/source/license.html
 #      in real-life application are somewhat lower, e.g. for 2KB
 #      fragments they range from 30% to 100% (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$/);
 
@@ -49,6 +50,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`
@@ -66,11 +72,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 sha1_multi_block (
@@ -87,6 +94,7 @@ $inp="%rsi";  # 2nd arg
 $num="%edx";
 @ptr=map("%r$_",(8..11));
 $Tbl="%rbp";
+$inp_elm_size=2*$ptr_size;
 
 @V=($A,$B,$C,$D,$E)=map("%xmm$_",(0..4));
 ($t0,$t1,$t2,$t3,$tx)=map("%xmm$_",(5..9));
@@ -363,6 +371,7 @@ $code.=<<___;
 .type  sha1_multi_block,\@function,3
 .align 32
 sha1_multi_block:
+.cfi_startproc
        mov     OPENSSL_ia32cap_P+4(%rip),%rcx
        bt      \$61,%rcx                       # check SHA bit
        jc      _shaext_shortcut
@@ -373,8 +382,11 @@ $code.=<<___ if ($avx);
 ___
 $code.=<<___;
        mov     %rsp,%rax
+.cfi_def_cfa_register  %rax
        push    %rbx
+.cfi_push      %rbx
        push    %rbp
+.cfi_push      %rbx
 ___
 $code.=<<___ if ($win64);
        lea     -0xa8(%rsp),%rsp
@@ -393,6 +405,7 @@ $code.=<<___;
        sub     \$`$REG_SZ*18`,%rsp
        and     \$-256,%rsp
        mov     %rax,`$REG_SZ*17`(%rsp)         # original %rsp
+.cfi_cfa_expression    %rsp+`$REG_SZ*17`,deref,+8
 .Lbody:
        lea     K_XX_XX(%rip),$Tbl
        lea     `$REG_SZ*16`(%rsp),%rbx
@@ -402,9 +415,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
@@ -439,7 +455,7 @@ for(;$i<80;$i++)    { &BODY_20_39($i,@V); unshift(@V,pop(@V)); }
 $code.=<<___;
        movdqa  (%rbx),@Xi[0]                   # pull counters
        mov     \$1,%ecx
-       cmp     4*0(%rbx),%ecx                  # examinte counters
+       cmp     4*0(%rbx),%ecx                  # examine counters
        pxor    $t2,$t2
        cmovge  $Tbl,@ptr[0]                    # cancel input
        cmp     4*1(%rbx),%ecx
@@ -481,12 +497,13 @@ $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
 
 .Ldone:
        mov     `$REG_SZ*17`(%rsp),%rax         # original %rsp
+.cfi_def_cfa   %rax,8
 ___
 $code.=<<___ if ($win64);
        movaps  -0xb8(%rax),%xmm6
@@ -502,10 +519,14 @@ $code.=<<___ if ($win64);
 ___
 $code.=<<___;
        mov     -16(%rax),%rbp
+.cfi_restore   %rbp
        mov     -8(%rax),%rbx
+.cfi_restore   %rbx
        lea     (%rax),%rsp
+.cfi_def_cfa_register  %rsp
 .Lepilogue:
        ret
+.cfi_endproc
 .size  sha1_multi_block,.-sha1_multi_block
 ___
                                                {{{
@@ -517,10 +538,14 @@ $code.=<<___;
 .type  sha1_multi_block_shaext,\@function,3
 .align 32
 sha1_multi_block_shaext:
+.cfi_startproc
 _shaext_shortcut:
        mov     %rsp,%rax
+.cfi_def_cfa_register  %rax
        push    %rbx
+.cfi_push      %rbx
        push    %rbp
+.cfi_push      %rbp
 ___
 $code.=<<___ if ($win64);
        lea     -0xa8(%rsp),%rsp
@@ -550,9 +575,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
@@ -735,7 +763,7 @@ $code.=<<___;
        movq            $E0,0x80-0x40($ctx)     # e1.e0
 
        lea     `$REG_SZ/2`($ctx),$ctx
-       lea     `16*2`($inp),$inp
+       lea     `$inp_elm_size*2`($inp),$inp
        dec     $num
        jnz     .Loop_grande_shaext
 
@@ -756,10 +784,14 @@ $code.=<<___ if ($win64);
 ___
 $code.=<<___;
        mov     -16(%rax),%rbp
+.cfi_restore   %rbp
        mov     -8(%rax),%rbx
+.cfi_restore   %rbx
        lea     (%rax),%rsp
+.cfi_def_cfa_register  %rsp
 .Lepilogue_shaext:
        ret
+.cfi_endproc
 .size  sha1_multi_block_shaext,.-sha1_multi_block_shaext
 ___
                                                }}}
@@ -1002,6 +1034,7 @@ $code.=<<___;
 .type  sha1_multi_block_avx,\@function,3
 .align 32
 sha1_multi_block_avx:
+.cfi_startproc
 _avx_shortcut:
 ___
 $code.=<<___ if ($avx>1);
@@ -1016,8 +1049,11 @@ $code.=<<___ if ($avx>1);
 ___
 $code.=<<___;
        mov     %rsp,%rax
+.cfi_def_cfa_register  %rax
        push    %rbx
+.cfi_push      %rbx
        push    %rbp
+.cfi_push      %rbp
 ___
 $code.=<<___ if ($win64);
        lea     -0xa8(%rsp),%rsp
@@ -1036,6 +1072,7 @@ $code.=<<___;
        sub     \$`$REG_SZ*18`, %rsp
        and     \$-256,%rsp
        mov     %rax,`$REG_SZ*17`(%rsp)         # original %rsp
+.cfi_cfa_expression    %rsp+`$REG_SZ*17`,deref,+8
 .Lbody_avx:
        lea     K_XX_XX(%rip),$Tbl
        lea     `$REG_SZ*16`(%rsp),%rbx
@@ -1046,9 +1083,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
@@ -1119,12 +1159,13 @@ $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
 
 .Ldone_avx:
        mov     `$REG_SZ*17`(%rsp),%rax         # original %rsp
+.cfi_def_cfa   %rax,8
        vzeroupper
 ___
 $code.=<<___ if ($win64);
@@ -1141,10 +1182,14 @@ $code.=<<___ if ($win64);
 ___
 $code.=<<___;
        mov     -16(%rax),%rbp
+.cfi_restore   %rbp
        mov     -8(%rax),%rbx
+.cfi_restore   %rbx
        lea     (%rax),%rsp
+.cfi_def_cfa_register  %rsp
 .Lepilogue_avx:
        ret
+.cfi_endproc
 .size  sha1_multi_block_avx,.-sha1_multi_block_avx
 ___
 
@@ -1164,14 +1209,22 @@ $code.=<<___;
 .type  sha1_multi_block_avx2,\@function,3
 .align 32
 sha1_multi_block_avx2:
+.cfi_startproc
 _avx2_shortcut:
        mov     %rsp,%rax
+.cfi_def_cfa_register  %rax
        push    %rbx
+.cfi_push      %rbx
        push    %rbp
+.cfi_push      %rbp
        push    %r12
+.cfi_push      %r12
        push    %r13
+.cfi_push      %r13
        push    %r14
+.cfi_push      %r14
        push    %r15
+.cfi_push      %r15
 ___
 $code.=<<___ if ($win64);
        lea     -0xa8(%rsp),%rsp
@@ -1190,6 +1243,7 @@ $code.=<<___;
        sub     \$`$REG_SZ*18`, %rsp
        and     \$-256,%rsp
        mov     %rax,`$REG_SZ*17`(%rsp)         # original %rsp
+.cfi_cfa_expression    %rsp+`$REG_SZ*17`,deref,+8
 .Lbody_avx2:
        lea     K_XX_XX(%rip),$Tbl
        shr     \$1,$num
@@ -1201,9 +1255,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
@@ -1274,12 +1331,13 @@ $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
 
 .Ldone_avx2:
        mov     `$REG_SZ*17`(%rsp),%rax         # original %rsp
+.cfi_def_cfa   %rax,8
        vzeroupper
 ___
 $code.=<<___ if ($win64);
@@ -1296,14 +1354,22 @@ $code.=<<___ if ($win64);
 ___
 $code.=<<___;
        mov     -48(%rax),%r15
+.cfi_restore   %r15
        mov     -40(%rax),%r14
+.cfi_restore   %r14
        mov     -32(%rax),%r13
+.cfi_restore   %r13
        mov     -24(%rax),%r12
+.cfi_restore   %r12
        mov     -16(%rax),%rbp
+.cfi_restore   %rbp
        mov     -8(%rax),%rbx
+.cfi_restore   %rbx
        lea     (%rax),%rsp
+.cfi_def_cfa_register  %rsp
 .Lepilogue_avx2:
        ret
+.cfi_endproc
 .size  sha1_multi_block_avx2,.-sha1_multi_block_avx2
 ___
                                                }       }}}
@@ -1462,10 +1528,10 @@ avx2_handler:
        mov     -48(%rax),%r15
        mov     %rbx,144($context)      # restore context->Rbx
        mov     %rbp,160($context)      # restore context->Rbp
-       mov     %r12,216($context)      # restore cotnext->R12
-       mov     %r13,224($context)      # restore cotnext->R13
-       mov     %r14,232($context)      # restore cotnext->R14
-       mov     %r15,240($context)      # restore cotnext->R15
+       mov     %r12,216($context)      # restore context->R12
+       mov     %r13,224($context)      # restore context->R13
+       mov     %r14,232($context)      # restore context->R14
+       mov     %r15,240($context)      # restore context->R15
 
        lea     -56-10*16(%rax),%rsi
        lea     512($context),%rdi      # &context.Xmm6
@@ -1579,4 +1645,4 @@ foreach (split("\n",$code)) {
        print $_,"\n";
 }
 
-close STDOUT;
+close STDOUT or die "error closing STDOUT: $!";