s390x assembler pack: adapt for -m31 build, see commentary in Configure
[openssl.git] / crypto / modes / asm / ghash-s390x.pl
1 #!/usr/bin/env perl
2
3 # ====================================================================
4 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
5 # project. The module is, however, dual licensed under OpenSSL and
6 # CRYPTOGAMS licenses depending on where you obtain it. For further
7 # details see http://www.openssl.org/~appro/cryptogams/.
8 # ====================================================================
9
10 # September 2010.
11 #
12 # The module implements "4-bit" GCM GHASH function and underlying
13 # single multiplication operation in GF(2^128). "4-bit" means that it
14 # uses 256 bytes per-key table [+128 bytes shared table]. Performance
15 # was measured to be ~18 cycles per processed byte on z10, which is
16 # almost 40% better than gcc-generated code. It should be noted that
17 # 18 cycles is worse result than expected: loop is scheduled for 12
18 # and the result should be close to 12. In the lack of instruction-
19 # level profiling data it's impossible to tell why...
20
21 # November 2010.
22 #
23 # Adapt for -m31 build. If kernel supports what's called "highgprs"
24 # feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit
25 # instructions and achieve "64-bit" performance even in 31-bit legacy
26 # application context. The feature is not specific to any particular
27 # processor, as long as it's "z-CPU". Latter implies that the code
28 # remains z/Architecture specific. On z990 it was measured to perform
29 # 2.8x better than 32-bit code generated by gcc 4.3.
30
31 $flavour = shift;
32
33 if ($flavour =~ /3[12]/) {
34         $SIZE_T=4;
35         $g="";
36 } else {
37         $SIZE_T=8;
38         $g="g";
39 }
40
41 while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
42 open STDOUT,">$output";
43
44 $softonly=1;    # disable hardware support for now
45
46 $Zhi="%r0";
47 $Zlo="%r1";
48
49 $Xi="%r2";      # argument block
50 $Htbl="%r3";
51 $inp="%r4";
52 $len="%r5";
53
54 $rem0="%r6";    # variables
55 $rem1="%r7";
56 $nlo="%r8";
57 $nhi="%r9";
58 $xi="%r10";
59 $cnt="%r11";
60 $tmp="%r12";
61 $x78="%r13";
62 $rem_4bit="%r14";
63
64 $sp="%r15";
65
66 $code.=<<___;
67 .text
68
69 .globl  gcm_gmult_4bit
70 .align  32
71 gcm_gmult_4bit:
72 ___
73 $code.=<<___ if(!$softonly);
74         larl    %r1,OPENSSL_s390xcap_P
75         lg      %r0,0(%r1)
76         tmhl    %r0,0x4000      # check for message-security-assist
77         jz      .Lsoft_gmult
78         lghi    %r0,0
79         la      %r1,16($sp)
80         .long   0xb93e0004      # kimd %r0,%r4
81         lg      %r1,24($sp)
82         tmhh    %r1,0x4000      # check for function 65
83         jz      .Lsoft_gmult
84         stg     %r0,16($sp)     # arrange 16 bytes of zero input
85         stg     %r0,24($sp)
86         lghi    %r0,65          # function 65
87         la      %r1,0($Xi)      # H lies right after Xi in gcm128_context
88         la      $inp,16($sp)
89         lghi    $len,16
90         .long   0xb93e0004      # kimd %r0,$inp
91         brc     1,.-4           # pay attention to "partial completion"
92         br      %r14
93 .align  32
94 .Lsoft_gmult:
95 ___
96 $code.=<<___;
97         stm${g} %r6,%r14,6*$SIZE_T($sp)
98
99         aghi    $Xi,-1
100         lghi    $len,1
101         lghi    $x78,`0xf<<3`
102         larl    $rem_4bit,rem_4bit
103
104         lg      $Zlo,8+1($Xi)           # Xi
105         j       .Lgmult_shortcut
106 .type   gcm_gmult_4bit,\@function
107 .size   gcm_gmult_4bit,(.-gcm_gmult_4bit)
108
109 .globl  gcm_ghash_4bit
110 .align  32
111 gcm_ghash_4bit:
112 ___
113 $code.=<<___ if(!$softonly);
114         larl    %r1,OPENSSL_s390xcap_P
115         lg      %r0,0(%r1)
116         tmhl    %r0,0x4000      # check for message-security-assist
117         jz      .Lsoft_ghash
118         lghi    %r0,0
119         la      %r1,16($sp)
120         .long   0xb93e0004      # kimd %r0,%r4
121         lg      %r1,24($sp)
122         tmhh    %r1,0x4000      # check for function 65
123         jz      .Lsoft_ghash
124         lghi    %r0,65          # function 65
125         la      %r1,0($Xi)      # H lies right after Xi in gcm128_context
126         .long   0xb93e0004      # kimd %r0,$inp
127         brc     1,.-4           # pay attention to "partial completion"
128         br      %r14
129 .align  32
130 .Lsoft_ghash:
131 ___
132 $cdoe.=<<___ if ($flavour =~ /3[12]/);
133         llgfr   $len,$len
134 ___
135 $code.=<<___;
136         stm${g} %r6,%r14,6*$SIZE_T($sp)
137
138         aghi    $Xi,-1
139         srlg    $len,$len,4
140         lghi    $x78,`0xf<<3`
141         larl    $rem_4bit,rem_4bit
142
143         lg      $Zlo,8+1($Xi)           # Xi
144         lg      $Zhi,0+1($Xi)
145         lghi    $tmp,0
146 .Louter:
147         xg      $Zhi,0($inp)            # Xi ^= inp 
148         xg      $Zlo,8($inp)
149         xgr     $Zhi,$tmp
150         stg     $Zlo,8+1($Xi)
151         stg     $Zhi,0+1($Xi)
152
153 .Lgmult_shortcut:
154         lghi    $tmp,0xf0
155         sllg    $nlo,$Zlo,4
156         srlg    $xi,$Zlo,8              # extract second byte
157         ngr     $nlo,$tmp
158         lgr     $nhi,$Zlo
159         lghi    $cnt,14
160         ngr     $nhi,$tmp
161
162         lg      $Zlo,8($nlo,$Htbl)
163         lg      $Zhi,0($nlo,$Htbl)
164
165         sllg    $nlo,$xi,4
166         sllg    $rem0,$Zlo,3
167         ngr     $nlo,$tmp
168         ngr     $rem0,$x78
169         ngr     $xi,$tmp
170
171         sllg    $tmp,$Zhi,60
172         srlg    $Zlo,$Zlo,4
173         srlg    $Zhi,$Zhi,4
174         xg      $Zlo,8($nhi,$Htbl)
175         xg      $Zhi,0($nhi,$Htbl)
176         lgr     $nhi,$xi
177         sllg    $rem1,$Zlo,3
178         xgr     $Zlo,$tmp
179         ngr     $rem1,$x78
180         j       .Lghash_inner
181 .align  16
182 .Lghash_inner:
183         srlg    $Zlo,$Zlo,4
184         sllg    $tmp,$Zhi,60
185         xg      $Zlo,8($nlo,$Htbl)
186         srlg    $Zhi,$Zhi,4
187         llgc    $xi,0($cnt,$Xi)
188         xg      $Zhi,0($nlo,$Htbl)
189         sllg    $nlo,$xi,4
190         xg      $Zhi,0($rem0,$rem_4bit)
191         nill    $nlo,0xf0
192         sllg    $rem0,$Zlo,3
193         xgr     $Zlo,$tmp
194         ngr     $rem0,$x78
195         nill    $xi,0xf0
196
197         sllg    $tmp,$Zhi,60
198         srlg    $Zlo,$Zlo,4
199         srlg    $Zhi,$Zhi,4
200         xg      $Zlo,8($nhi,$Htbl)
201         xg      $Zhi,0($nhi,$Htbl)
202         lgr     $nhi,$xi
203         xg      $Zhi,0($rem1,$rem_4bit)
204         sllg    $rem1,$Zlo,3
205         xgr     $Zlo,$tmp
206         ngr     $rem1,$x78
207         brct    $cnt,.Lghash_inner
208
209         sllg    $tmp,$Zhi,60
210         srlg    $Zlo,$Zlo,4
211         srlg    $Zhi,$Zhi,4
212         xg      $Zlo,8($nlo,$Htbl)
213         xg      $Zhi,0($nlo,$Htbl)
214         sllg    $xi,$Zlo,3
215         xg      $Zhi,0($rem0,$rem_4bit)
216         xgr     $Zlo,$tmp
217         ngr     $xi,$x78
218
219         sllg    $tmp,$Zhi,60
220         srlg    $Zlo,$Zlo,4
221         srlg    $Zhi,$Zhi,4
222         xg      $Zlo,8($nhi,$Htbl)
223         xg      $Zhi,0($nhi,$Htbl)
224         xgr     $Zlo,$tmp
225         xg      $Zhi,0($rem1,$rem_4bit)
226
227         lg      $tmp,0($xi,$rem_4bit)
228         la      $inp,16($inp)
229         sllg    $tmp,$tmp,4             # correct last rem_4bit[rem]
230         brctg   $len,.Louter
231
232         xgr     $Zhi,$tmp
233         stg     $Zlo,8+1($Xi)
234         stg     $Zhi,0+1($Xi)
235         lm${g}  %r6,%r14,6*$SIZE_T($sp)
236         br      %r14
237 .type   gcm_ghash_4bit,\@function
238 .size   gcm_ghash_4bit,(.-gcm_ghash_4bit)
239
240 .align  64
241 rem_4bit:
242         .long   `0x0000<<12`,0,`0x1C20<<12`,0,`0x3840<<12`,0,`0x2460<<12`,0
243         .long   `0x7080<<12`,0,`0x6CA0<<12`,0,`0x48C0<<12`,0,`0x54E0<<12`,0
244         .long   `0xE100<<12`,0,`0xFD20<<12`,0,`0xD940<<12`,0,`0xC560<<12`,0
245         .long   `0x9180<<12`,0,`0x8DA0<<12`,0,`0xA9C0<<12`,0,`0xB5E0<<12`,0
246 .type   rem_4bit,\@object
247 .size   rem_4bit,(.-rem_4bit)
248 .string "GHASH for s390x, CRYPTOGAMS by <appro\@openssl.org>"
249 ___
250
251 $code =~ s/\`([^\`]*)\`/eval $1/gem;
252 print $code;
253 close STDOUT;