Add dummy pipeline support for aes128_cbc_hmac_sha1
[openssl.git] / engines / asm / e_padlock-x86_64.pl
index 13c371be67ed5aa7cac3054efcc51ed4141e31ce..07c0a6d08448017d853a27562f7a099b213215b9 100644 (file)
@@ -23,10 +23,12 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
 ( $xlate="${dir}../../crypto/perlasm/x86_64-xlate.pl" and -f $xlate) or
 die "can't locate x86_64-xlate.pl";
 
-open STDOUT,"| $^X $xlate $flavour $output";
+open OUT,"| \"$^X\" $xlate $flavour $output";
+*STDOUT=*OUT;
 
 $code=".text\n";
 
+%PADLOCK_PREFETCH=(ecb=>128, cbc=>64, ctr32=>32);      # prefetch errata
 $PADLOCK_CHUNK=512;    # Must be a power of 2 between 32 and 2^20
 
 $ctx="%rdx";
@@ -146,9 +148,21 @@ padlock_xstore:
 .type  padlock_sha1_oneshot,\@function,3
 .align 16
 padlock_sha1_oneshot:
-       xor     %rax,%rax
        mov     %rdx,%rcx
+       mov     %rdi,%rdx               # put aside %rdi
+       movups  (%rdi),%xmm0            # copy-in context
+       sub     \$128+8,%rsp
+       mov     16(%rdi),%eax
+       movaps  %xmm0,(%rsp)
+       mov     %rsp,%rdi
+       mov     %eax,16(%rsp)
+       xor     %rax,%rax
        .byte   0xf3,0x0f,0xa6,0xc8     # rep xsha1
+       movaps  (%rsp),%xmm0
+       mov     16(%rsp),%eax
+       add     \$128+8,%rsp
+       movups  %xmm0,(%rdx)            # copy-out context
+       mov     %eax,16(%rdx)
        ret
 .size  padlock_sha1_oneshot,.-padlock_sha1_oneshot
 
@@ -156,9 +170,21 @@ padlock_sha1_oneshot:
 .type  padlock_sha1_blocks,\@function,3
 .align 16
 padlock_sha1_blocks:
-       mov     \$-1,%rax
        mov     %rdx,%rcx
+       mov     %rdi,%rdx               # put aside %rdi
+       movups  (%rdi),%xmm0            # copy-in context
+       sub     \$128+8,%rsp
+       mov     16(%rdi),%eax
+       movaps  %xmm0,(%rsp)
+       mov     %rsp,%rdi
+       mov     %eax,16(%rsp)
+       mov     \$-1,%rax
        .byte   0xf3,0x0f,0xa6,0xc8     # rep xsha1
+       movaps  (%rsp),%xmm0
+       mov     16(%rsp),%eax
+       add     \$128+8,%rsp
+       movups  %xmm0,(%rdx)            # copy-out context
+       mov     %eax,16(%rdx)
        ret
 .size  padlock_sha1_blocks,.-padlock_sha1_blocks
 
@@ -166,9 +192,21 @@ padlock_sha1_blocks:
 .type  padlock_sha256_oneshot,\@function,3
 .align 16
 padlock_sha256_oneshot:
-       xor     %rax,%rax
        mov     %rdx,%rcx
+       mov     %rdi,%rdx               # put aside %rdi
+       movups  (%rdi),%xmm0            # copy-in context
+       sub     \$128+8,%rsp
+       movups  16(%rdi),%xmm1
+       movaps  %xmm0,(%rsp)
+       mov     %rsp,%rdi
+       movaps  %xmm1,16(%rsp)
+       xor     %rax,%rax
        .byte   0xf3,0x0f,0xa6,0xd0     # rep xsha256
+       movaps  (%rsp),%xmm0
+       movaps  16(%rsp),%xmm1
+       add     \$128+8,%rsp
+       movups  %xmm0,(%rdx)            # copy-out context
+       movups  %xmm1,16(%rdx)
        ret
 .size  padlock_sha256_oneshot,.-padlock_sha256_oneshot
 
@@ -176,9 +214,21 @@ padlock_sha256_oneshot:
 .type  padlock_sha256_blocks,\@function,3
 .align 16
 padlock_sha256_blocks:
-       mov     \$-1,%rax
        mov     %rdx,%rcx
+       mov     %rdi,%rdx               # put aside %rdi
+       movups  (%rdi),%xmm0            # copy-in context
+       sub     \$128+8,%rsp
+       movups  16(%rdi),%xmm1
+       movaps  %xmm0,(%rsp)
+       mov     %rsp,%rdi
+       movaps  %xmm1,16(%rsp)
+       mov     \$-1,%rax
        .byte   0xf3,0x0f,0xa6,0xd0     # rep xsha256
+       movaps  (%rsp),%xmm0
+       movaps  16(%rsp),%xmm1
+       add     \$128+8,%rsp
+       movups  %xmm0,(%rdx)            # copy-out context
+       movups  %xmm1,16(%rdx)
        ret
 .size  padlock_sha256_blocks,.-padlock_sha256_blocks
 
@@ -187,7 +237,27 @@ padlock_sha256_blocks:
 .align 16
 padlock_sha512_blocks:
        mov     %rdx,%rcx
+       mov     %rdi,%rdx               # put aside %rdi
+       movups  (%rdi),%xmm0            # copy-in context
+       sub     \$128+8,%rsp
+       movups  16(%rdi),%xmm1
+       movups  32(%rdi),%xmm2
+       movups  48(%rdi),%xmm3
+       movaps  %xmm0,(%rsp)
+       mov     %rsp,%rdi
+       movaps  %xmm1,16(%rsp)
+       movaps  %xmm2,32(%rsp)
+       movaps  %xmm3,48(%rsp)
        .byte   0xf3,0x0f,0xa6,0xe0     # rep xha512
+       movaps  (%rsp),%xmm0
+       movaps  16(%rsp),%xmm1
+       movaps  32(%rsp),%xmm2
+       movaps  48(%rsp),%xmm3
+       add     \$128+8,%rsp
+       movups  %xmm0,(%rdx)            # copy-out context
+       movups  %xmm1,16(%rdx)
+       movups  %xmm2,32(%rdx)
+       movups  %xmm3,48(%rdx)
        ret
 .size  padlock_sha512_blocks,.-padlock_sha512_blocks
 ___
@@ -235,16 +305,36 @@ padlock_${mode}_encrypt:
        neg     %rax
        and     \$$PADLOCK_CHUNK-1,$chunk       # chunk%=PADLOCK_CHUNK
        lea     (%rax,%rbp),%rsp
+       mov     \$$PADLOCK_CHUNK,%rax
+       cmovz   %rax,$chunk                     # chunk=chunk?:PADLOCK_CHUNK
 ___
 $code.=<<___                           if ($mode eq "ctr32");
+.L${mode}_reenter:
        mov     -4($ctx),%eax           # pull 32-bit counter
        bswap   %eax
        neg     %eax
        and     \$`$PADLOCK_CHUNK/16-1`,%eax
-       jz      .L${mode}_loop
+       mov     \$$PADLOCK_CHUNK,$chunk
        shl     \$4,%eax
+       cmovz   $chunk,%rax
        cmp     %rax,$len
        cmova   %rax,$chunk             # don't let counter cross PADLOCK_CHUNK
+       cmovbe  $len,$chunk
+___
+$code.=<<___                           if ($PADLOCK_PREFETCH{$mode});
+       cmp     $chunk,$len
+       ja      .L${mode}_loop
+       mov     $inp,%rax               # check if prefetch crosses page
+       cmp     %rsp,%rbp
+       cmove   $out,%rax
+       add     $len,%rax
+       neg     %rax
+       and     \$0xfff,%rax            # distance to page boundary
+       cmp     \$$PADLOCK_PREFETCH{$mode},%rax
+       mov     \$-$PADLOCK_PREFETCH{$mode},%rax
+       cmovae  $chunk,%rax             # mask=distance<prefetch?-prefetch:-1
+       and     %rax,$chunk
+       jz      .L${mode}_unaligned_tail
 ___
 $code.=<<___;
        jmp     .L${mode}_loop
@@ -279,21 +369,21 @@ ___
 $code.=<<___                           if ($mode eq "ctr32");
        mov     -4($ctx),%eax           # pull 32-bit counter
        test    \$0xffff0000,%eax
-       jnz     .L${mode}_no_corr
+       jnz     .L${mode}_no_carry
        bswap   %eax
        add     \$0x10000,%eax
        bswap   %eax
        mov     %eax,-4($ctx)
-.L${mode}_no_corr:
+.L${mode}_no_carry:
 ___
 $code.=<<___;
-       mov     %r8,$out                # restore paramters
+       mov     %r8,$out                # restore parameters
        mov     %r11,$chunk
        test    \$0x0f,$out
        jz      .L${mode}_out_aligned
        mov     $chunk,$len
-       shr     \$3,$len
        lea     (%rsp),$inp
+       shr     \$3,$len
        .byte   0xf3,0x48,0xa5          # rep movsq
        sub     $chunk,$out
 .L${mode}_out_aligned:
@@ -303,17 +393,62 @@ $code.=<<___;
        add     $chunk,$inp
        sub     $chunk,$len
        mov     \$$PADLOCK_CHUNK,$chunk
+___
+                                       if (!$PADLOCK_PREFETCH{$mode}) {
+$code.=<<___;
+       jnz     .L${mode}_loop
+___
+                                       } else {
+$code.=<<___;
+       jz      .L${mode}_break
+       cmp     $chunk,$len
+       jae     .L${mode}_loop
+___
+$code.=<<___                           if ($mode eq "ctr32");
+       mov     $len,$chunk
+       mov     $inp,%rax               # check if prefetch crosses page
+       cmp     %rsp,%rbp
+       cmove   $out,%rax
+       add     $len,%rax
+       neg     %rax
+       and     \$0xfff,%rax            # distance to page boundary
+       cmp     \$$PADLOCK_PREFETCH{$mode},%rax
+       mov     \$-$PADLOCK_PREFETCH{$mode},%rax
+       cmovae  $chunk,%rax
+       and     %rax,$chunk
        jnz     .L${mode}_loop
+___
+$code.=<<___;
+.L${mode}_unaligned_tail:
+       xor     %eax,%eax
+       cmp     %rsp,%rbp
+       cmove   $len,%rax
+       mov     $out,%r8                # save parameters
+       mov     $len,$chunk
+       sub     %rax,%rsp               # alloca
+       shr     \$3,$len
+       lea     (%rsp),$out
+       .byte   0xf3,0x48,0xa5          # rep movsq
+       mov     %rsp,$inp
+       mov     %r8, $out               # restore parameters
+       mov     $chunk,$len
+       jmp     .L${mode}_loop
+.align 16
+.L${mode}_break:
+___
+                                       }
+$code.=<<___;
+       cmp     %rbp,%rsp
+       je      .L${mode}_done
 
-       test    \$0x0f,$out
-       jz      .L${mode}_done
+       pxor    %xmm0,%xmm0
+       lea     (%rsp),%rax
+.L${mode}_bzero:
+       movaps  %xmm0,(%rax)
+       lea     16(%rax),%rax
+       cmp     %rax,%rbp
+       ja      .L${mode}_bzero
 
-       mov     %rbp,$len
-       mov     %rsp,$out
-       sub     %rsp,$len
-       xor     %rax,%rax
-       shr     \$3,$len
-       .byte   0xf3,0x48,0xab          # rep stosq
 .L${mode}_done:
        lea     (%rbp),%rsp
        jmp     .L${mode}_exit
@@ -323,24 +458,53 @@ $code.=<<___;
 ___
 $code.=<<___                           if ($mode eq "ctr32");
        mov     -4($ctx),%eax           # pull 32-bit counter
-       mov     \$`16*0x10000`,$chunk
        bswap   %eax
-       cmp     $len,$chunk
-       cmova   $len,$chunk
        neg     %eax
        and     \$0xffff,%eax
-       jz      .L${mode}_aligned_loop
+       mov     \$`16*0x10000`,$chunk
        shl     \$4,%eax
+       cmovz   $chunk,%rax
        cmp     %rax,$len
        cmova   %rax,$chunk             # don't let counter cross 2^16
-       jmp     .L${mode}_aligned_loop
-.align 16
+       cmovbe  $len,$chunk
+       jbe     .L${mode}_aligned_skip
+
 .L${mode}_aligned_loop:
-       cmp     $len,$chunk
-       cmova   $len,$chunk
        mov     $len,%r10               # save parameters
        mov     $chunk,$len
        mov     $chunk,%r11
+
+       lea     -16($ctx),%rax          # ivp
+       lea     16($ctx),%rbx           # key
+       shr     \$4,$len                # len/=AES_BLOCK_SIZE
+       .byte   0xf3,0x0f,0xa7,$opcode  # rep xcrypt*
+
+       mov     -4($ctx),%eax           # pull 32-bit counter
+       bswap   %eax
+       add     \$0x10000,%eax
+       bswap   %eax
+       mov     %eax,-4($ctx)
+
+       mov     %r10,$len               # restore parameters
+       sub     %r11,$len
+       mov     \$`16*0x10000`,$chunk
+       jz      .L${mode}_exit
+       cmp     $chunk,$len
+       jae     .L${mode}_aligned_loop
+
+.L${mode}_aligned_skip:
+___
+$code.=<<___                           if ($PADLOCK_PREFETCH{$mode});
+       lea     ($inp,$len),%rbp
+       neg     %rbp
+       and     \$0xfff,%rbp            # distance to page boundary
+       xor     %eax,%eax
+       cmp     \$$PADLOCK_PREFETCH{$mode},%rbp
+       mov     \$$PADLOCK_PREFETCH{$mode}-1,%rbp
+       cmovae  %rax,%rbp
+       and     $len,%rbp               # remainder
+       sub     %rbp,$len
+       jz      .L${mode}_aligned_tail
 ___
 $code.=<<___;
        lea     -16($ctx),%rax          # ivp
@@ -352,18 +516,23 @@ $code.=<<___                              if ($mode !~ /ecb|ctr/);
        movdqa  (%rax),%xmm0
        movdqa  %xmm0,-16($ctx)         # copy [or refresh] iv
 ___
-$code.=<<___                           if ($mode eq "ctr32");
-       mov     -4($ctx),%eax           # pull 32-bit counter
-       bswap   %eax
-       add     \$0x10000,%eax
-       bswap   %eax
-       mov     %eax,-4($ctx)
+$code.=<<___                           if ($PADLOCK_PREFETCH{$mode});
+       test    %rbp,%rbp               # check remainder
+       jz      .L${mode}_exit
 
-       mov     %r11,$chunk             # restore paramters
-       mov     %r10,$len
-       sub     $chunk,$len
-       mov     \$`16*0x10000`,$chunk
-       jnz     .L${mode}_aligned_loop
+.L${mode}_aligned_tail:
+       mov     $out,%r8
+       mov     %rbp,$chunk
+       mov     %rbp,$len
+       lea     (%rsp),%rbp
+       sub     $len,%rsp
+       shr     \$3,$len
+       lea     (%rsp),$out
+       .byte   0xf3,0x48,0xa5          # rep movsq     
+       lea     (%r8),$out
+       lea     (%rsp),$inp
+       mov     $chunk,$len
+       jmp     .L${mode}_loop
 ___
 $code.=<<___;
 .L${mode}_exit: