modes/asm/*-x86_64.pl: add CFI annotations.
[openssl.git] / crypto / modes / asm / aesni-gcm-x86_64.pl
index 378c0d1685868d4e0a321aa6de99bb95e399d312..5e69cb86fa3d0a98c63e764a8b46f95bfd1fe156 100644 (file)
@@ -1,4 +1,11 @@
-#!/usr/bin/env perl
+#! /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
+# 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
+
 #
 # ====================================================================
 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
@@ -44,7 +51,7 @@ die "can't locate x86_64-xlate.pl";
 
 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1`
                =~ /GNU assembler version ([2-9]\.[0-9]+)/) {
-       $avx = ($1>=2.19) + ($1>=2.22);
+       $avx = ($1>=2.20) + ($1>=2.22);
 }
 
 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) &&
@@ -57,11 +64,11 @@ 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) ([3-9]\.[0-9]+)/) {
        $avx = ($2>=3.0) + ($2>3.0);
 }
 
-open OUT,"| \"$^X\" $xlate $flavour $output";
+open OUT,"| \"$^X\" \"$xlate\" $flavour \"$output\"";
 *STDOUT=*OUT;
 
 if ($avx>1) {{{
@@ -109,6 +116,23 @@ _aesni_ctr32_ghash_6x:
          vpxor         $rndkey,$inout3,$inout3
          vmovups       0x10-0x80($key),$T2     # borrow $T2 for $rndkey
        vpclmulqdq      \$0x01,$Hkey,$Z3,$Z2
+
+       # At this point, the current block of 96 (0x60) bytes has already been
+       # loaded into registers. Concurrently with processing it, we want to
+       # load the next 96 bytes of input for the next round. Obviously, we can
+       # only do this if there are at least 96 more bytes of input beyond the
+       # input we're currently processing, or else we'd read past the end of
+       # the input buffer. Here, we set |%r12| to 96 if there are at least 96
+       # bytes of input beyond the 96 bytes we're already processing, and we
+       # set |%r12| to 0 otherwise. In the case where we set |%r12| to 96,
+       # we'll read in the next block so that it is in registers for the next
+       # loop iteration. In the case where we set |%r12| to 0, we'll re-read
+       # the current block and then ignore what we re-read.
+       #
+       # At this point, |$in0| points to the current (already read into
+       # registers) block, and |$end0| points to 2*96 bytes before the end of
+       # the input. Thus, |$in0| > |$end0| means that we do not have the next
+       # 96-byte block to read in, and |$in0| <= |$end0| means we do.
        xor             %r12,%r12
        cmp             $in0,$end0
 
@@ -400,17 +424,28 @@ $code.=<<___;
 .type  aesni_gcm_decrypt,\@function,6
 .align 32
 aesni_gcm_decrypt:
+.cfi_startproc
        xor     $ret,$ret
+
+       # We call |_aesni_ctr32_ghash_6x|, which requires at least 96 (0x60)
+       # bytes of input.
        cmp     \$0x60,$len                     # minimal accepted length
        jb      .Lgcm_dec_abort
 
        lea     (%rsp),%rax                     # save stack pointer
+.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
@@ -455,7 +490,15 @@ $code.=<<___;
        vmovdqu         0x50($inp),$Z3          # I[5]
        lea             ($inp),$in0
        vmovdqu         0x40($inp),$Z0
+
+       # |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0)
+       # bytes before the end of the input. Note, in particular, that this is
+       # correct even if |$len| is not an even multiple of 96 or 16. XXX: This
+       # seems to require that |$inp| + |$len| >= 2*96 (0xc0); i.e. |$inp| must
+       # not be near the very beginning of the address space when |$len| < 2*96
+       # (0xc0).
        lea             -0xc0($inp,$len),$end0
+
        vmovdqu         0x30($inp),$Z1
        shr             \$4,$len
        xor             $ret,$ret
@@ -490,7 +533,7 @@ $code.=<<___;
 ___
 $code.=<<___ if ($win64);
        movaps  -0xd8(%rax),%xmm6
-       movaps  -0xd8(%rax),%xmm7
+       movaps  -0xc8(%rax),%xmm7
        movaps  -0xb8(%rax),%xmm8
        movaps  -0xa8(%rax),%xmm9
        movaps  -0x98(%rax),%xmm10
@@ -502,15 +545,23 @@ $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             # restore %rsp
+.cfi_def_cfa_register  %rsp
 .Lgcm_dec_abort:
        mov     $ret,%rax               # return value
        ret
+.cfi_endproc
 .size  aesni_gcm_decrypt,.-aesni_gcm_decrypt
 ___
 
@@ -610,17 +661,29 @@ _aesni_ctr32_6x:
 .type  aesni_gcm_encrypt,\@function,6
 .align 32
 aesni_gcm_encrypt:
+.cfi_startproc
        xor     $ret,$ret
+
+       # We call |_aesni_ctr32_6x| twice, each call consuming 96 bytes of
+       # input. Then we call |_aesni_ctr32_ghash_6x|, which requires at
+       # least 96 more bytes of input.
        cmp     \$0x60*3,$len                   # minimal accepted length
        jb      .Lgcm_enc_abort
 
        lea     (%rsp),%rax                     # save stack pointer
+.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
@@ -660,7 +723,16 @@ $code.=<<___;
 .Lenc_no_key_aliasing:
 
        lea             ($out),$in0
+
+       # |_aesni_ctr32_ghash_6x| requires |$end0| to point to 2*96 (0xc0)
+       # bytes before the end of the input. Note, in particular, that this is
+       # correct even if |$len| is not an even multiple of 96 or 16. Unlike in
+       # the decryption case, there's no caveat that |$out| must not be near
+       # the very beginning of the address space, because we know that
+       # |$len| >= 3*96 from the check above, and so we know
+       # |$out| + |$len| >= 2*96 (0xc0).
        lea             -0xc0($out,$len),$end0
+
        shr             \$4,$len
 
        call            _aesni_ctr32_6x
@@ -883,15 +955,23 @@ $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             # restore %rsp
+.cfi_def_cfa_register  %rsp
 .Lgcm_enc_abort:
        mov     $ret,%rax               # return value
        ret
+.cfi_endproc
 .size  aesni_gcm_encrypt,.-aesni_gcm_encrypt
 ___