GHASH assembler: new ghash-sparcv9.pl module and saner descriptions.
[openssl.git] / crypto / modes / asm / ghash-x86_64.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 # March 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 # results are for streamed GHASH subroutine and are expressed in
16 # cycles per processed byte, less is better:
17 #
18 #               gcc 3.4.x       assembler
19 #
20 # Opteron       18.5            10.2            +80%
21 # Core2         26.0            16.4            +58%
22
23 $flavour = shift;
24 $output  = shift;
25 if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
26
27 $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
28
29 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
30 ( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
31 ( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or
32 die "can't locate x86_64-xlate.pl";
33
34 open STDOUT,"| $^X $xlate $flavour $output";
35
36 # common register layout
37 $nlo="%rax";
38 $nhi="%rbx";
39 $Zlo="%r8";
40 $Zhi="%r9";
41 $tmp="%r10";
42 $rem_4bit = "%r11";
43
44 # per-function register layout
45 $Xi="%rdi";
46 $Htbl="%rsi";
47
48 $cnt="%rcx";
49 $rem="%rdx";
50
51 sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/;
52                         $r =~ s/%[er]([sd]i)/%\1l/;
53                         $r =~ s/%(r[0-9]+)[d]?/%\1b/;   $r; }
54
55 { my $N;
56   sub loop() {
57   my $inp = shift;
58
59         $N++;
60 $code.=<<___;
61         xor     $nlo,$nlo
62         xor     $nhi,$nhi
63         mov     `&lo("$Zlo")`,`&lo("$nlo")`
64         mov     `&lo("$Zlo")`,`&lo("$nhi")`
65         shl     \$4,`&lo("$nlo")`
66         mov     \$14,$cnt
67         mov     8($Htbl,$nlo),$Zlo
68         mov     ($Htbl,$nlo),$Zhi
69         and     \$0xf0,`&lo("$nhi")`
70         mov     $Zlo,$rem
71         jmp     .Loop$N
72
73 .align  16
74 .Loop$N:
75         shr     \$4,$Zlo
76         and     \$0xf,$rem
77         mov     $Zhi,$tmp
78         mov     ($inp,$cnt),`&lo("$nlo")`
79         shr     \$4,$Zhi
80         xor     8($Htbl,$nhi),$Zlo
81         shl     \$60,$tmp
82         xor     ($Htbl,$nhi),$Zhi
83         mov     `&lo("$nlo")`,`&lo("$nhi")`
84         xor     ($rem_4bit,$rem,8),$Zhi
85         mov     $Zlo,$rem
86         shl     \$4,`&lo("$nlo")`
87         xor     $tmp,$Zlo
88         dec     $cnt
89         js      .Lbreak$N
90
91         shr     \$4,$Zlo
92         and     \$0xf,$rem
93         mov     $Zhi,$tmp
94         shr     \$4,$Zhi
95         xor     8($Htbl,$nlo),$Zlo
96         shl     \$60,$tmp
97         xor     ($Htbl,$nlo),$Zhi
98         and     \$0xf0,`&lo("$nhi")`
99         xor     ($rem_4bit,$rem,8),$Zhi
100         mov     $Zlo,$rem
101         xor     $tmp,$Zlo
102         jmp     .Loop$N
103
104 .align  16
105 .Lbreak$N:
106         shr     \$4,$Zlo
107         and     \$0xf,$rem
108         mov     $Zhi,$tmp
109         shr     \$4,$Zhi
110         xor     8($Htbl,$nlo),$Zlo
111         shl     \$60,$tmp
112         xor     ($Htbl,$nlo),$Zhi
113         and     \$0xf0,`&lo("$nhi")`
114         xor     ($rem_4bit,$rem,8),$Zhi
115         mov     $Zlo,$rem
116         xor     $tmp,$Zlo
117
118         shr     \$4,$Zlo
119         and     \$0xf,$rem
120         mov     $Zhi,$tmp
121         shr     \$4,$Zhi
122         xor     8($Htbl,$nhi),$Zlo
123         shl     \$60,$tmp
124         xor     ($Htbl,$nhi),$Zhi
125         xor     $tmp,$Zlo
126         xor     ($rem_4bit,$rem,8),$Zhi
127
128         bswap   $Zlo
129         bswap   $Zhi
130 ___
131 }}
132
133 $code=<<___;
134 .text
135
136 .globl  gcm_gmult_4bit
137 .type   gcm_gmult_4bit,\@function,2
138 .align  16
139 gcm_gmult_4bit:
140         push    %rbx
141         push    %rbp            # %rbp and %r12 are pushed exclusively in
142         push    %r12            # order to reuse Win64 exception handler...
143 .Lgmult_prologue:
144
145         movzb   15($Xi),$Zlo
146         lea     .Lrem_4bit(%rip),$rem_4bit
147 ___
148         &loop   ($Xi);
149 $code.=<<___;
150         mov     $Zlo,8($Xi)
151         mov     $Zhi,($Xi)
152
153         mov     16(%rsp),%rbx
154         lea     24(%rsp),%rsp
155 .Lgmult_epilogue:
156         ret
157 .size   gcm_gmult_4bit,.-gcm_gmult_4bit
158 ___
159
160
161 # per-function register layout
162 $inp="%rdi";
163 $len="%rsi";
164 $Xi="%rdx";
165 $Htbl="%rcx";
166
167 $cnt="%rbp";
168 $rem="%r12";
169
170 $code.=<<___;
171 .globl  gcm_ghash_4bit
172 .type   gcm_ghash_4bit,\@function,4
173 .align  16
174 gcm_ghash_4bit:
175         push    %rbx
176         push    %rbp
177         push    %r12
178 .Lghash_prologue:
179
180         mov     8($Xi),$Zlo
181         mov     ($Xi),$Zhi
182         add     $inp,$len
183         lea     .Lrem_4bit(%rip),$rem_4bit
184 .align  4
185 .Louter_loop:
186         xor     8($inp),$Zlo
187         xor     ($inp),$Zhi
188         lea     16($inp),$inp
189         mov     $Zlo,8($Xi)
190         mov     $Zhi,($Xi)
191         shr     \$56,$Zlo
192 ___
193         &loop   ($Xi);
194 $code.=<<___;
195         cmp     $len,$inp
196         jb      .Louter_loop
197
198         mov     $Zlo,8($Xi)
199         mov     $Zhi,($Xi)
200
201         mov     0(%rsp),%r12
202         mov     8(%rsp),%rbp
203         mov     16(%rsp),%rbx
204         lea     24(%rsp),%rsp
205 .Lghash_epilogue:
206         ret
207 .size   gcm_ghash_4bit,.-gcm_ghash_4bit
208
209 .align  64
210 .type   rem_4bit,\@object
211 .Lrem_4bit:
212         .long   0,`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`
213         .long   0,`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`
214         .long   0,`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`
215         .long   0,`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`
216 .asciz  "GHASH for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
217 .align  64
218 ___
219
220 # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
221 #               CONTEXT *context,DISPATCHER_CONTEXT *disp)
222 if ($win64) {
223 $rec="%rcx";
224 $frame="%rdx";
225 $context="%r8";
226 $disp="%r9";
227
228 $code.=<<___;
229 .extern __imp_RtlVirtualUnwind
230 .type   se_handler,\@abi-omnipotent
231 .align  16
232 se_handler:
233         push    %rsi
234         push    %rdi
235         push    %rbx
236         push    %rbp
237         push    %r12
238         push    %r13
239         push    %r14
240         push    %r15
241         pushfq
242         sub     \$64,%rsp
243
244         mov     120($context),%rax      # pull context->Rax
245         mov     248($context),%rbx      # pull context->Rip
246
247         mov     8($disp),%rsi           # disp->ImageBase
248         mov     56($disp),%r11          # disp->HandlerData
249
250         mov     0(%r11),%r10d           # HandlerData[0]
251         lea     (%rsi,%r10),%r10        # prologue label
252         cmp     %r10,%rbx               # context->Rip<prologue label
253         jb      .Lin_prologue
254
255         mov     152($context),%rax      # pull context->Rsp
256
257         mov     4(%r11),%r10d           # HandlerData[1]
258         lea     (%rsi,%r10),%r10        # epilogue label
259         cmp     %r10,%rbx               # context->Rip>=epilogue label
260         jae     .Lin_prologue
261
262         lea     24(%rax),%rax           # adjust "rsp"
263
264         mov     -8(%rax),%rbx
265         mov     -16(%rax),%rbp
266         mov     -24(%rax),%r12
267         mov     %rbx,144($context)      # restore context->Rbx
268         mov     %rbp,160($context)      # restore context->Rbp
269         mov     %r12,216($context)      # restore context->R12
270
271 .Lin_prologue:
272         mov     8(%rax),%rdi
273         mov     16(%rax),%rsi
274         mov     %rax,152($context)      # restore context->Rsp
275         mov     %rsi,168($context)      # restore context->Rsi
276         mov     %rdi,176($context)      # restore context->Rdi
277
278         mov     40($disp),%rdi          # disp->ContextRecord
279         mov     $context,%rsi           # context
280         mov     \$`1232/8`,%ecx         # sizeof(CONTEXT)
281         .long   0xa548f3fc              # cld; rep movsq
282
283         mov     $disp,%rsi
284         xor     %rcx,%rcx               # arg1, UNW_FLAG_NHANDLER
285         mov     8(%rsi),%rdx            # arg2, disp->ImageBase
286         mov     0(%rsi),%r8             # arg3, disp->ControlPc
287         mov     16(%rsi),%r9            # arg4, disp->FunctionEntry
288         mov     40(%rsi),%r10           # disp->ContextRecord
289         lea     56(%rsi),%r11           # &disp->HandlerData
290         lea     24(%rsi),%r12           # &disp->EstablisherFrame
291         mov     %r10,32(%rsp)           # arg5
292         mov     %r11,40(%rsp)           # arg6
293         mov     %r12,48(%rsp)           # arg7
294         mov     %rcx,56(%rsp)           # arg8, (NULL)
295         call    *__imp_RtlVirtualUnwind(%rip)
296
297         mov     \$1,%eax                # ExceptionContinueSearch
298         add     \$64,%rsp
299         popfq
300         pop     %r15
301         pop     %r14
302         pop     %r13
303         pop     %r12
304         pop     %rbp
305         pop     %rbx
306         pop     %rdi
307         pop     %rsi
308         ret
309 .size   se_handler,.-se_handler
310
311 .section        .pdata
312 .align  4
313         .rva    .LSEH_begin_gcm_gmult_4bit
314         .rva    .LSEH_end_gcm_gmult_4bit
315         .rva    .LSEH_info_gcm_gmult_4bit
316
317         .rva    .LSEH_begin_gcm_ghash_4bit
318         .rva    .LSEH_end_gcm_ghash_4bit
319         .rva    .LSEH_info_gcm_ghash_4bit
320
321 .section        .xdata
322 .align  8
323 .LSEH_info_gcm_gmult_4bit:
324         .byte   9,0,0,0
325         .rva    se_handler
326         .rva    .Lgmult_prologue,.Lgmult_epilogue       # HandlerData
327 .LSEH_info_gcm_ghash_4bit:
328         .byte   9,0,0,0
329         .rva    se_handler
330         .rva    .Lghash_prologue,.Lghash_epilogue       # HandlerData
331 ___
332 }
333 $code =~ s/\`([^\`]*)\`/eval($1)/gem;
334
335 print $code;
336
337 close STDOUT;