2 # Copyright 2007-2020 The OpenSSL Project Authors. All Rights Reserved.
4 # Licensed under the Apache License 2.0 (the "License"). You may not use
5 # this file except in compliance with the License. You can obtain a copy
6 # in the file LICENSE in the source distribution or at
7 # https://www.openssl.org/source/license.html
10 # ====================================================================
11 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
12 # project. The module is, however, dual licensed under OpenSSL and
13 # CRYPTOGAMS licenses depending on where you obtain it. For further
14 # details see http://www.openssl.org/~appro/cryptogams/.
15 # ====================================================================
17 # SHA1 block procedure for s390x.
21 # Performance is >30% better than gcc 3.3 generated code. But the real
22 # twist is that SHA1 hardware support is detected and utilized. In
23 # which case performance can reach further >4.5x for larger chunks.
27 # Optimize Xupdate for amount of memory references and reschedule
28 # instructions to favour dual-issue z10 pipeline. On z10 hardware is
29 # "only" ~2.3x faster than software.
33 # Adapt for -m31 build. If kernel supports what's called "highgprs"
34 # feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
35 # instructions and achieve "64-bit" performance even in 31-bit legacy
36 # application context. The feature is not specific to any particular
37 # processor, as long as it's "z-CPU". Latter implies that the code
38 # remains z/Architecture specific. On z990 it was measured to perform
39 # 23% better than code generated by gcc 4.3.
41 $kimdfunc=1; # magic function code for kimd instruction
43 # $output is the last argument if it looks like a file (it has an extension)
44 # $flavour is the first argument if it doesn't look like a file
45 $output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m
|\
.\w
+$| ?
pop : undef;
46 $flavour = $#ARGV >= 0 && $ARGV[0] !~ m
|\
.| ?
shift : undef;
48 if ($flavour =~ /3[12]/) {
56 $output and open STDOUT
,">$output";
58 $K_00_39="%r0"; $K=$K_00_39;
60 $ctx="%r2"; $prefetch="%r2";
68 $E="%r9"; @V=($A,$B,$C,$D,$E);
71 @X=("%r12","%r13","%r14");
74 $stdframe=16*$SIZE_T+4*8;
75 $frame=$stdframe+16*4;
80 $code.=<<___
if ($i==15);
81 lg
$prefetch,$stdframe($sp) ### Xupdate(16) warm-up
84 return if ($i&1); # Xupdate is vectorized and executed every 2nd cycle
85 $code.=<<___
if ($i<16);
86 lg
$X[0],`$i*4`($inp) ### Xload($i)
89 $code.=<<___
if ($i>=16);
90 xgr
$X[0],$prefetch ### Xupdate($i)
91 lg
$prefetch,`$stdframe+4*(($i+2)%16)`($sp)
92 xg
$X[0],`$stdframe+4*(($i+8)%16)`($sp)
98 lr
$X[2],$X[1] # feedback
100 $code.=<<___
if ($i<=70);
101 stg
$X[0],`$stdframe+4*($i%16)`($sp)
107 my ($i,$a,$b,$c,$d,$e)=@_;
126 my ($i,$a,$b,$c,$d,$e)=@_;
144 my ($i,$a,$b,$c,$d,$e)=@_;
165 #include "s390x_arch.h"
169 .type Ktable
,\
@object
170 Ktable
: .long
0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6
171 .skip
48 #.long 0,0,0,0,0,0,0,0,0,0,0,0
172 .size Ktable
,.-Ktable
173 .globl sha1_block_data_order
174 .type sha1_block_data_order
,\
@function
175 sha1_block_data_order
:
177 $code.=<<___
if ($kimdfunc);
178 larl
%r1,OPENSSL_s390xcap_P
179 lg
%r0,S390X_KIMD
(%r1) # check kimd capabilities
180 tmhh
%r0,`0x8000>>$kimdfunc`
186 .long
0xb93e0002 # kimd %r0,%r2
187 brc
1,.-4 # pay attention to "partial completion"
194 st
${g
} $ctx,`2*$SIZE_T`($sp)
195 stm
${g
} %r6,%r15,`6*$SIZE_T`($sp)
211 rllg
$K_00_39,$K_00_39,32
213 for ($i=0;$i<20;$i++) { &BODY_00_19
($i,@V); unshift(@V,pop(@V)); }
215 rllg
$K_00_39,$K_00_39,32
217 for (;$i<40;$i++) { &BODY_20_39
($i,@V); unshift(@V,pop(@V)); }
218 $code.=<<___
; $K=$K_40_79;
219 rllg
$K_40_79,$K_40_79,32
221 for (;$i<60;$i++) { &BODY_40_59
($i,@V); unshift(@V,pop(@V)); }
223 rllg
$K_40_79,$K_40_79,32
225 for (;$i<80;$i++) { &BODY_20_39
($i,@V); unshift(@V,pop(@V)); }
228 l
${g
} $ctx,`$frame+2*$SIZE_T`($sp)
242 lm
${g
} %r6,%r15,`$frame+6*$SIZE_T`($sp)
244 .size sha1_block_data_order
,.-sha1_block_data_order
245 .string
"SHA1 block transform for s390x, CRYPTOGAMS by <appro\@openssl.org>"
248 $code =~ s/\`([^\`]*)\`/eval $1/gem;
251 close STDOUT
or die "error closing STDOUT: $!";