random: Take at max 25% from RDRAND
[libgcrypt.git] / cipher / chacha20-ssse3-amd64.S
1 /* chacha20-ssse3-amd64.S  -  AMD64/SSSE3 implementation of ChaCha20
2  *
3  * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /*
22  * Based on public domain implementation by Andrew Moon at
23  *  https://github.com/floodyberry/chacha-opt
24  */
25
26 #ifdef __x86_64__
27 #include <config.h>
28
29 #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \
30      defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \
31     defined(HAVE_GCC_INLINE_ASM_SSSE3) && USE_CHACHA20
32
33 #ifdef __PIC__
34 #  define RIP (%rip)
35 #else
36 #  define RIP
37 #endif
38
39 #ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
40 # define ELF(...) __VA_ARGS__
41 #else
42 # define ELF(...) /*_*/
43 #endif
44
45 .text
46
47 .align 8
48 .globl _gcry_chacha20_amd64_ssse3_blocks
49 ELF(.type  _gcry_chacha20_amd64_ssse3_blocks,@function;)
50 _gcry_chacha20_amd64_ssse3_blocks:
51 .Lchacha_blocks_ssse3_local:
52         pushq %rbx
53         pushq %rbp
54         movq %rsp, %rbp
55         andq $~63, %rsp
56         subq $512, %rsp
57         leaq .LC RIP, %rax
58         movdqa 0(%rax), %xmm6
59         movdqa 16(%rax), %xmm7
60         movdqu 0(%rdi), %xmm8
61         movdqu 16(%rdi), %xmm9
62         movdqu 32(%rdi), %xmm10
63         movdqu 48(%rdi), %xmm11
64         movl $20, %eax
65         movq $1, %r9
66         movdqa %xmm8, 0(%rsp)
67         movdqa %xmm9, 16(%rsp)
68         movdqa %xmm10, 32(%rsp)
69         movdqa %xmm11, 48(%rsp)
70         movdqa %xmm6, 80(%rsp)
71         movdqa %xmm7, 96(%rsp)
72         movq %rax, 64(%rsp)
73         cmpq $256, %rcx
74         jb .Lchacha_blocks_ssse3_below256
75         pshufd $0x00, %xmm8, %xmm0
76         pshufd $0x55, %xmm8, %xmm1
77         pshufd $0xaa, %xmm8, %xmm2
78         pshufd $0xff, %xmm8, %xmm3
79         movdqa %xmm0, 128(%rsp)
80         movdqa %xmm1, 144(%rsp)
81         movdqa %xmm2, 160(%rsp)
82         movdqa %xmm3, 176(%rsp)
83         pshufd $0x00, %xmm9, %xmm0
84         pshufd $0x55, %xmm9, %xmm1
85         pshufd $0xaa, %xmm9, %xmm2
86         pshufd $0xff, %xmm9, %xmm3
87         movdqa %xmm0, 192(%rsp)
88         movdqa %xmm1, 208(%rsp)
89         movdqa %xmm2, 224(%rsp)
90         movdqa %xmm3, 240(%rsp)
91         pshufd $0x00, %xmm10, %xmm0
92         pshufd $0x55, %xmm10, %xmm1
93         pshufd $0xaa, %xmm10, %xmm2
94         pshufd $0xff, %xmm10, %xmm3
95         movdqa %xmm0, 256(%rsp)
96         movdqa %xmm1, 272(%rsp)
97         movdqa %xmm2, 288(%rsp)
98         movdqa %xmm3, 304(%rsp)
99         pshufd $0xaa, %xmm11, %xmm0
100         pshufd $0xff, %xmm11, %xmm1
101         movdqa %xmm0, 352(%rsp)
102         movdqa %xmm1, 368(%rsp)
103         jmp .Lchacha_blocks_ssse3_atleast256
104 .p2align 6,,63
105         # align to 4 mod 64
106         nop;nop;nop;nop;
107 .Lchacha_blocks_ssse3_atleast256:
108         movq 48(%rsp), %rax
109         leaq 1(%rax), %r8
110         leaq 2(%rax), %r9
111         leaq 3(%rax), %r10
112         leaq 4(%rax), %rbx
113         movl %eax, 320(%rsp)
114         movl %r8d, 4+320(%rsp)
115         movl %r9d, 8+320(%rsp)
116         movl %r10d, 12+320(%rsp)
117         shrq $32, %rax
118         shrq $32, %r8
119         shrq $32, %r9
120         shrq $32, %r10
121         movl %eax, 336(%rsp)
122         movl %r8d, 4+336(%rsp)
123         movl %r9d, 8+336(%rsp)
124         movl %r10d, 12+336(%rsp)
125         movq %rbx, 48(%rsp)
126         movq 64(%rsp), %rax
127         movdqa 128(%rsp), %xmm0
128         movdqa 144(%rsp), %xmm1
129         movdqa 160(%rsp), %xmm2
130         movdqa 176(%rsp), %xmm3
131         movdqa 192(%rsp), %xmm4
132         movdqa 208(%rsp), %xmm5
133         movdqa 224(%rsp), %xmm6
134         movdqa 240(%rsp), %xmm7
135         movdqa 256(%rsp), %xmm8
136         movdqa 272(%rsp), %xmm9
137         movdqa 288(%rsp), %xmm10
138         movdqa 304(%rsp), %xmm11
139         movdqa 320(%rsp), %xmm12
140         movdqa 336(%rsp), %xmm13
141         movdqa 352(%rsp), %xmm14
142         movdqa 368(%rsp), %xmm15
143 .Lchacha_blocks_ssse3_mainloop1:
144         paddd %xmm4, %xmm0
145         paddd %xmm5, %xmm1
146         pxor %xmm0, %xmm12
147         pxor %xmm1, %xmm13
148         paddd %xmm6, %xmm2
149         paddd %xmm7, %xmm3
150         pxor %xmm2, %xmm14
151         pxor %xmm3, %xmm15
152         pshufb 80(%rsp), %xmm12
153         pshufb 80(%rsp), %xmm13
154         paddd %xmm12, %xmm8
155         paddd %xmm13, %xmm9
156         pshufb 80(%rsp), %xmm14
157         pshufb 80(%rsp), %xmm15
158         paddd %xmm14, %xmm10
159         paddd %xmm15, %xmm11
160         movdqa %xmm12, 112(%rsp)
161         pxor %xmm8, %xmm4
162         pxor %xmm9, %xmm5
163         movdqa %xmm4, %xmm12
164         pslld $ 12, %xmm4
165         psrld $20, %xmm12
166         pxor %xmm12, %xmm4
167         movdqa %xmm5, %xmm12
168         pslld $ 12, %xmm5
169         psrld $20, %xmm12
170         pxor %xmm12, %xmm5
171         pxor %xmm10, %xmm6
172         pxor %xmm11, %xmm7
173         movdqa %xmm6, %xmm12
174         pslld $ 12, %xmm6
175         psrld $20, %xmm12
176         pxor %xmm12, %xmm6
177         movdqa %xmm7, %xmm12
178         pslld $ 12, %xmm7
179         psrld $20, %xmm12
180         pxor %xmm12, %xmm7
181         movdqa 112(%rsp), %xmm12
182         paddd %xmm4, %xmm0
183         paddd %xmm5, %xmm1
184         pxor %xmm0, %xmm12
185         pxor %xmm1, %xmm13
186         paddd %xmm6, %xmm2
187         paddd %xmm7, %xmm3
188         pxor %xmm2, %xmm14
189         pxor %xmm3, %xmm15
190         pshufb 96(%rsp), %xmm12
191         pshufb 96(%rsp), %xmm13
192         paddd %xmm12, %xmm8
193         paddd %xmm13, %xmm9
194         pshufb 96(%rsp), %xmm14
195         pshufb 96(%rsp), %xmm15
196         paddd %xmm14, %xmm10
197         paddd %xmm15, %xmm11
198         movdqa %xmm12, 112(%rsp)
199         pxor %xmm8, %xmm4
200         pxor %xmm9, %xmm5
201         movdqa %xmm4, %xmm12
202         pslld $ 7, %xmm4
203         psrld $25, %xmm12
204         pxor %xmm12, %xmm4
205         movdqa %xmm5, %xmm12
206         pslld $ 7, %xmm5
207         psrld $25, %xmm12
208         pxor %xmm12, %xmm5
209         pxor %xmm10, %xmm6
210         pxor %xmm11, %xmm7
211         movdqa %xmm6, %xmm12
212         pslld $ 7, %xmm6
213         psrld $25, %xmm12
214         pxor %xmm12, %xmm6
215         movdqa %xmm7, %xmm12
216         pslld $ 7, %xmm7
217         psrld $25, %xmm12
218         pxor %xmm12, %xmm7
219         movdqa 112(%rsp), %xmm12
220         paddd %xmm5, %xmm0
221         paddd %xmm6, %xmm1
222         pxor %xmm0, %xmm15
223         pxor %xmm1, %xmm12
224         paddd %xmm7, %xmm2
225         paddd %xmm4, %xmm3
226         pxor %xmm2, %xmm13
227         pxor %xmm3, %xmm14
228         pshufb 80(%rsp), %xmm15
229         pshufb 80(%rsp), %xmm12
230         paddd %xmm15, %xmm10
231         paddd %xmm12, %xmm11
232         pshufb 80(%rsp), %xmm13
233         pshufb 80(%rsp), %xmm14
234         paddd %xmm13, %xmm8
235         paddd %xmm14, %xmm9
236         movdqa %xmm15, 112(%rsp)
237         pxor %xmm10, %xmm5
238         pxor %xmm11, %xmm6
239         movdqa %xmm5, %xmm15
240         pslld $ 12, %xmm5
241         psrld $20, %xmm15
242         pxor %xmm15, %xmm5
243         movdqa %xmm6, %xmm15
244         pslld $ 12, %xmm6
245         psrld $20, %xmm15
246         pxor %xmm15, %xmm6
247         pxor %xmm8, %xmm7
248         pxor %xmm9, %xmm4
249         movdqa %xmm7, %xmm15
250         pslld $ 12, %xmm7
251         psrld $20, %xmm15
252         pxor %xmm15, %xmm7
253         movdqa %xmm4, %xmm15
254         pslld $ 12, %xmm4
255         psrld $20, %xmm15
256         pxor %xmm15, %xmm4
257         movdqa 112(%rsp), %xmm15
258         paddd %xmm5, %xmm0
259         paddd %xmm6, %xmm1
260         pxor %xmm0, %xmm15
261         pxor %xmm1, %xmm12
262         paddd %xmm7, %xmm2
263         paddd %xmm4, %xmm3
264         pxor %xmm2, %xmm13
265         pxor %xmm3, %xmm14
266         pshufb 96(%rsp), %xmm15
267         pshufb 96(%rsp), %xmm12
268         paddd %xmm15, %xmm10
269         paddd %xmm12, %xmm11
270         pshufb 96(%rsp), %xmm13
271         pshufb 96(%rsp), %xmm14
272         paddd %xmm13, %xmm8
273         paddd %xmm14, %xmm9
274         movdqa %xmm15, 112(%rsp)
275         pxor %xmm10, %xmm5
276         pxor %xmm11, %xmm6
277         movdqa %xmm5, %xmm15
278         pslld $ 7, %xmm5
279         psrld $25, %xmm15
280         pxor %xmm15, %xmm5
281         movdqa %xmm6, %xmm15
282         pslld $ 7, %xmm6
283         psrld $25, %xmm15
284         pxor %xmm15, %xmm6
285         pxor %xmm8, %xmm7
286         pxor %xmm9, %xmm4
287         movdqa %xmm7, %xmm15
288         pslld $ 7, %xmm7
289         psrld $25, %xmm15
290         pxor %xmm15, %xmm7
291         movdqa %xmm4, %xmm15
292         pslld $ 7, %xmm4
293         psrld $25, %xmm15
294         pxor %xmm15, %xmm4
295         subq $2, %rax
296         movdqa 112(%rsp), %xmm15
297         jnz .Lchacha_blocks_ssse3_mainloop1
298         paddd 128(%rsp), %xmm0
299         paddd 144(%rsp), %xmm1
300         paddd 160(%rsp), %xmm2
301         paddd 176(%rsp), %xmm3
302         paddd 192(%rsp), %xmm4
303         paddd 208(%rsp), %xmm5
304         paddd 224(%rsp), %xmm6
305         paddd 240(%rsp), %xmm7
306         paddd 256(%rsp), %xmm8
307         paddd 272(%rsp), %xmm9
308         paddd 288(%rsp), %xmm10
309         paddd 304(%rsp), %xmm11
310         paddd 320(%rsp), %xmm12
311         paddd 336(%rsp), %xmm13
312         paddd 352(%rsp), %xmm14
313         paddd 368(%rsp), %xmm15
314         movdqa %xmm8, 384(%rsp)
315         movdqa %xmm9, 400(%rsp)
316         movdqa %xmm10, 416(%rsp)
317         movdqa %xmm11, 432(%rsp)
318         movdqa %xmm12, 448(%rsp)
319         movdqa %xmm13, 464(%rsp)
320         movdqa %xmm14, 480(%rsp)
321         movdqa %xmm15, 496(%rsp)
322         movdqa %xmm0, %xmm8
323         movdqa %xmm2, %xmm9
324         movdqa %xmm4, %xmm10
325         movdqa %xmm6, %xmm11
326         punpckhdq %xmm1, %xmm0
327         punpckhdq %xmm3, %xmm2
328         punpckhdq %xmm5, %xmm4
329         punpckhdq %xmm7, %xmm6
330         punpckldq %xmm1, %xmm8
331         punpckldq %xmm3, %xmm9
332         punpckldq %xmm5, %xmm10
333         punpckldq %xmm7, %xmm11
334         movdqa %xmm0, %xmm1
335         movdqa %xmm4, %xmm3
336         movdqa %xmm8, %xmm5
337         movdqa %xmm10, %xmm7
338         punpckhqdq %xmm2, %xmm0
339         punpckhqdq %xmm6, %xmm4
340         punpckhqdq %xmm9, %xmm8
341         punpckhqdq %xmm11, %xmm10
342         punpcklqdq %xmm2, %xmm1
343         punpcklqdq %xmm6, %xmm3
344         punpcklqdq %xmm9, %xmm5
345         punpcklqdq %xmm11, %xmm7
346         andq %rsi, %rsi
347         jz .Lchacha_blocks_ssse3_noinput1
348         movdqu 0(%rsi), %xmm2
349         movdqu 16(%rsi), %xmm6
350         movdqu 64(%rsi), %xmm9
351         movdqu 80(%rsi), %xmm11
352         movdqu 128(%rsi), %xmm12
353         movdqu 144(%rsi), %xmm13
354         movdqu 192(%rsi), %xmm14
355         movdqu 208(%rsi), %xmm15
356         pxor %xmm2, %xmm5
357         pxor %xmm6, %xmm7
358         pxor %xmm9, %xmm8
359         pxor %xmm11, %xmm10
360         pxor %xmm12, %xmm1
361         pxor %xmm13, %xmm3
362         pxor %xmm14, %xmm0
363         pxor %xmm15, %xmm4
364         movdqu %xmm5, 0(%rdx)
365         movdqu %xmm7, 16(%rdx)
366         movdqu %xmm8, 64(%rdx)
367         movdqu %xmm10, 80(%rdx)
368         movdqu %xmm1, 128(%rdx)
369         movdqu %xmm3, 144(%rdx)
370         movdqu %xmm0, 192(%rdx)
371         movdqu %xmm4, 208(%rdx)
372         movdqa 384(%rsp), %xmm0
373         movdqa 400(%rsp), %xmm1
374         movdqa 416(%rsp), %xmm2
375         movdqa 432(%rsp), %xmm3
376         movdqa 448(%rsp), %xmm4
377         movdqa 464(%rsp), %xmm5
378         movdqa 480(%rsp), %xmm6
379         movdqa 496(%rsp), %xmm7
380         movdqa %xmm0, %xmm8
381         movdqa %xmm2, %xmm9
382         movdqa %xmm4, %xmm10
383         movdqa %xmm6, %xmm11
384         punpckldq %xmm1, %xmm8
385         punpckldq %xmm3, %xmm9
386         punpckhdq %xmm1, %xmm0
387         punpckhdq %xmm3, %xmm2
388         punpckldq %xmm5, %xmm10
389         punpckldq %xmm7, %xmm11
390         punpckhdq %xmm5, %xmm4
391         punpckhdq %xmm7, %xmm6
392         movdqa %xmm8, %xmm1
393         movdqa %xmm0, %xmm3
394         movdqa %xmm10, %xmm5
395         movdqa %xmm4, %xmm7
396         punpcklqdq %xmm9, %xmm1
397         punpcklqdq %xmm11, %xmm5
398         punpckhqdq %xmm9, %xmm8
399         punpckhqdq %xmm11, %xmm10
400         punpcklqdq %xmm2, %xmm3
401         punpcklqdq %xmm6, %xmm7
402         punpckhqdq %xmm2, %xmm0
403         punpckhqdq %xmm6, %xmm4
404         movdqu 32(%rsi), %xmm2
405         movdqu 48(%rsi), %xmm6
406         movdqu 96(%rsi), %xmm9
407         movdqu 112(%rsi), %xmm11
408         movdqu 160(%rsi), %xmm12
409         movdqu 176(%rsi), %xmm13
410         movdqu 224(%rsi), %xmm14
411         movdqu 240(%rsi), %xmm15
412         pxor %xmm2, %xmm1
413         pxor %xmm6, %xmm5
414         pxor %xmm9, %xmm8
415         pxor %xmm11, %xmm10
416         pxor %xmm12, %xmm3
417         pxor %xmm13, %xmm7
418         pxor %xmm14, %xmm0
419         pxor %xmm15, %xmm4
420         movdqu %xmm1, 32(%rdx)
421         movdqu %xmm5, 48(%rdx)
422         movdqu %xmm8, 96(%rdx)
423         movdqu %xmm10, 112(%rdx)
424         movdqu %xmm3, 160(%rdx)
425         movdqu %xmm7, 176(%rdx)
426         movdqu %xmm0, 224(%rdx)
427         movdqu %xmm4, 240(%rdx)
428         addq $256, %rsi
429         jmp .Lchacha_blocks_ssse3_mainloop_cont
430 .Lchacha_blocks_ssse3_noinput1:
431         movdqu %xmm5, 0(%rdx)
432         movdqu %xmm7, 16(%rdx)
433         movdqu %xmm8, 64(%rdx)
434         movdqu %xmm10, 80(%rdx)
435         movdqu %xmm1, 128(%rdx)
436         movdqu %xmm3, 144(%rdx)
437         movdqu %xmm0, 192(%rdx)
438         movdqu %xmm4, 208(%rdx)
439         movdqa 384(%rsp), %xmm0
440         movdqa 400(%rsp), %xmm1
441         movdqa 416(%rsp), %xmm2
442         movdqa 432(%rsp), %xmm3
443         movdqa 448(%rsp), %xmm4
444         movdqa 464(%rsp), %xmm5
445         movdqa 480(%rsp), %xmm6
446         movdqa 496(%rsp), %xmm7
447         movdqa %xmm0, %xmm8
448         movdqa %xmm2, %xmm9
449         movdqa %xmm4, %xmm10
450         movdqa %xmm6, %xmm11
451         punpckldq %xmm1, %xmm8
452         punpckldq %xmm3, %xmm9
453         punpckhdq %xmm1, %xmm0
454         punpckhdq %xmm3, %xmm2
455         punpckldq %xmm5, %xmm10
456         punpckldq %xmm7, %xmm11
457         punpckhdq %xmm5, %xmm4
458         punpckhdq %xmm7, %xmm6
459         movdqa %xmm8, %xmm1
460         movdqa %xmm0, %xmm3
461         movdqa %xmm10, %xmm5
462         movdqa %xmm4, %xmm7
463         punpcklqdq %xmm9, %xmm1
464         punpcklqdq %xmm11, %xmm5
465         punpckhqdq %xmm9, %xmm8
466         punpckhqdq %xmm11, %xmm10
467         punpcklqdq %xmm2, %xmm3
468         punpcklqdq %xmm6, %xmm7
469         punpckhqdq %xmm2, %xmm0
470         punpckhqdq %xmm6, %xmm4
471         movdqu %xmm1, 32(%rdx)
472         movdqu %xmm5, 48(%rdx)
473         movdqu %xmm8, 96(%rdx)
474         movdqu %xmm10, 112(%rdx)
475         movdqu %xmm3, 160(%rdx)
476         movdqu %xmm7, 176(%rdx)
477         movdqu %xmm0, 224(%rdx)
478         movdqu %xmm4, 240(%rdx)
479 .Lchacha_blocks_ssse3_mainloop_cont:
480         addq $256, %rdx
481         subq $256, %rcx
482         cmp $256, %rcx
483         jae .Lchacha_blocks_ssse3_atleast256
484         movdqa 80(%rsp), %xmm6
485         movdqa 96(%rsp), %xmm7
486         movdqa 0(%rsp), %xmm8
487         movdqa 16(%rsp), %xmm9
488         movdqa 32(%rsp), %xmm10
489         movdqa 48(%rsp), %xmm11
490         movq $1, %r9
491 .Lchacha_blocks_ssse3_below256:
492         movq %r9, %xmm5
493         andq %rcx, %rcx
494         jz .Lchacha_blocks_ssse3_done
495         cmpq $64, %rcx
496         jae .Lchacha_blocks_ssse3_above63
497         movq %rdx, %r9
498         andq %rsi, %rsi
499         jz .Lchacha_blocks_ssse3_noinput2
500         movq %rcx, %r10
501         movq %rsp, %rdx
502         addq %r10, %rsi
503         addq %r10, %rdx
504         negq %r10
505 .Lchacha_blocks_ssse3_copyinput:
506         movb (%rsi, %r10), %al
507         movb %al, (%rdx, %r10)
508         incq %r10
509         jnz .Lchacha_blocks_ssse3_copyinput
510         movq %rsp, %rsi
511 .Lchacha_blocks_ssse3_noinput2:
512         movq %rsp, %rdx
513 .Lchacha_blocks_ssse3_above63:
514         movdqa %xmm8, %xmm0
515         movdqa %xmm9, %xmm1
516         movdqa %xmm10, %xmm2
517         movdqa %xmm11, %xmm3
518         movq 64(%rsp), %rax
519 .Lchacha_blocks_ssse3_mainloop2:
520         paddd %xmm1, %xmm0
521         pxor %xmm0, %xmm3
522         pshufb %xmm6, %xmm3
523         paddd %xmm3, %xmm2
524         pxor %xmm2, %xmm1
525         movdqa %xmm1, %xmm4
526         pslld $12, %xmm4
527         psrld $20, %xmm1
528         pxor %xmm4, %xmm1
529         paddd %xmm1, %xmm0
530         pxor %xmm0, %xmm3
531         pshufb %xmm7, %xmm3
532         pshufd $0x93, %xmm0, %xmm0
533         paddd %xmm3, %xmm2
534         pshufd $0x4e, %xmm3, %xmm3
535         pxor %xmm2, %xmm1
536         pshufd $0x39, %xmm2, %xmm2
537         movdqa %xmm1, %xmm4
538         pslld $7, %xmm4
539         psrld $25, %xmm1
540         pxor %xmm4, %xmm1
541         paddd %xmm1, %xmm0
542         pxor %xmm0, %xmm3
543         pshufb %xmm6, %xmm3
544         paddd %xmm3, %xmm2
545         pxor %xmm2, %xmm1
546         movdqa %xmm1, %xmm4
547         pslld $12, %xmm4
548         psrld $20, %xmm1
549         pxor %xmm4, %xmm1
550         paddd %xmm1, %xmm0
551         pxor %xmm0, %xmm3
552         pshufb %xmm7, %xmm3
553         pshufd $0x39, %xmm0, %xmm0
554         paddd %xmm3, %xmm2
555         pshufd $0x4e, %xmm3, %xmm3
556         pxor %xmm2, %xmm1
557         pshufd $0x93, %xmm2, %xmm2
558         movdqa %xmm1, %xmm4
559         pslld $7, %xmm4
560         psrld $25, %xmm1
561         pxor %xmm4, %xmm1
562         subq $2, %rax
563         jnz .Lchacha_blocks_ssse3_mainloop2
564         paddd %xmm8, %xmm0
565         paddd %xmm9, %xmm1
566         paddd %xmm10, %xmm2
567         paddd %xmm11, %xmm3
568         andq %rsi, %rsi
569         jz .Lchacha_blocks_ssse3_noinput3
570         movdqu 0(%rsi), %xmm12
571         movdqu 16(%rsi), %xmm13
572         movdqu 32(%rsi), %xmm14
573         movdqu 48(%rsi), %xmm15
574         pxor %xmm12, %xmm0
575         pxor %xmm13, %xmm1
576         pxor %xmm14, %xmm2
577         pxor %xmm15, %xmm3
578         addq $64, %rsi
579 .Lchacha_blocks_ssse3_noinput3:
580         movdqu %xmm0, 0(%rdx)
581         movdqu %xmm1, 16(%rdx)
582         movdqu %xmm2, 32(%rdx)
583         movdqu %xmm3, 48(%rdx)
584         paddq %xmm5, %xmm11
585         cmpq $64, %rcx
586         jbe .Lchacha_blocks_ssse3_mainloop2_finishup
587         addq $64, %rdx
588         subq $64, %rcx
589         jmp .Lchacha_blocks_ssse3_below256
590 .Lchacha_blocks_ssse3_mainloop2_finishup:
591         cmpq $64, %rcx
592         je .Lchacha_blocks_ssse3_done
593         addq %rcx, %r9
594         addq %rcx, %rdx
595         negq %rcx
596 .Lchacha_blocks_ssse3_copyoutput:
597         movb (%rdx, %rcx), %al
598         movb %al, (%r9, %rcx)
599         incq %rcx
600         jnz .Lchacha_blocks_ssse3_copyoutput
601 .Lchacha_blocks_ssse3_done:
602         movdqu %xmm11, 48(%rdi)
603         movq %rbp, %rsp
604         pxor %xmm15, %xmm15
605         pxor %xmm7, %xmm7
606         pxor %xmm14, %xmm14
607         pxor %xmm6, %xmm6
608         pxor %xmm13, %xmm13
609         pxor %xmm5, %xmm5
610         pxor %xmm12, %xmm12
611         pxor %xmm4, %xmm4
612         popq %rbp
613         popq %rbx
614         movl $(63 + 512 + 16), %eax
615         pxor %xmm11, %xmm11
616         pxor %xmm3, %xmm3
617         pxor %xmm10, %xmm10
618         pxor %xmm2, %xmm2
619         pxor %xmm9, %xmm9
620         pxor %xmm1, %xmm1
621         pxor %xmm8, %xmm8
622         pxor %xmm0, %xmm0
623         ret
624 ELF(.size _gcry_chacha20_amd64_ssse3_blocks,.-_gcry_chacha20_amd64_ssse3_blocks;)
625
626 .data
627 .align 16;
628 .LC:
629 .byte 2,3,0,1,6,7,4,5,10,11,8,9,14,15,12,13       /* pshufb rotate by 16 */
630 .byte 3,0,1,2,7,4,5,6,11,8,9,10,15,12,13,14       /* pshufb rotate by 8 */
631
632 #endif /*defined(USE_CHACHA20)*/
633 #endif /*__x86_64*/