x86_64: Don't assume 8-byte pointer size
[openssl.git] / crypto / aes / asm / aesni-mb-x86_64.pl
index c4151feb7e3a0c446c73196f264a2964a7d23669..0b86285d30195f29e0a6e6d94e79495f672c5896 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
 # (*)  Sandy/Ivy Bridge are known to handle high interleave factors
 #      suboptimally;
 
-$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$/);
 
@@ -53,6 +54,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`
@@ -70,11 +76,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 aesni_multi_cbc_encrypt (
@@ -86,6 +93,8 @@ $inp="%rdi";  # 1st arg
 $key="%rsi";   # 2nd arg
 $num="%edx";
 
+$inp_elm_size=2*$ptr_size+8+16;
+
 @inptr=map("%r$_",(8..11));
 @outptr=map("%r$_",(12..15));
 
@@ -161,21 +170,25 @@ $code.=<<___;
 .Lenc4x_body:
        movdqu  ($key),$zero                    # 0-round key
        lea     0x78($key),$key                 # size optimization
-       lea     40*2($inp),$inp
+       lea     $inp_elm_size*2($inp),$inp
 
 .Lenc4x_loop_grande:
        mov     $num,24(%rsp)                   # original $num
        xor     $num,$num
 ___
 for($i=0;$i<4;$i++) {
+    $inptr_reg=&pointer_register($flavour,@inptr[$i]);
+    $outptr_reg=&pointer_register($flavour,@outptr[$i]);
     $code.=<<___;
-       mov     `40*$i+16-40*2`($inp),$one      # borrow $one for number of blocks
-       mov     `40*$i+0-40*2`($inp),@inptr[$i]
+       # borrow $one for number of blocks
+       mov     `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*2`($inp),$one
+       mov     `$inp_elm_size*$i+0-$inp_elm_size*2`($inp),$inptr_reg
        cmp     $num,$one
-       mov     `40*$i+8-40*2`($inp),@outptr[$i]
+       mov     `$inp_elm_size*$i+$ptr_size-$inp_elm_size*2`($inp),$outptr_reg
        cmovg   $one,$num                       # find maximum
        test    $one,$one
-       movdqu  `40*$i+24-40*2`($inp),@out[$i]  # load IV
+       # load IV
+       movdqu  `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*2`($inp),@out[$i]
        mov     $one,`32+4*$i`(%rsp)            # initialize counters
        cmovle  %rsp,@inptr[$i]                 # cancel input
 ___
@@ -333,14 +346,15 @@ $code.=<<___;
 
        #pxor   @inp[0],@out[0]
        #pxor   @inp[1],@out[1]
-       #movdqu @out[0],`40*0+24-40*2`($inp)    # output iv FIX ME!
+       # output iv FIX ME!
+       #movdqu @out[0],`$inp_elm_size*0+2*$ptr_size+8-$inp_elm_size*2`($inp)
        #pxor   @inp[2],@out[2]
-       #movdqu @out[1],`40*1+24-40*2`($inp)
+       #movdqu @out[1],`$inp_elm_size*1+2*$ptr_size+8-$inp_elm_size*2`($inp)
        #pxor   @inp[3],@out[3]
-       #movdqu @out[2],`40*2+24-40*2`($inp)    # won't fix, let caller
-       #movdqu @out[3],`40*3+24-40*2`($inp)    # figure this out...
+       #movdqu @out[2],`$inp_elm_size*2+2*$ptr_size+8-$inp_elm_size*2`($inp)   # won't fix, let caller
+       #movdqu @out[3],`$inp_elm_size*3+2*$ptr_size+8-$inp_elm_size*2`($inp)   # figure this out...
 
-       lea     `40*4`($inp),$inp
+       lea     `$inp_elm_size*4`($inp),$inp
        dec     $num
        jnz     .Lenc4x_loop_grande
 
@@ -438,21 +452,25 @@ $code.=<<___;
 .Ldec4x_body:
        movdqu  ($key),$zero                    # 0-round key
        lea     0x78($key),$key                 # size optimization
-       lea     40*2($inp),$inp
+       lea     $inp_elm_size*2($inp),$inp
 
 .Ldec4x_loop_grande:
        mov     $num,24(%rsp)                   # original $num
        xor     $num,$num
 ___
 for($i=0;$i<4;$i++) {
+    $inptr_reg=&pointer_register($flavour,@inptr[$i]);
+    $outptr_reg=&pointer_register($flavour,@outptr[$i]);
     $code.=<<___;
-       mov     `40*$i+16-40*2`($inp),$one      # borrow $one for number of blocks
-       mov     `40*$i+0-40*2`($inp),@inptr[$i]
+       # borrow $one for number of blocks
+       mov     `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*2`($inp),$one
+       mov     `$inp_elm_size*$i+0-$inp_elm_size*2`($inp),$inptr_reg
        cmp     $num,$one
-       mov     `40*$i+8-40*2`($inp),@outptr[$i]
+       mov     `$inp_elm_size*$i+$ptr_size-$inp_elm_size*2`($inp),$outptr_reg
        cmovg   $one,$num                       # find maximum
        test    $one,$one
-       movdqu  `40*$i+24-40*2`($inp),@inp[$i]  # load IV
+       # load IV
+       movdqu  `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*2`($inp),@inp[$i]
        mov     $one,`32+4*$i`(%rsp)            # initialize counters
        cmovle  %rsp,@inptr[$i]                 # cancel input
 ___
@@ -608,7 +626,7 @@ $code.=<<___;
 .cfi_def_cfa   %rax,8
        mov     24(%rsp),$num
 
-       lea     `40*4`($inp),$inp
+       lea     `$inp_elm_size*4`($inp),$inp
        dec     $num
        jnz     .Ldec4x_loop_grande
 
@@ -707,7 +725,7 @@ $code.=<<___;
        vzeroupper
        vmovdqu ($key),$zero                    # 0-round key
        lea     0x78($key),$key                 # size optimization
-       lea     40*4($inp),$inp
+       lea     `$inp_elm_size*4`($inp),$inp
        shr     \$1,$num
 
 .Lenc8x_loop_grande:
@@ -716,14 +734,20 @@ $code.=<<___;
 ___
 for($i=0;$i<8;$i++) {
   my $temp = $i ? $offload : $offset;
+    $ptr_reg=&pointer_register($flavour,@ptr[$i]);
+    $temp_reg=&pointer_register($flavour,$temp);
     $code.=<<___;
-       mov     `40*$i+16-40*4`($inp),$one      # borrow $one for number of blocks
-       mov     `40*$i+0-40*4`($inp),@ptr[$i]   # input pointer
+       # borrow $one for number of blocks
+       mov     `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*4`($inp),$one
+       # input pointer
+       mov     `$inp_elm_size*$i+0-$inp_elm_size*4`($inp),$ptr_reg
        cmp     $num,$one
-       mov     `40*$i+8-40*4`($inp),$temp      # output pointer
+       # output pointer
+       mov     `$inp_elm_size*$i+$ptr_size-$inp_elm_size*4`($inp),$temp_reg
        cmovg   $one,$num                       # find maximum
        test    $one,$one
-       vmovdqu `40*$i+24-40*4`($inp),@out[$i]  # load IV
+       # load IV
+       vmovdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*4`($inp),@out[$i]
        mov     $one,`32+4*$i`(%rsp)            # initialize counters
        cmovle  %rsp,@ptr[$i]                   # cancel input
        sub     @ptr[$i],$temp                  # distance between input and output
@@ -908,7 +932,7 @@ $code.=<<___;
        mov     16(%rsp),%rax                   # original %rsp
 .cfi_def_cfa   %rax,8
        #mov    24(%rsp),$num
-       #lea    `40*8`($inp),$inp
+       #lea    `$inp_elm_size*8`($inp),$inp
        #dec    $num
        #jnz    .Lenc8x_loop_grande
 
@@ -1000,7 +1024,7 @@ $code.=<<___;
        vzeroupper
        vmovdqu ($key),$zero                    # 0-round key
        lea     0x78($key),$key                 # size optimization
-       lea     40*4($inp),$inp
+       lea     `$inp_elm_size*4`($inp),$inp
        shr     \$1,$num
 
 .Ldec8x_loop_grande:
@@ -1009,14 +1033,20 @@ $code.=<<___;
 ___
 for($i=0;$i<8;$i++) {
   my $temp = $i ? $offload : $offset;
+    $ptr_reg=&pointer_register($flavour,@ptr[$i]);
+    $temp_reg=&pointer_register($flavour,$temp);
     $code.=<<___;
-       mov     `40*$i+16-40*4`($inp),$one      # borrow $one for number of blocks
-       mov     `40*$i+0-40*4`($inp),@ptr[$i]   # input pointer
+       # borrow $one for number of blocks
+       mov     `$inp_elm_size*$i+2*$ptr_size-$inp_elm_size*4`($inp),$one
+       # input pointer
+       mov     `$inp_elm_size*$i+0-$inp_elm_size*4`($inp),$ptr_reg
        cmp     $num,$one
-       mov     `40*$i+8-40*4`($inp),$temp      # output pointer
+       # output pointer
+       mov     `$inp_elm_size*$i+$ptr_size-$inp_elm_size*4`($inp),$temp_reg
        cmovg   $one,$num                       # find maximum
        test    $one,$one
-       vmovdqu `40*$i+24-40*4`($inp),@out[$i]  # load IV
+       # load IV
+       vmovdqu `$inp_elm_size*$i+2*$ptr_size+8-$inp_elm_size*4`($inp),@out[$i]
        mov     $one,`32+4*$i`(%rsp)            # initialize counters
        cmovle  %rsp,@ptr[$i]                   # cancel input
        sub     @ptr[$i],$temp                  # distance between input and output
@@ -1232,7 +1262,7 @@ $code.=<<___;
        mov     16(%rsp),%rax                   # original %rsp
 .cfi_def_cfa   %rax,8
        #mov    24(%rsp),$num
-       #lea    `40*8`($inp),$inp
+       #lea    `$inp_elm_size*8`($inp),$inp
        #dec    $num
        #jnz    .Ldec8x_loop_grande
 
@@ -1325,10 +1355,10 @@ se_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
@@ -1471,4 +1501,4 @@ $code =~ s/\`([^\`]*)\`/eval($1)/gem;
 $code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem;
 
 print $code;
-close STDOUT;
+close STDOUT or die "error closing STDOUT: $!";