]> WPIA git - cassiopeia.git/blobdiff - lib/openssl/crypto/sha/asm/sha512-armv4.pl
upd: openssl to 1.1.0
[cassiopeia.git] / lib / openssl / crypto / sha / asm / sha512-armv4.pl
index 7faf37b1479029e152ec99200b4c55b551850131..22b5a9d0b1328ded0db569ea8dfa91883ed3ed03 100644 (file)
@@ -1,10 +1,19 @@
-#!/usr/bin/env perl
+#! /usr/bin/env perl
+# Copyright 2007-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@fy.chalmers.se> for the OpenSSL
+# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
 # project. The module is, however, dual licensed under OpenSSL and
 # CRYPTOGAMS licenses depending on where you obtain it. For further
 # details see http://www.openssl.org/~appro/cryptogams/.
+#
+# Permission to use under GPL terms is granted.
 # ====================================================================
 
 # SHA512 block procedure for ARMv4. September 2007.
 # March 2011.
 #
 # Add NEON implementation. On Cortex A8 it was measured to process
-# one byte in 25.5 cycles or 47% faster than integer-only code.
+# one byte in 23.3 cycles or ~60% faster than integer-only code.
+
+# August 2012.
+#
+# Improve NEON performance by 12% on Snapdragon S4. In absolute
+# terms it's 22.6 cycles per byte, which is disappointing result.
+# Technical writers asserted that 3-way S4 pipeline can sustain
+# multiple NEON instructions per cycle, but dual NEON issue could
+# not be observed, see http://www.openssl.org/~appro/Snapdragon-S4.html
+# for further details. On side note Cortex-A15 processes one byte in
+# 16 cycles.
 
 # Byte order [in]dependence. =========================================
 #
@@ -38,8 +57,20 @@ $hi="HI";
 $lo="LO";
 # ====================================================================
 
-while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
-open STDOUT,">$output";
+$flavour = shift;
+if ($flavour=~/\w[\w\-]*\.\w+$/) { $output=$flavour; undef $flavour; }
+else { while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {} }
+
+if ($flavour && $flavour ne "void") {
+    $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+    ( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+    ( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
+    die "can't locate arm-xlate.pl";
+
+    open STDOUT,"| \"$^X\" $xlate $flavour $output";
+} else {
+    open STDOUT,">$output";
+}
 
 $ctx="r0";     # parameter block
 $inp="r1";
@@ -126,6 +157,9 @@ $code.=<<___;
        teq     $t0,#$magic
 
        ldr     $t3,[sp,#$Coff+0]       @ c.lo
+#if __ARM_ARCH__>=7
+       it      eq                      @ Thumb2 thing, sanity check in ARM
+#endif
        orreq   $Ktbl,$Ktbl,#1
        @ Sigma0(x)     (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39))
        @ LO            lo>>28^hi<<4  ^ hi>>2^lo<<30 ^ hi>>7^lo<<25
@@ -163,7 +197,17 @@ $code.=<<___;
 ___
 }
 $code=<<___;
-#include "arm_arch.h"
+#ifndef __KERNEL__
+# include "arm_arch.h"
+# define VFP_ABI_PUSH  vstmdb  sp!,{d8-d15}
+# define VFP_ABI_POP   vldmia  sp!,{d8-d15}
+#else
+# define __ARM_ARCH__ __LINUX_ARM_ARCH__
+# define __ARM_MAX_ARCH__ 7
+# define VFP_ABI_PUSH
+# define VFP_ABI_POP
+#endif
+
 #ifdef __ARMEL__
 # define LO 0
 # define HI 4
@@ -175,7 +219,14 @@ $code=<<___;
 #endif
 
 .text
+#if defined(__thumb2__)
+.syntax unified
+.thumb
+# define adrl adr
+#else
 .code  32
+#endif
+
 .type  K512,%object
 .align 5
 K512:
@@ -220,21 +271,33 @@ WORD64(0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c)
 WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a)
 WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817)
 .size  K512,.-K512
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
 .LOPENSSL_armcap:
-.word  OPENSSL_armcap_P-sha512_block_data_order
+.word  OPENSSL_armcap_P-.Lsha512_block_data_order
 .skip  32-4
+#else
+.skip  32
+#endif
 
 .global        sha512_block_data_order
 .type  sha512_block_data_order,%function
 sha512_block_data_order:
+.Lsha512_block_data_order:
+#if __ARM_ARCH__<7 && !defined(__thumb2__)
        sub     r3,pc,#8                @ sha512_block_data_order
-       add     $len,$inp,$len,lsl#7    @ len to point at the end of inp
-#if __ARM_ARCH__>=7
+#else
+       adr     r3,.Lsha512_block_data_order
+#endif
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
        ldr     r12,.LOPENSSL_armcap
        ldr     r12,[r3,r12]            @ OPENSSL_armcap_P
-       tst     r12,#1
+#ifdef __APPLE__
+       ldr     r12,[r12]
+#endif
+       tst     r12,#ARMV7_NEON
        bne     .LNEON
 #endif
+       add     $len,$inp,$len,lsl#7    @ len to point at the end of inp
        stmdb   sp!,{r4-r12,lr}
        sub     $Ktbl,r3,#672           @ K512
        sub     sp,sp,#9*8
@@ -348,6 +411,9 @@ $code.=<<___;
 ___
        &BODY_00_15(0x17);
 $code.=<<___;
+#if __ARM_ARCH__>=7
+       ittt    eq                      @ Thumb2 thing, sanity check in ARM
+#endif
        ldreq   $t0,[sp,#`$Xoff+8*(16-1)`+0]
        ldreq   $t1,[sp,#`$Xoff+8*(16-1)`+4]
        beq     .L16_79
@@ -432,6 +498,7 @@ $code.=<<___;
        moveq   pc,lr                   @ be binary compatible with V4, yet
        bx      lr                      @ interoperable with Thumb ISA:-)
 #endif
+.size  sha512_block_data_order,.-sha512_block_data_order
 ___
 
 {
@@ -457,40 +524,40 @@ $code.=<<___ if ($i<16 || $i&1);
        vld1.64         {@X[$i%16]},[$inp]!     @ handles unaligned
 #endif
        vshr.u64        $t1,$e,#@Sigma1[1]
+#if $i>0
+        vadd.i64       $a,$Maj                 @ h+=Maj from the past
+#endif
        vshr.u64        $t2,$e,#@Sigma1[2]
 ___
 $code.=<<___;
        vld1.64         {$K},[$Ktbl,:64]!       @ K[i++]
        vsli.64         $t0,$e,#`64-@Sigma1[0]`
        vsli.64         $t1,$e,#`64-@Sigma1[1]`
+       vmov            $Ch,$e
        vsli.64         $t2,$e,#`64-@Sigma1[2]`
 #if $i<16 && defined(__ARMEL__)
        vrev64.8        @X[$i],@X[$i]
 #endif
-       vadd.i64        $T1,$K,$h
-       veor            $Ch,$f,$g
-       veor            $t0,$t1
-       vand            $Ch,$e
-       veor            $t0,$t2                 @ Sigma1(e)
-       veor            $Ch,$g                  @ Ch(e,f,g)
-       vadd.i64        $T1,$t0
+       veor            $t1,$t0
+       vbsl            $Ch,$f,$g               @ Ch(e,f,g)
        vshr.u64        $t0,$a,#@Sigma0[0]
-       vadd.i64        $T1,$Ch
+       veor            $t2,$t1                 @ Sigma1(e)
+       vadd.i64        $T1,$Ch,$h
        vshr.u64        $t1,$a,#@Sigma0[1]
-       vshr.u64        $t2,$a,#@Sigma0[2]
        vsli.64         $t0,$a,#`64-@Sigma0[0]`
+       vadd.i64        $T1,$t2
+       vshr.u64        $t2,$a,#@Sigma0[2]
+       vadd.i64        $K,@X[$i%16]
        vsli.64         $t1,$a,#`64-@Sigma0[1]`
+       veor            $Maj,$a,$b
        vsli.64         $t2,$a,#`64-@Sigma0[2]`
-       vadd.i64        $T1,@X[$i%16]
-       vorr            $Maj,$a,$c
-       vand            $Ch,$a,$c
        veor            $h,$t0,$t1
-       vand            $Maj,$b
+       vadd.i64        $T1,$K
+       vbsl            $Maj,$c,$b              @ Maj(a,b,c)
        veor            $h,$t2                  @ Sigma0(a)
-       vorr            $Maj,$Ch                @ Maj(a,b,c)
-       vadd.i64        $h,$T1
        vadd.i64        $d,$T1
-       vadd.i64        $h,$Maj
+       vadd.i64        $Maj,$T1
+       @ vadd.i64      $h,$Maj
 ___
 }
 
@@ -508,6 +575,7 @@ $i /= 2;
 $code.=<<___;
        vshr.u64        $t0,@X[($i+7)%8],#@sigma1[0]
        vshr.u64        $t1,@X[($i+7)%8],#@sigma1[1]
+        vadd.i64       @_[0],d30                       @ h+=Maj from the past
        vshr.u64        $s1,@X[($i+7)%8],#@sigma1[2]
        vsli.64         $t0,@X[($i+7)%8],#`64-@sigma1[0]`
        vext.8          $s0,@X[$i%8],@X[($i+1)%8],#8    @ X[i+1]
@@ -533,14 +601,19 @@ ___
 }
 
 $code.=<<___;
-#if __ARM_ARCH__>=7
+#if __ARM_MAX_ARCH__>=7
+.arch  armv7-a
 .fpu   neon
 
+.global        sha512_block_data_order_neon
+.type  sha512_block_data_order_neon,%function
 .align 4
+sha512_block_data_order_neon:
 .LNEON:
        dmb                             @ errata #451034 on early Cortex A8
-       vstmdb  sp!,{d8-d15}            @ ABI specification says so
-       sub     $Ktbl,r3,#672           @ K512
+       add     $len,$inp,$len,lsl#7    @ len to point at the end of inp
+       adr     $Ktbl,K512
+       VFP_ABI_PUSH
        vldmia  $ctx,{$A-$H}            @ load context
 .Loop_neon:
 ___
@@ -554,6 +627,7 @@ for(;$i<32;$i++)    { &NEON_16_79($i,@V); unshift(@V,pop(@V)); }
 $code.=<<___;
        bne             .L16_79_neon
 
+        vadd.i64       $A,d30          @ h+=Maj from the past
        vldmia          $ctx,{d24-d31}  @ load context to temp
        vadd.i64        q8,q12          @ vectorized accumulate
        vadd.i64        q9,q13
@@ -564,19 +638,31 @@ $code.=<<___;
        sub             $Ktbl,#640      @ rewind K512
        bne             .Loop_neon
 
-       vldmia  sp!,{d8-d15}            @ epilogue
-       bx      lr
+       VFP_ABI_POP
+       ret                             @ bx lr
+.size  sha512_block_data_order_neon,.-sha512_block_data_order_neon
 #endif
 ___
 }
 $code.=<<___;
-.size  sha512_block_data_order,.-sha512_block_data_order
 .asciz "SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by <appro\@openssl.org>"
 .align 2
+#if __ARM_MAX_ARCH__>=7 && !defined(__KERNEL__)
 .comm  OPENSSL_armcap_P,4,4
+#endif
 ___
 
 $code =~ s/\`([^\`]*)\`/eval $1/gem;
 $code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm;   # make it possible to compile with -march=armv4
+$code =~ s/\bret\b/bx  lr/gm;
+
+open SELF,$0;
+while(<SELF>) {
+       next if (/^#!/);
+       last if (!s/^#/@/ and !/^$/);
+       print;
+}
+close SELF;
+
 print $code;
 close STDOUT; # enforce flush