d7689de541fefda513f9d359ddfbada7ad5b8a35
[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 while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {}
22 open STDOUT,">$output";
23
24 $softonly=1;    # disable hardware support for now
25
26 $Zhi="%r0";
27 $Zlo="%r1";
28
29 $Xi="%r2";      # argument block
30 $Htbl="%r3";
31 $inp="%r4";
32 $len="%r5";
33
34 $rem0="%r6";    # variables
35 $rem1="%r7";
36 $nlo="%r8";
37 $nhi="%r9";
38 $xi="%r10";
39 $cnt="%r11";
40 $tmp="%r12";
41 $x78="%r13";
42 $rem_4bit="%r14";
43
44 $sp="%r15";
45
46 $code.=<<___;
47 .text
48
49 .globl  gcm_gmult_4bit
50 .align  32
51 gcm_gmult_4bit:
52 ___
53 $code.=<<___ if(!$softonly);
54         larl    %r1,OPENSSL_s390xcap_P
55         lg      %r0,0(%r1)
56         tmhl    %r0,0x4000      # check for message-security-assist
57         jz      .Lsoft_gmult
58         lghi    %r0,0
59         la      %r1,16($sp)
60         .long   0xb93e0004      # kimd %r0,%r4
61         lg      %r1,24($sp)
62         tmhh    %r1,0x4000      # check for function 65
63         jz      .Lsoft_gmult
64         stg     %r0,16($sp)     # arrange 16 bytes of zero input
65         stg     %r0,24($sp)
66         lghi    %r0,65          # function 65
67         la      %r1,0($Xi)      # H lies right after Xi in gcm128_context
68         la      $inp,16($sp)
69         lghi    $len,16
70         .long   0xb93e0004      # kimd %r0,$inp
71         brc     1,.-4           # pay attention to "partial completion"
72         br      %r14
73 .align  32
74 .Lsoft_gmult:
75 ___
76 $code.=<<___;
77         stmg    %r6,%r14,48($sp)
78
79         aghi    $Xi,-1
80         lghi    $len,1
81         lghi    $x78,`0xf<<3`
82         larl    $rem_4bit,rem_4bit
83
84         lg      $Zlo,8+1($Xi)           # Xi
85         j       .Lgmult_shortcut
86 .type   gcm_gmult_4bit,\@function
87 .size   gcm_gmult_4bit,(.-gcm_gmult_4bit)
88
89 .globl  gcm_ghash_4bit
90 .align  32
91 gcm_ghash_4bit:
92 ___
93 $code.=<<___ if(!$softonly);
94         larl    %r1,OPENSSL_s390xcap_P
95         lg      %r0,0(%r1)
96         tmhl    %r0,0x4000      # check for message-security-assist
97         jz      .Lsoft_ghash
98         lghi    %r0,0
99         la      %r1,16($sp)
100         .long   0xb93e0004      # kimd %r0,%r4
101         lg      %r1,24($sp)
102         tmhh    %r1,0x4000      # check for function 65
103         jz      .Lsoft_ghash
104         lghi    %r0,65          # function 65
105         la      %r1,0($Xi)      # H lies right after Xi in gcm128_context
106         .long   0xb93e0004      # kimd %r0,$inp
107         brc     1,.-4           # pay attention to "partial completion"
108         br      %r14
109 .align  32
110 .Lsoft_ghash:
111 ___
112 $code.=<<___;
113         stmg    %r6,%r14,48($sp)
114
115         aghi    $Xi,-1
116         srlg    $len,$len,4
117         lghi    $x78,`0xf<<3`
118         larl    $rem_4bit,rem_4bit
119
120         lg      $Zlo,8+1($Xi)           # Xi
121         lg      $Zhi,0+1($Xi)
122         lghi    $tmp,0
123 .Louter:
124         xg      $Zhi,0($inp)            # Xi ^= inp 
125         xg      $Zlo,8($inp)
126         xgr     $Zhi,$tmp
127         stg     $Zlo,8+1($Xi)
128         stg     $Zhi,0+1($Xi)
129
130 .Lgmult_shortcut:
131         lghi    $tmp,0xf0
132         sllg    $nlo,$Zlo,4
133         srlg    $xi,$Zlo,8              # extract second byte
134         ngr     $nlo,$tmp
135         lgr     $nhi,$Zlo
136         lghi    $cnt,14
137         ngr     $nhi,$tmp
138
139         lg      $Zlo,8($nlo,$Htbl)
140         lg      $Zhi,0($nlo,$Htbl)
141
142         sllg    $nlo,$xi,4
143         sllg    $rem0,$Zlo,3
144         ngr     $nlo,$tmp
145         ngr     $rem0,$x78
146         ngr     $xi,$tmp
147
148         sllg    $tmp,$Zhi,60
149         srlg    $Zlo,$Zlo,4
150         srlg    $Zhi,$Zhi,4
151         xg      $Zlo,8($nhi,$Htbl)
152         xg      $Zhi,0($nhi,$Htbl)
153         lgr     $nhi,$xi
154         sllg    $rem1,$Zlo,3
155         xgr     $Zlo,$tmp
156         ngr     $rem1,$x78
157         j       .Lghash_inner
158 .align  16
159 .Lghash_inner:
160         srlg    $Zlo,$Zlo,4
161         sllg    $tmp,$Zhi,60
162         xg      $Zlo,8($nlo,$Htbl)
163         srlg    $Zhi,$Zhi,4
164         llgc    $xi,0($cnt,$Xi)
165         xg      $Zhi,0($nlo,$Htbl)
166         sllg    $nlo,$xi,4
167         xg      $Zhi,0($rem0,$rem_4bit)
168         nill    $nlo,0xf0
169         sllg    $rem0,$Zlo,3
170         xgr     $Zlo,$tmp
171         ngr     $rem0,$x78
172         nill    $xi,0xf0
173
174         sllg    $tmp,$Zhi,60
175         srlg    $Zlo,$Zlo,4
176         srlg    $Zhi,$Zhi,4
177         xg      $Zlo,8($nhi,$Htbl)
178         xg      $Zhi,0($nhi,$Htbl)
179         lgr     $nhi,$xi
180         xg      $Zhi,0($rem1,$rem_4bit)
181         sllg    $rem1,$Zlo,3
182         xgr     $Zlo,$tmp
183         ngr     $rem1,$x78
184         brct    $cnt,.Lghash_inner
185
186         sllg    $tmp,$Zhi,60
187         srlg    $Zlo,$Zlo,4
188         srlg    $Zhi,$Zhi,4
189         xg      $Zlo,8($nlo,$Htbl)
190         xg      $Zhi,0($nlo,$Htbl)
191         sllg    $xi,$Zlo,3
192         xg      $Zhi,0($rem0,$rem_4bit)
193         xgr     $Zlo,$tmp
194         ngr     $xi,$x78
195
196         sllg    $tmp,$Zhi,60
197         srlg    $Zlo,$Zlo,4
198         srlg    $Zhi,$Zhi,4
199         xg      $Zlo,8($nhi,$Htbl)
200         xg      $Zhi,0($nhi,$Htbl)
201         xgr     $Zlo,$tmp
202         xg      $Zhi,0($rem1,$rem_4bit)
203
204         lg      $tmp,0($xi,$rem_4bit)
205         la      $inp,16($inp)
206         sllg    $tmp,$tmp,4             # correct last rem_4bit[rem]
207         brctg   $len,.Louter
208
209         xgr     $Zhi,$tmp
210         stg     $Zlo,8+1($Xi)
211         stg     $Zhi,0+1($Xi)
212         lmg     %r6,%r14,48($sp)
213         br      %r14
214 .type   gcm_ghash_4bit,\@function
215 .size   gcm_ghash_4bit,(.-gcm_ghash_4bit)
216
217 .align  64
218 rem_4bit:
219         .long   `0x0000<<12`,0,`0x1C20<<12`,0,`0x3840<<12`,0,`0x2460<<12`,0
220         .long   `0x7080<<12`,0,`0x6CA0<<12`,0,`0x48C0<<12`,0,`0x54E0<<12`,0
221         .long   `0xE100<<12`,0,`0xFD20<<12`,0,`0xD940<<12`,0,`0xC560<<12`,0
222         .long   `0x9180<<12`,0,`0x8DA0<<12`,0,`0xA9C0<<12`,0,`0xB5E0<<12`,0
223 .type   rem_4bit,\@object
224 .size   rem_4bit,(.-rem_4bit)
225 .string "GHASH for s390x, CRYPTOGAMS by <appro\@openssl.org>"
226 ___
227
228 $code =~ s/\`([^\`]*)\`/eval $1/gem;
229 print $code;
230 close STDOUT;