Add crypto hash SM3.
[libgcrypt.git] / cipher / chacha20-sse2-amd64.S
1 /* chacha20-sse2-amd64.S  -  AMD64/SSE2 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)) && USE_CHACHA20
31
32 #ifdef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
33 # define ELF(...) __VA_ARGS__
34 #else
35 # define ELF(...) /*_*/
36 #endif
37
38 .text
39
40 .align 8
41 .globl _gcry_chacha20_amd64_sse2_blocks
42 ELF(.type  _gcry_chacha20_amd64_sse2_blocks,@function;)
43 _gcry_chacha20_amd64_sse2_blocks:
44 .Lchacha_blocks_sse2_local:
45         pushq %rbx
46         pushq %rbp
47         movq %rsp, %rbp
48         andq $~63, %rsp
49         subq $512, %rsp
50         movdqu (%rdi), %xmm8
51         movdqu 16(%rdi), %xmm9
52         movdqu 32(%rdi), %xmm10
53         movdqu 48(%rdi), %xmm11
54         movq $20, %rax
55         movq $1, %r9
56         movdqa %xmm8, 0(%rsp)
57         movdqa %xmm9, 16(%rsp)
58         movdqa %xmm10, 32(%rsp)
59         movdqa %xmm11, 48(%rsp)
60         movq %rax, 64(%rsp)
61         cmpq $256, %rcx
62         jb .Lchacha_blocks_sse2_below256
63         pshufd $0x00, %xmm8, %xmm0
64         pshufd $0x55, %xmm8, %xmm1
65         pshufd $0xaa, %xmm8, %xmm2
66         pshufd $0xff, %xmm8, %xmm3
67         movdqa %xmm0, 128(%rsp)
68         movdqa %xmm1, 144(%rsp)
69         movdqa %xmm2, 160(%rsp)
70         movdqa %xmm3, 176(%rsp)
71         pshufd $0x00, %xmm9, %xmm0
72         pshufd $0x55, %xmm9, %xmm1
73         pshufd $0xaa, %xmm9, %xmm2
74         pshufd $0xff, %xmm9, %xmm3
75         movdqa %xmm0, 192(%rsp)
76         movdqa %xmm1, 208(%rsp)
77         movdqa %xmm2, 224(%rsp)
78         movdqa %xmm3, 240(%rsp)
79         pshufd $0x00, %xmm10, %xmm0
80         pshufd $0x55, %xmm10, %xmm1
81         pshufd $0xaa, %xmm10, %xmm2
82         pshufd $0xff, %xmm10, %xmm3
83         movdqa %xmm0, 256(%rsp)
84         movdqa %xmm1, 272(%rsp)
85         movdqa %xmm2, 288(%rsp)
86         movdqa %xmm3, 304(%rsp)
87         pshufd $0xaa, %xmm11, %xmm0
88         pshufd $0xff, %xmm11, %xmm1
89         movdqa %xmm0, 352(%rsp)
90         movdqa %xmm1, 368(%rsp)
91         jmp .Lchacha_blocks_sse2_atleast256
92 .p2align 6,,63
93 .Lchacha_blocks_sse2_atleast256:
94         movq 48(%rsp), %rax
95         leaq 1(%rax), %r8
96         leaq 2(%rax), %r9
97         leaq 3(%rax), %r10
98         leaq 4(%rax), %rbx
99         movl %eax, 320(%rsp)
100         movl %r8d, 4+320(%rsp)
101         movl %r9d, 8+320(%rsp)
102         movl %r10d, 12+320(%rsp)
103         shrq $32, %rax
104         shrq $32, %r8
105         shrq $32, %r9
106         shrq $32, %r10
107         movl %eax, 336(%rsp)
108         movl %r8d, 4+336(%rsp)
109         movl %r9d, 8+336(%rsp)
110         movl %r10d, 12+336(%rsp)
111         movq %rbx, 48(%rsp)
112         movq 64(%rsp), %rax
113         movdqa 128(%rsp), %xmm0
114         movdqa 144(%rsp), %xmm1
115         movdqa 160(%rsp), %xmm2
116         movdqa 176(%rsp), %xmm3
117         movdqa 192(%rsp), %xmm4
118         movdqa 208(%rsp), %xmm5
119         movdqa 224(%rsp), %xmm6
120         movdqa 240(%rsp), %xmm7
121         movdqa 256(%rsp), %xmm8
122         movdqa 272(%rsp), %xmm9
123         movdqa 288(%rsp), %xmm10
124         movdqa 304(%rsp), %xmm11
125         movdqa 320(%rsp), %xmm12
126         movdqa 336(%rsp), %xmm13
127         movdqa 352(%rsp), %xmm14
128         movdqa 368(%rsp), %xmm15
129 .Lchacha_blocks_sse2_mainloop1:
130         paddd %xmm4, %xmm0
131         paddd %xmm5, %xmm1
132         pxor %xmm0, %xmm12
133         pxor %xmm1, %xmm13
134         paddd %xmm6, %xmm2
135         paddd %xmm7, %xmm3
136         movdqa %xmm6, 96(%rsp)
137         pxor %xmm2, %xmm14
138         pxor %xmm3, %xmm15
139         pshuflw $0xb1,%xmm12,%xmm12
140         pshufhw $0xb1,%xmm12,%xmm12
141         pshuflw $0xb1,%xmm13,%xmm13
142         pshufhw $0xb1,%xmm13,%xmm13
143         pshuflw $0xb1,%xmm14,%xmm14
144         pshufhw $0xb1,%xmm14,%xmm14
145         pshuflw $0xb1,%xmm15,%xmm15
146         pshufhw $0xb1,%xmm15,%xmm15
147         paddd %xmm12, %xmm8
148         paddd %xmm13, %xmm9
149         paddd %xmm14, %xmm10
150         paddd %xmm15, %xmm11
151         movdqa %xmm12, 112(%rsp)
152         pxor %xmm8, %xmm4
153         pxor %xmm9, %xmm5
154         movdqa 96(%rsp), %xmm6
155         movdqa %xmm4, %xmm12
156         pslld $ 12, %xmm4
157         psrld $20, %xmm12
158         pxor %xmm12, %xmm4
159         movdqa %xmm5, %xmm12
160         pslld $ 12, %xmm5
161         psrld $20, %xmm12
162         pxor %xmm12, %xmm5
163         pxor %xmm10, %xmm6
164         pxor %xmm11, %xmm7
165         movdqa %xmm6, %xmm12
166         pslld $ 12, %xmm6
167         psrld $20, %xmm12
168         pxor %xmm12, %xmm6
169         movdqa %xmm7, %xmm12
170         pslld $ 12, %xmm7
171         psrld $20, %xmm12
172         pxor %xmm12, %xmm7
173         movdqa 112(%rsp), %xmm12
174         paddd %xmm4, %xmm0
175         paddd %xmm5, %xmm1
176         pxor %xmm0, %xmm12
177         pxor %xmm1, %xmm13
178         paddd %xmm6, %xmm2
179         paddd %xmm7, %xmm3
180         movdqa %xmm6, 96(%rsp)
181         pxor %xmm2, %xmm14
182         pxor %xmm3, %xmm15
183         movdqa %xmm12, %xmm6
184         pslld $ 8, %xmm12
185         psrld $24, %xmm6
186         pxor %xmm6, %xmm12
187         movdqa %xmm13, %xmm6
188         pslld $ 8, %xmm13
189         psrld $24, %xmm6
190         pxor %xmm6, %xmm13
191         paddd %xmm12, %xmm8
192         paddd %xmm13, %xmm9
193         movdqa %xmm14, %xmm6
194         pslld $ 8, %xmm14
195         psrld $24, %xmm6
196         pxor %xmm6, %xmm14
197         movdqa %xmm15, %xmm6
198         pslld $ 8, %xmm15
199         psrld $24, %xmm6
200         pxor %xmm6, %xmm15
201         paddd %xmm14, %xmm10
202         paddd %xmm15, %xmm11
203         movdqa %xmm12, 112(%rsp)
204         pxor %xmm8, %xmm4
205         pxor %xmm9, %xmm5
206         movdqa 96(%rsp), %xmm6
207         movdqa %xmm4, %xmm12
208         pslld $ 7, %xmm4
209         psrld $25, %xmm12
210         pxor %xmm12, %xmm4
211         movdqa %xmm5, %xmm12
212         pslld $ 7, %xmm5
213         psrld $25, %xmm12
214         pxor %xmm12, %xmm5
215         pxor %xmm10, %xmm6
216         pxor %xmm11, %xmm7
217         movdqa %xmm6, %xmm12
218         pslld $ 7, %xmm6
219         psrld $25, %xmm12
220         pxor %xmm12, %xmm6
221         movdqa %xmm7, %xmm12
222         pslld $ 7, %xmm7
223         psrld $25, %xmm12
224         pxor %xmm12, %xmm7
225         movdqa 112(%rsp), %xmm12
226         paddd %xmm5, %xmm0
227         paddd %xmm6, %xmm1
228         pxor %xmm0, %xmm15
229         pxor %xmm1, %xmm12
230         paddd %xmm7, %xmm2
231         paddd %xmm4, %xmm3
232         movdqa %xmm7, 96(%rsp)
233         pxor %xmm2, %xmm13
234         pxor %xmm3, %xmm14
235         pshuflw $0xb1,%xmm15,%xmm15
236         pshufhw $0xb1,%xmm15,%xmm15
237         pshuflw $0xb1,%xmm12,%xmm12
238         pshufhw $0xb1,%xmm12,%xmm12
239         pshuflw $0xb1,%xmm13,%xmm13
240         pshufhw $0xb1,%xmm13,%xmm13
241         pshuflw $0xb1,%xmm14,%xmm14
242         pshufhw $0xb1,%xmm14,%xmm14
243         paddd %xmm15, %xmm10
244         paddd %xmm12, %xmm11
245         paddd %xmm13, %xmm8
246         paddd %xmm14, %xmm9
247         movdqa %xmm15, 112(%rsp)
248         pxor %xmm10, %xmm5
249         pxor %xmm11, %xmm6
250         movdqa 96(%rsp), %xmm7
251         movdqa %xmm5, %xmm15
252         pslld $ 12, %xmm5
253         psrld $20, %xmm15
254         pxor %xmm15, %xmm5
255         movdqa %xmm6, %xmm15
256         pslld $ 12, %xmm6
257         psrld $20, %xmm15
258         pxor %xmm15, %xmm6
259         pxor %xmm8, %xmm7
260         pxor %xmm9, %xmm4
261         movdqa %xmm7, %xmm15
262         pslld $ 12, %xmm7
263         psrld $20, %xmm15
264         pxor %xmm15, %xmm7
265         movdqa %xmm4, %xmm15
266         pslld $ 12, %xmm4
267         psrld $20, %xmm15
268         pxor %xmm15, %xmm4
269         movdqa 112(%rsp), %xmm15
270         paddd %xmm5, %xmm0
271         paddd %xmm6, %xmm1
272         pxor %xmm0, %xmm15
273         pxor %xmm1, %xmm12
274         paddd %xmm7, %xmm2
275         paddd %xmm4, %xmm3
276         movdqa %xmm7, 96(%rsp)
277         pxor %xmm2, %xmm13
278         pxor %xmm3, %xmm14
279         movdqa %xmm15, %xmm7
280         pslld $ 8, %xmm15
281         psrld $24, %xmm7
282         pxor %xmm7, %xmm15
283         movdqa %xmm12, %xmm7
284         pslld $ 8, %xmm12
285         psrld $24, %xmm7
286         pxor %xmm7, %xmm12
287         paddd %xmm15, %xmm10
288         paddd %xmm12, %xmm11
289         movdqa %xmm13, %xmm7
290         pslld $ 8, %xmm13
291         psrld $24, %xmm7
292         pxor %xmm7, %xmm13
293         movdqa %xmm14, %xmm7
294         pslld $ 8, %xmm14
295         psrld $24, %xmm7
296         pxor %xmm7, %xmm14
297         paddd %xmm13, %xmm8
298         paddd %xmm14, %xmm9
299         movdqa %xmm15, 112(%rsp)
300         pxor %xmm10, %xmm5
301         pxor %xmm11, %xmm6
302         movdqa 96(%rsp), %xmm7
303         movdqa %xmm5, %xmm15
304         pslld $ 7, %xmm5
305         psrld $25, %xmm15
306         pxor %xmm15, %xmm5
307         movdqa %xmm6, %xmm15
308         pslld $ 7, %xmm6
309         psrld $25, %xmm15
310         pxor %xmm15, %xmm6
311         pxor %xmm8, %xmm7
312         pxor %xmm9, %xmm4
313         movdqa %xmm7, %xmm15
314         pslld $ 7, %xmm7
315         psrld $25, %xmm15
316         pxor %xmm15, %xmm7
317         movdqa %xmm4, %xmm15
318         pslld $ 7, %xmm4
319         psrld $25, %xmm15
320         pxor %xmm15, %xmm4
321         movdqa 112(%rsp), %xmm15
322         subq $2, %rax
323         jnz .Lchacha_blocks_sse2_mainloop1
324         paddd 128(%rsp), %xmm0
325         paddd 144(%rsp), %xmm1
326         paddd 160(%rsp), %xmm2
327         paddd 176(%rsp), %xmm3
328         paddd 192(%rsp), %xmm4
329         paddd 208(%rsp), %xmm5
330         paddd 224(%rsp), %xmm6
331         paddd 240(%rsp), %xmm7
332         paddd 256(%rsp), %xmm8
333         paddd 272(%rsp), %xmm9
334         paddd 288(%rsp), %xmm10
335         paddd 304(%rsp), %xmm11
336         paddd 320(%rsp), %xmm12
337         paddd 336(%rsp), %xmm13
338         paddd 352(%rsp), %xmm14
339         paddd 368(%rsp), %xmm15
340         movdqa %xmm8, 384(%rsp)
341         movdqa %xmm9, 400(%rsp)
342         movdqa %xmm10, 416(%rsp)
343         movdqa %xmm11, 432(%rsp)
344         movdqa %xmm12, 448(%rsp)
345         movdqa %xmm13, 464(%rsp)
346         movdqa %xmm14, 480(%rsp)
347         movdqa %xmm15, 496(%rsp)
348         movdqa %xmm0, %xmm8
349         movdqa %xmm2, %xmm9
350         movdqa %xmm4, %xmm10
351         movdqa %xmm6, %xmm11
352         punpckhdq %xmm1, %xmm0
353         punpckhdq %xmm3, %xmm2
354         punpckhdq %xmm5, %xmm4
355         punpckhdq %xmm7, %xmm6
356         punpckldq %xmm1, %xmm8
357         punpckldq %xmm3, %xmm9
358         punpckldq %xmm5, %xmm10
359         punpckldq %xmm7, %xmm11
360         movdqa %xmm0, %xmm1
361         movdqa %xmm4, %xmm3
362         movdqa %xmm8, %xmm5
363         movdqa %xmm10, %xmm7
364         punpckhqdq %xmm2, %xmm0
365         punpckhqdq %xmm6, %xmm4
366         punpckhqdq %xmm9, %xmm8
367         punpckhqdq %xmm11, %xmm10
368         punpcklqdq %xmm2, %xmm1
369         punpcklqdq %xmm6, %xmm3
370         punpcklqdq %xmm9, %xmm5
371         punpcklqdq %xmm11, %xmm7
372         andq %rsi, %rsi
373         jz .Lchacha_blocks_sse2_noinput1
374         movdqu 0(%rsi), %xmm2
375         movdqu 16(%rsi), %xmm6
376         movdqu 64(%rsi), %xmm9
377         movdqu 80(%rsi), %xmm11
378         movdqu 128(%rsi), %xmm12
379         movdqu 144(%rsi), %xmm13
380         movdqu 192(%rsi), %xmm14
381         movdqu 208(%rsi), %xmm15
382         pxor %xmm2, %xmm5
383         pxor %xmm6, %xmm7
384         pxor %xmm9, %xmm8
385         pxor %xmm11, %xmm10
386         pxor %xmm12, %xmm1
387         pxor %xmm13, %xmm3
388         pxor %xmm14, %xmm0
389         pxor %xmm15, %xmm4
390         movdqu %xmm5, 0(%rdx)
391         movdqu %xmm7, 16(%rdx)
392         movdqu %xmm8, 64(%rdx)
393         movdqu %xmm10, 80(%rdx)
394         movdqu %xmm1, 128(%rdx)
395         movdqu %xmm3, 144(%rdx)
396         movdqu %xmm0, 192(%rdx)
397         movdqu %xmm4, 208(%rdx)
398         movdqa 384(%rsp), %xmm0
399         movdqa 400(%rsp), %xmm1
400         movdqa 416(%rsp), %xmm2
401         movdqa 432(%rsp), %xmm3
402         movdqa 448(%rsp), %xmm4
403         movdqa 464(%rsp), %xmm5
404         movdqa 480(%rsp), %xmm6
405         movdqa 496(%rsp), %xmm7
406         movdqa %xmm0, %xmm8
407         movdqa %xmm2, %xmm9
408         movdqa %xmm4, %xmm10
409         movdqa %xmm6, %xmm11
410         punpckldq %xmm1, %xmm8
411         punpckldq %xmm3, %xmm9
412         punpckhdq %xmm1, %xmm0
413         punpckhdq %xmm3, %xmm2
414         punpckldq %xmm5, %xmm10
415         punpckldq %xmm7, %xmm11
416         punpckhdq %xmm5, %xmm4
417         punpckhdq %xmm7, %xmm6
418         movdqa %xmm8, %xmm1
419         movdqa %xmm0, %xmm3
420         movdqa %xmm10, %xmm5
421         movdqa %xmm4, %xmm7
422         punpcklqdq %xmm9, %xmm1
423         punpcklqdq %xmm11, %xmm5
424         punpckhqdq %xmm9, %xmm8
425         punpckhqdq %xmm11, %xmm10
426         punpcklqdq %xmm2, %xmm3
427         punpcklqdq %xmm6, %xmm7
428         punpckhqdq %xmm2, %xmm0
429         punpckhqdq %xmm6, %xmm4
430         movdqu 32(%rsi), %xmm2
431         movdqu 48(%rsi), %xmm6
432         movdqu 96(%rsi), %xmm9
433         movdqu 112(%rsi), %xmm11
434         movdqu 160(%rsi), %xmm12
435         movdqu 176(%rsi), %xmm13
436         movdqu 224(%rsi), %xmm14
437         movdqu 240(%rsi), %xmm15
438         pxor %xmm2, %xmm1
439         pxor %xmm6, %xmm5
440         pxor %xmm9, %xmm8
441         pxor %xmm11, %xmm10
442         pxor %xmm12, %xmm3
443         pxor %xmm13, %xmm7
444         pxor %xmm14, %xmm0
445         pxor %xmm15, %xmm4
446         movdqu %xmm1, 32(%rdx)
447         movdqu %xmm5, 48(%rdx)
448         movdqu %xmm8, 96(%rdx)
449         movdqu %xmm10, 112(%rdx)
450         movdqu %xmm3, 160(%rdx)
451         movdqu %xmm7, 176(%rdx)
452         movdqu %xmm0, 224(%rdx)
453         movdqu %xmm4, 240(%rdx)
454         addq $256, %rsi
455         jmp .Lchacha_blocks_sse2_mainloop_cont
456 .Lchacha_blocks_sse2_noinput1:
457         movdqu %xmm5, 0(%rdx)
458         movdqu %xmm7, 16(%rdx)
459         movdqu %xmm8, 64(%rdx)
460         movdqu %xmm10, 80(%rdx)
461         movdqu %xmm1, 128(%rdx)
462         movdqu %xmm3, 144(%rdx)
463         movdqu %xmm0, 192(%rdx)
464         movdqu %xmm4, 208(%rdx)
465         movdqa 384(%rsp), %xmm0
466         movdqa 400(%rsp), %xmm1
467         movdqa 416(%rsp), %xmm2
468         movdqa 432(%rsp), %xmm3
469         movdqa 448(%rsp), %xmm4
470         movdqa 464(%rsp), %xmm5
471         movdqa 480(%rsp), %xmm6
472         movdqa 496(%rsp), %xmm7
473         movdqa %xmm0, %xmm8
474         movdqa %xmm2, %xmm9
475         movdqa %xmm4, %xmm10
476         movdqa %xmm6, %xmm11
477         punpckldq %xmm1, %xmm8
478         punpckldq %xmm3, %xmm9
479         punpckhdq %xmm1, %xmm0
480         punpckhdq %xmm3, %xmm2
481         punpckldq %xmm5, %xmm10
482         punpckldq %xmm7, %xmm11
483         punpckhdq %xmm5, %xmm4
484         punpckhdq %xmm7, %xmm6
485         movdqa %xmm8, %xmm1
486         movdqa %xmm0, %xmm3
487         movdqa %xmm10, %xmm5
488         movdqa %xmm4, %xmm7
489         punpcklqdq %xmm9, %xmm1
490         punpcklqdq %xmm11, %xmm5
491         punpckhqdq %xmm9, %xmm8
492         punpckhqdq %xmm11, %xmm10
493         punpcklqdq %xmm2, %xmm3
494         punpcklqdq %xmm6, %xmm7
495         punpckhqdq %xmm2, %xmm0
496         punpckhqdq %xmm6, %xmm4
497         movdqu %xmm1, 32(%rdx)
498         movdqu %xmm5, 48(%rdx)
499         movdqu %xmm8, 96(%rdx)
500         movdqu %xmm10, 112(%rdx)
501         movdqu %xmm3, 160(%rdx)
502         movdqu %xmm7, 176(%rdx)
503         movdqu %xmm0, 224(%rdx)
504         movdqu %xmm4, 240(%rdx)
505 .Lchacha_blocks_sse2_mainloop_cont:
506         addq $256, %rdx
507         subq $256, %rcx
508         cmp $256, %rcx
509         jae .Lchacha_blocks_sse2_atleast256
510         movdqa 0(%rsp), %xmm8
511         movdqa 16(%rsp), %xmm9
512         movdqa 32(%rsp), %xmm10
513         movdqa 48(%rsp), %xmm11
514         movq $1, %r9
515 .Lchacha_blocks_sse2_below256:
516         movq %r9, %xmm5
517         andq %rcx, %rcx
518         jz .Lchacha_blocks_sse2_done
519         cmpq $64, %rcx
520         jae .Lchacha_blocks_sse2_above63
521         movq %rdx, %r9
522         andq %rsi, %rsi
523         jz .Lchacha_blocks_sse2_noinput2
524         movq %rcx, %r10
525         movq %rsp, %rdx
526         addq %r10, %rsi
527         addq %r10, %rdx
528         negq %r10
529 .Lchacha_blocks_sse2_copyinput:
530         movb (%rsi, %r10), %al
531         movb %al, (%rdx, %r10)
532         incq %r10
533         jnz .Lchacha_blocks_sse2_copyinput
534         movq %rsp, %rsi
535 .Lchacha_blocks_sse2_noinput2:
536         movq %rsp, %rdx
537 .Lchacha_blocks_sse2_above63:
538         movdqa %xmm8, %xmm0
539         movdqa %xmm9, %xmm1
540         movdqa %xmm10, %xmm2
541         movdqa %xmm11, %xmm3
542         movq 64(%rsp), %rax
543 .Lchacha_blocks_sse2_mainloop2:
544         paddd %xmm1, %xmm0
545         pxor %xmm0, %xmm3
546         pshuflw $0xb1,%xmm3,%xmm3
547         pshufhw $0xb1,%xmm3,%xmm3
548         paddd %xmm3, %xmm2
549         pxor %xmm2, %xmm1
550         movdqa %xmm1,%xmm4
551         pslld $12, %xmm1
552         psrld $20, %xmm4
553         pxor %xmm4, %xmm1
554         paddd %xmm1, %xmm0
555         pxor %xmm0, %xmm3
556         movdqa %xmm3,%xmm4
557         pslld $8, %xmm3
558         psrld $24, %xmm4
559         pshufd $0x93,%xmm0,%xmm0
560         pxor %xmm4, %xmm3
561         paddd %xmm3, %xmm2
562         pshufd $0x4e,%xmm3,%xmm3
563         pxor %xmm2, %xmm1
564         pshufd $0x39,%xmm2,%xmm2
565         movdqa %xmm1,%xmm4
566         pslld $7, %xmm1
567         psrld $25, %xmm4
568         pxor %xmm4, %xmm1
569         subq $2, %rax
570         paddd %xmm1, %xmm0
571         pxor %xmm0, %xmm3
572         pshuflw $0xb1,%xmm3,%xmm3
573         pshufhw $0xb1,%xmm3,%xmm3
574         paddd %xmm3, %xmm2
575         pxor %xmm2, %xmm1
576         movdqa %xmm1,%xmm4
577         pslld $12, %xmm1
578         psrld $20, %xmm4
579         pxor %xmm4, %xmm1
580         paddd %xmm1, %xmm0
581         pxor %xmm0, %xmm3
582         movdqa %xmm3,%xmm4
583         pslld $8, %xmm3
584         psrld $24, %xmm4
585         pshufd $0x39,%xmm0,%xmm0
586         pxor %xmm4, %xmm3
587         paddd %xmm3, %xmm2
588         pshufd $0x4e,%xmm3,%xmm3
589         pxor %xmm2, %xmm1
590         pshufd $0x93,%xmm2,%xmm2
591         movdqa %xmm1,%xmm4
592         pslld $7, %xmm1
593         psrld $25, %xmm4
594         pxor %xmm4, %xmm1
595         jnz .Lchacha_blocks_sse2_mainloop2
596         paddd %xmm8, %xmm0
597         paddd %xmm9, %xmm1
598         paddd %xmm10, %xmm2
599         paddd %xmm11, %xmm3
600         andq %rsi, %rsi
601         jz .Lchacha_blocks_sse2_noinput3
602         movdqu 0(%rsi), %xmm12
603         movdqu 16(%rsi), %xmm13
604         movdqu 32(%rsi), %xmm14
605         movdqu 48(%rsi), %xmm15
606         pxor %xmm12, %xmm0
607         pxor %xmm13, %xmm1
608         pxor %xmm14, %xmm2
609         pxor %xmm15, %xmm3
610         addq $64, %rsi
611 .Lchacha_blocks_sse2_noinput3:
612         movdqu %xmm0, 0(%rdx)
613         movdqu %xmm1, 16(%rdx)
614         movdqu %xmm2, 32(%rdx)
615         movdqu %xmm3, 48(%rdx)
616         paddq %xmm5, %xmm11
617         cmpq $64, %rcx
618         jbe .Lchacha_blocks_sse2_mainloop2_finishup
619         addq $64, %rdx
620         subq $64, %rcx
621         jmp .Lchacha_blocks_sse2_below256
622 .Lchacha_blocks_sse2_mainloop2_finishup:
623         cmpq $64, %rcx
624         je .Lchacha_blocks_sse2_done
625         addq %rcx, %r9
626         addq %rcx, %rdx
627         negq %rcx
628 .Lchacha_blocks_sse2_copyoutput:
629         movb (%rdx, %rcx), %al
630         movb %al, (%r9, %rcx)
631         incq %rcx
632         jnz .Lchacha_blocks_sse2_copyoutput
633 .Lchacha_blocks_sse2_done:
634         movdqu %xmm11, 48(%rdi)
635         movq %rbp, %rsp
636         pxor %xmm15, %xmm15
637         pxor %xmm7, %xmm7
638         pxor %xmm14, %xmm14
639         pxor %xmm6, %xmm6
640         pxor %xmm13, %xmm13
641         pxor %xmm5, %xmm5
642         pxor %xmm12, %xmm12
643         pxor %xmm4, %xmm4
644         popq %rbp
645         popq %rbx
646         movl $(63 + 512 + 16), %eax
647         pxor %xmm11, %xmm11
648         pxor %xmm3, %xmm3
649         pxor %xmm10, %xmm10
650         pxor %xmm2, %xmm2
651         pxor %xmm9, %xmm9
652         pxor %xmm1, %xmm1
653         pxor %xmm8, %xmm8
654         pxor %xmm0, %xmm0
655         ret
656 ELF(.size _gcry_chacha20_amd64_sse2_blocks,.-_gcry_chacha20_amd64_sse2_blocks;)
657
658 #endif /*defined(USE_CHACHA20)*/
659 #endif /*__x86_64*/