Add ghash-parisc.pl.
[oweals/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         17.5            11.0            +59%
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 $Xi="%rdi";
45 $Htbl="%rsi";
46
47 # per-function register layout
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="%rdx";
163 $len="%rcx";
164
165 $cnt="%rbp";
166 $rem="%r12";
167
168 $code.=<<___;
169 .globl  gcm_ghash_4bit
170 .type   gcm_ghash_4bit,\@function,4
171 .align  16
172 gcm_ghash_4bit:
173         push    %rbx
174         push    %rbp
175         push    %r12
176 .Lghash_prologue:
177
178         mov     8($Xi),$Zlo
179         mov     ($Xi),$Zhi
180         add     $inp,$len
181         lea     .Lrem_4bit(%rip),$rem_4bit
182 .align  4
183 .Louter_loop:
184         xor     8($inp),$Zlo
185         xor     ($inp),$Zhi
186         lea     16($inp),$inp
187         mov     $Zlo,8($Xi)
188         mov     $Zhi,($Xi)
189         shr     \$56,$Zlo
190 ___
191         &loop   ($Xi);
192 $code.=<<___;
193         cmp     $len,$inp
194         jb      .Louter_loop
195
196         mov     $Zlo,8($Xi)
197         mov     $Zhi,($Xi)
198
199         mov     0(%rsp),%r12
200         mov     8(%rsp),%rbp
201         mov     16(%rsp),%rbx
202         lea     24(%rsp),%rsp
203 .Lghash_epilogue:
204         ret
205 .size   gcm_ghash_4bit,.-gcm_ghash_4bit
206
207 .align  64
208 .type   rem_4bit,\@object
209 .Lrem_4bit:
210         .long   0,`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`
211         .long   0,`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`
212         .long   0,`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`
213         .long   0,`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`
214 .asciz  "GHASH for x86_64, CRYPTOGAMS by <appro\@openssl.org>"
215 .align  64
216 ___
217
218 # EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
219 #               CONTEXT *context,DISPATCHER_CONTEXT *disp)
220 if ($win64) {
221 $rec="%rcx";
222 $frame="%rdx";
223 $context="%r8";
224 $disp="%r9";
225
226 $code.=<<___;
227 .extern __imp_RtlVirtualUnwind
228 .type   se_handler,\@abi-omnipotent
229 .align  16
230 se_handler:
231         push    %rsi
232         push    %rdi
233         push    %rbx
234         push    %rbp
235         push    %r12
236         push    %r13
237         push    %r14
238         push    %r15
239         pushfq
240         sub     \$64,%rsp
241
242         mov     120($context),%rax      # pull context->Rax
243         mov     248($context),%rbx      # pull context->Rip
244
245         mov     8($disp),%rsi           # disp->ImageBase
246         mov     56($disp),%r11          # disp->HandlerData
247
248         mov     0(%r11),%r10d           # HandlerData[0]
249         lea     (%rsi,%r10),%r10        # prologue label
250         cmp     %r10,%rbx               # context->Rip<prologue label
251         jb      .Lin_prologue
252
253         mov     152($context),%rax      # pull context->Rsp
254
255         mov     4(%r11),%r10d           # HandlerData[1]
256         lea     (%rsi,%r10),%r10        # epilogue label
257         cmp     %r10,%rbx               # context->Rip>=epilogue label
258         jae     .Lin_prologue
259
260         lea     24(%rax),%rax           # adjust "rsp"
261
262         mov     -8(%rax),%rbx
263         mov     -16(%rax),%rbp
264         mov     -24(%rax),%r12
265         mov     %rbx,144($context)      # restore context->Rbx
266         mov     %rbp,160($context)      # restore context->Rbp
267         mov     %r12,216($context)      # restore context->R12
268
269 .Lin_prologue:
270         mov     8(%rax),%rdi
271         mov     16(%rax),%rsi
272         mov     %rax,152($context)      # restore context->Rsp
273         mov     %rsi,168($context)      # restore context->Rsi
274         mov     %rdi,176($context)      # restore context->Rdi
275
276         mov     40($disp),%rdi          # disp->ContextRecord
277         mov     $context,%rsi           # context
278         mov     \$`1232/8`,%ecx         # sizeof(CONTEXT)
279         .long   0xa548f3fc              # cld; rep movsq
280
281         mov     $disp,%rsi
282         xor     %rcx,%rcx               # arg1, UNW_FLAG_NHANDLER
283         mov     8(%rsi),%rdx            # arg2, disp->ImageBase
284         mov     0(%rsi),%r8             # arg3, disp->ControlPc
285         mov     16(%rsi),%r9            # arg4, disp->FunctionEntry
286         mov     40(%rsi),%r10           # disp->ContextRecord
287         lea     56(%rsi),%r11           # &disp->HandlerData
288         lea     24(%rsi),%r12           # &disp->EstablisherFrame
289         mov     %r10,32(%rsp)           # arg5
290         mov     %r11,40(%rsp)           # arg6
291         mov     %r12,48(%rsp)           # arg7
292         mov     %rcx,56(%rsp)           # arg8, (NULL)
293         call    *__imp_RtlVirtualUnwind(%rip)
294
295         mov     \$1,%eax                # ExceptionContinueSearch
296         add     \$64,%rsp
297         popfq
298         pop     %r15
299         pop     %r14
300         pop     %r13
301         pop     %r12
302         pop     %rbp
303         pop     %rbx
304         pop     %rdi
305         pop     %rsi
306         ret
307 .size   se_handler,.-se_handler
308
309 .section        .pdata
310 .align  4
311         .rva    .LSEH_begin_gcm_gmult_4bit
312         .rva    .LSEH_end_gcm_gmult_4bit
313         .rva    .LSEH_info_gcm_gmult_4bit
314
315         .rva    .LSEH_begin_gcm_ghash_4bit
316         .rva    .LSEH_end_gcm_ghash_4bit
317         .rva    .LSEH_info_gcm_ghash_4bit
318
319 .section        .xdata
320 .align  8
321 .LSEH_info_gcm_gmult_4bit:
322         .byte   9,0,0,0
323         .rva    se_handler
324         .rva    .Lgmult_prologue,.Lgmult_epilogue       # HandlerData
325 .LSEH_info_gcm_ghash_4bit:
326         .byte   9,0,0,0
327         .rva    se_handler
328         .rva    .Lghash_prologue,.Lghash_epilogue       # HandlerData
329 ___
330 }
331 $code =~ s/\`([^\`]*)\`/eval($1)/gem;
332
333 print $code;
334
335 close STDOUT;