1#include "../macro.S"
2#include "constants.S"
3SECTION_TEXT
4
5GLOBAL_HIDDEN_FN chacha_blocks_sse2
6chacha_blocks_sse2_local:
7pushq %rbx
8pushq %rbp
9movq %rsp, %rbp
10andq $~63, %rsp
11subq $512, %rsp
12movq $0x3320646e61707865, %rax
13movq $0x6b20657479622d32, %r8
14movd %rax, %xmm8
15movd %r8, %xmm14
16punpcklqdq %xmm14, %xmm8
17movdqu 0(%rdi), %xmm9
18movdqu 16(%rdi), %xmm10
19movdqu 32(%rdi), %xmm11
20movq 48(%rdi), %rax
21movq $1, %r9
22movdqa %xmm8, 0(%rsp)
23movdqa %xmm9, 16(%rsp)
24movdqa %xmm10, 32(%rsp)
25movdqa %xmm11, 48(%rsp)
26movq %rax, 64(%rsp)
27cmpq $256, %rcx
28jb chacha_blocks_sse2_below256
29pshufd $0x00, %xmm8, %xmm0
30pshufd $0x55, %xmm8, %xmm1
31pshufd $0xaa, %xmm8, %xmm2
32pshufd $0xff, %xmm8, %xmm3
33movdqa %xmm0, 128(%rsp)
34movdqa %xmm1, 144(%rsp)
35movdqa %xmm2, 160(%rsp)
36movdqa %xmm3, 176(%rsp)
37pshufd $0x00, %xmm9, %xmm0
38pshufd $0x55, %xmm9, %xmm1
39pshufd $0xaa, %xmm9, %xmm2
40pshufd $0xff, %xmm9, %xmm3
41movdqa %xmm0, 192(%rsp)
42movdqa %xmm1, 208(%rsp)
43movdqa %xmm2, 224(%rsp)
44movdqa %xmm3, 240(%rsp)
45pshufd $0x00, %xmm10, %xmm0
46pshufd $0x55, %xmm10, %xmm1
47pshufd $0xaa, %xmm10, %xmm2
48pshufd $0xff, %xmm10, %xmm3
49movdqa %xmm0, 256(%rsp)
50movdqa %xmm1, 272(%rsp)
51movdqa %xmm2, 288(%rsp)
52movdqa %xmm3, 304(%rsp)
53pshufd $0xaa, %xmm11, %xmm0
54pshufd $0xff, %xmm11, %xmm1
55movdqa %xmm0, 352(%rsp)
56movdqa %xmm1, 368(%rsp)
57jmp chacha_blocks_sse2_atleast256
58.p2align 6,,63
59chacha_blocks_sse2_atleast256:
60movq 48(%rsp), %rax
61leaq 1(%rax), %r8
62leaq 2(%rax), %r9
63leaq 3(%rax), %r10
64leaq 4(%rax), %rbx
65movl %eax, 320(%rsp)
66movl %r8d, 4+320(%rsp)
67movl %r9d, 8+320(%rsp)
68movl %r10d, 12+320(%rsp)
69shrq $32, %rax
70shrq $32, %r8
71shrq $32, %r9
72shrq $32, %r10
73movl %eax, 336(%rsp)
74movl %r8d, 4+336(%rsp)
75movl %r9d, 8+336(%rsp)
76movl %r10d, 12+336(%rsp)
77movq %rbx, 48(%rsp)
78movq 64(%rsp), %rax
79movdqa 128(%rsp), %xmm0
80movdqa 144(%rsp), %xmm1
81movdqa 160(%rsp), %xmm2
82movdqa 176(%rsp), %xmm3
83movdqa 192(%rsp), %xmm4
84movdqa 208(%rsp), %xmm5
85movdqa 224(%rsp), %xmm6
86movdqa 240(%rsp), %xmm7
87movdqa 256(%rsp), %xmm8
88movdqa 272(%rsp), %xmm9
89movdqa 288(%rsp), %xmm10
90movdqa 304(%rsp), %xmm11
91movdqa 320(%rsp), %xmm12
92movdqa 336(%rsp), %xmm13
93movdqa 352(%rsp), %xmm14
94movdqa 368(%rsp), %xmm15
95chacha_blocks_sse2_mainloop1:
96paddd %xmm4, %xmm0
97paddd %xmm5, %xmm1
98pxor %xmm0, %xmm12
99pxor %xmm1, %xmm13
100paddd %xmm6, %xmm2
101paddd %xmm7, %xmm3
102movdqa %xmm6, 96(%rsp)
103pxor %xmm2, %xmm14
104pxor %xmm3, %xmm15
105pshuflw $0xb1,%xmm12,%xmm12
106pshufhw $0xb1,%xmm12,%xmm12
107pshuflw $0xb1,%xmm13,%xmm13
108pshufhw $0xb1,%xmm13,%xmm13
109pshuflw $0xb1,%xmm14,%xmm14
110pshufhw $0xb1,%xmm14,%xmm14
111pshuflw $0xb1,%xmm15,%xmm15
112pshufhw $0xb1,%xmm15,%xmm15
113paddd %xmm12, %xmm8
114paddd %xmm13, %xmm9
115paddd %xmm14, %xmm10
116paddd %xmm15, %xmm11
117movdqa %xmm12, 112(%rsp)
118pxor %xmm8, %xmm4
119pxor %xmm9, %xmm5
120movdqa 96(%rsp), %xmm6
121movdqa %xmm4, %xmm12
122pslld $ 12, %xmm4
123psrld $20, %xmm12
124pxor %xmm12, %xmm4
125movdqa %xmm5, %xmm12
126pslld $ 12, %xmm5
127psrld $20, %xmm12
128pxor %xmm12, %xmm5
129pxor %xmm10, %xmm6
130pxor %xmm11, %xmm7
131movdqa %xmm6, %xmm12
132pslld $ 12, %xmm6
133psrld $20, %xmm12
134pxor %xmm12, %xmm6
135movdqa %xmm7, %xmm12
136pslld $ 12, %xmm7
137psrld $20, %xmm12
138pxor %xmm12, %xmm7
139movdqa 112(%rsp), %xmm12
140paddd %xmm4, %xmm0
141paddd %xmm5, %xmm1
142pxor %xmm0, %xmm12
143pxor %xmm1, %xmm13
144paddd %xmm6, %xmm2
145paddd %xmm7, %xmm3
146movdqa %xmm6, 96(%rsp)
147pxor %xmm2, %xmm14
148pxor %xmm3, %xmm15
149movdqa %xmm12, %xmm6
150pslld $ 8, %xmm12
151psrld $24, %xmm6
152pxor %xmm6, %xmm12
153movdqa %xmm13, %xmm6
154pslld $ 8, %xmm13
155psrld $24, %xmm6
156pxor %xmm6, %xmm13
157paddd %xmm12, %xmm8
158paddd %xmm13, %xmm9
159movdqa %xmm14, %xmm6
160pslld $ 8, %xmm14
161psrld $24, %xmm6
162pxor %xmm6, %xmm14
163movdqa %xmm15, %xmm6
164pslld $ 8, %xmm15
165psrld $24, %xmm6
166pxor %xmm6, %xmm15
167paddd %xmm14, %xmm10
168paddd %xmm15, %xmm11
169movdqa %xmm12, 112(%rsp)
170pxor %xmm8, %xmm4
171pxor %xmm9, %xmm5
172movdqa 96(%rsp), %xmm6
173movdqa %xmm4, %xmm12
174pslld $ 7, %xmm4
175psrld $25, %xmm12
176pxor %xmm12, %xmm4
177movdqa %xmm5, %xmm12
178pslld $ 7, %xmm5
179psrld $25, %xmm12
180pxor %xmm12, %xmm5
181pxor %xmm10, %xmm6
182pxor %xmm11, %xmm7
183movdqa %xmm6, %xmm12
184pslld $ 7, %xmm6
185psrld $25, %xmm12
186pxor %xmm12, %xmm6
187movdqa %xmm7, %xmm12
188pslld $ 7, %xmm7
189psrld $25, %xmm12
190pxor %xmm12, %xmm7
191movdqa 112(%rsp), %xmm12
192paddd %xmm5, %xmm0
193paddd %xmm6, %xmm1
194pxor %xmm0, %xmm15
195pxor %xmm1, %xmm12
196paddd %xmm7, %xmm2
197paddd %xmm4, %xmm3
198movdqa %xmm7, 96(%rsp)
199pxor %xmm2, %xmm13
200pxor %xmm3, %xmm14
201pshuflw $0xb1,%xmm15,%xmm15
202pshufhw $0xb1,%xmm15,%xmm15
203pshuflw $0xb1,%xmm12,%xmm12
204pshufhw $0xb1,%xmm12,%xmm12
205pshuflw $0xb1,%xmm13,%xmm13
206pshufhw $0xb1,%xmm13,%xmm13
207pshuflw $0xb1,%xmm14,%xmm14
208pshufhw $0xb1,%xmm14,%xmm14
209paddd %xmm15, %xmm10
210paddd %xmm12, %xmm11
211paddd %xmm13, %xmm8
212paddd %xmm14, %xmm9
213movdqa %xmm15, 112(%rsp)
214pxor %xmm10, %xmm5
215pxor %xmm11, %xmm6
216movdqa 96(%rsp), %xmm7
217movdqa %xmm5, %xmm15
218pslld $ 12, %xmm5
219psrld $20, %xmm15
220pxor %xmm15, %xmm5
221movdqa %xmm6, %xmm15
222pslld $ 12, %xmm6
223psrld $20, %xmm15
224pxor %xmm15, %xmm6
225pxor %xmm8, %xmm7
226pxor %xmm9, %xmm4
227movdqa %xmm7, %xmm15
228pslld $ 12, %xmm7
229psrld $20, %xmm15
230pxor %xmm15, %xmm7
231movdqa %xmm4, %xmm15
232pslld $ 12, %xmm4
233psrld $20, %xmm15
234pxor %xmm15, %xmm4
235movdqa 112(%rsp), %xmm15
236paddd %xmm5, %xmm0
237paddd %xmm6, %xmm1
238pxor %xmm0, %xmm15
239pxor %xmm1, %xmm12
240paddd %xmm7, %xmm2
241paddd %xmm4, %xmm3
242movdqa %xmm7, 96(%rsp)
243pxor %xmm2, %xmm13
244pxor %xmm3, %xmm14
245movdqa %xmm15, %xmm7
246pslld $ 8, %xmm15
247psrld $24, %xmm7
248pxor %xmm7, %xmm15
249movdqa %xmm12, %xmm7
250pslld $ 8, %xmm12
251psrld $24, %xmm7
252pxor %xmm7, %xmm12
253paddd %xmm15, %xmm10
254paddd %xmm12, %xmm11
255movdqa %xmm13, %xmm7
256pslld $ 8, %xmm13
257psrld $24, %xmm7
258pxor %xmm7, %xmm13
259movdqa %xmm14, %xmm7
260pslld $ 8, %xmm14
261psrld $24, %xmm7
262pxor %xmm7, %xmm14
263paddd %xmm13, %xmm8
264paddd %xmm14, %xmm9
265movdqa %xmm15, 112(%rsp)
266pxor %xmm10, %xmm5
267pxor %xmm11, %xmm6
268movdqa 96(%rsp), %xmm7
269movdqa %xmm5, %xmm15
270pslld $ 7, %xmm5
271psrld $25, %xmm15
272pxor %xmm15, %xmm5
273movdqa %xmm6, %xmm15
274pslld $ 7, %xmm6
275psrld $25, %xmm15
276pxor %xmm15, %xmm6
277pxor %xmm8, %xmm7
278pxor %xmm9, %xmm4
279movdqa %xmm7, %xmm15
280pslld $ 7, %xmm7
281psrld $25, %xmm15
282pxor %xmm15, %xmm7
283movdqa %xmm4, %xmm15
284pslld $ 7, %xmm4
285psrld $25, %xmm15
286pxor %xmm15, %xmm4
287movdqa 112(%rsp), %xmm15
288subq $2, %rax
289jnz chacha_blocks_sse2_mainloop1
290paddd 128(%rsp), %xmm0
291paddd 144(%rsp), %xmm1
292paddd 160(%rsp), %xmm2
293paddd 176(%rsp), %xmm3
294paddd 192(%rsp), %xmm4
295paddd 208(%rsp), %xmm5
296paddd 224(%rsp), %xmm6
297paddd 240(%rsp), %xmm7
298paddd 256(%rsp), %xmm8
299paddd 272(%rsp), %xmm9
300paddd 288(%rsp), %xmm10
301paddd 304(%rsp), %xmm11
302paddd 320(%rsp), %xmm12
303paddd 336(%rsp), %xmm13
304paddd 352(%rsp), %xmm14
305paddd 368(%rsp), %xmm15
306movdqa %xmm8, 384(%rsp)
307movdqa %xmm9, 400(%rsp)
308movdqa %xmm10, 416(%rsp)
309movdqa %xmm11, 432(%rsp)
310movdqa %xmm12, 448(%rsp)
311movdqa %xmm13, 464(%rsp)
312movdqa %xmm14, 480(%rsp)
313movdqa %xmm15, 496(%rsp)
314movdqa %xmm0, %xmm8
315movdqa %xmm2, %xmm9
316movdqa %xmm4, %xmm10
317movdqa %xmm6, %xmm11
318punpckhdq %xmm1, %xmm0
319punpckhdq %xmm3, %xmm2
320punpckhdq %xmm5, %xmm4
321punpckhdq %xmm7, %xmm6
322punpckldq %xmm1, %xmm8
323punpckldq %xmm3, %xmm9
324punpckldq %xmm5, %xmm10
325punpckldq %xmm7, %xmm11
326movdqa %xmm0, %xmm1
327movdqa %xmm4, %xmm3
328movdqa %xmm8, %xmm5
329movdqa %xmm10, %xmm7
330punpckhqdq %xmm2, %xmm0
331punpckhqdq %xmm6, %xmm4
332punpckhqdq %xmm9, %xmm8
333punpckhqdq %xmm11, %xmm10
334punpcklqdq %xmm2, %xmm1
335punpcklqdq %xmm6, %xmm3
336punpcklqdq %xmm9, %xmm5
337punpcklqdq %xmm11, %xmm7
338andq %rsi, %rsi
339jz chacha_blocks_sse2_noinput1
340movdqu 0(%rsi), %xmm2
341movdqu 16(%rsi), %xmm6
342movdqu 64(%rsi), %xmm9
343movdqu 80(%rsi), %xmm11
344movdqu 128(%rsi), %xmm12
345movdqu 144(%rsi), %xmm13
346movdqu 192(%rsi), %xmm14
347movdqu 208(%rsi), %xmm15
348pxor %xmm2, %xmm5
349pxor %xmm6, %xmm7
350pxor %xmm9, %xmm8
351pxor %xmm11, %xmm10
352pxor %xmm12, %xmm1
353pxor %xmm13, %xmm3
354pxor %xmm14, %xmm0
355pxor %xmm15, %xmm4
356movdqu %xmm5, 0(%rdx)
357movdqu %xmm7, 16(%rdx)
358movdqu %xmm8, 64(%rdx)
359movdqu %xmm10, 80(%rdx)
360movdqu %xmm1, 128(%rdx)
361movdqu %xmm3, 144(%rdx)
362movdqu %xmm0, 192(%rdx)
363movdqu %xmm4, 208(%rdx)
364movdqa 384(%rsp), %xmm0
365movdqa 400(%rsp), %xmm1
366movdqa 416(%rsp), %xmm2
367movdqa 432(%rsp), %xmm3
368movdqa 448(%rsp), %xmm4
369movdqa 464(%rsp), %xmm5
370movdqa 480(%rsp), %xmm6
371movdqa 496(%rsp), %xmm7
372movdqa %xmm0, %xmm8
373movdqa %xmm2, %xmm9
374movdqa %xmm4, %xmm10
375movdqa %xmm6, %xmm11
376punpckldq %xmm1, %xmm8
377punpckldq %xmm3, %xmm9
378punpckhdq %xmm1, %xmm0
379punpckhdq %xmm3, %xmm2
380punpckldq %xmm5, %xmm10
381punpckldq %xmm7, %xmm11
382punpckhdq %xmm5, %xmm4
383punpckhdq %xmm7, %xmm6
384movdqa %xmm8, %xmm1
385movdqa %xmm0, %xmm3
386movdqa %xmm10, %xmm5
387movdqa %xmm4, %xmm7
388punpcklqdq %xmm9, %xmm1
389punpcklqdq %xmm11, %xmm5
390punpckhqdq %xmm9, %xmm8
391punpckhqdq %xmm11, %xmm10
392punpcklqdq %xmm2, %xmm3
393punpcklqdq %xmm6, %xmm7
394punpckhqdq %xmm2, %xmm0
395punpckhqdq %xmm6, %xmm4
396movdqu 32(%rsi), %xmm2
397movdqu 48(%rsi), %xmm6
398movdqu 96(%rsi), %xmm9
399movdqu 112(%rsi), %xmm11
400movdqu 160(%rsi), %xmm12
401movdqu 176(%rsi), %xmm13
402movdqu 224(%rsi), %xmm14
403movdqu 240(%rsi), %xmm15
404pxor %xmm2, %xmm1
405pxor %xmm6, %xmm5
406pxor %xmm9, %xmm8
407pxor %xmm11, %xmm10
408pxor %xmm12, %xmm3
409pxor %xmm13, %xmm7
410pxor %xmm14, %xmm0
411pxor %xmm15, %xmm4
412movdqu %xmm1, 32(%rdx)
413movdqu %xmm5, 48(%rdx)
414movdqu %xmm8, 96(%rdx)
415movdqu %xmm10, 112(%rdx)
416movdqu %xmm3, 160(%rdx)
417movdqu %xmm7, 176(%rdx)
418movdqu %xmm0, 224(%rdx)
419movdqu %xmm4, 240(%rdx)
420addq $256, %rsi
421jmp chacha_blocks_sse2_mainloop_cont
422chacha_blocks_sse2_noinput1:
423movdqu %xmm5, 0(%rdx)
424movdqu %xmm7, 16(%rdx)
425movdqu %xmm8, 64(%rdx)
426movdqu %xmm10, 80(%rdx)
427movdqu %xmm1, 128(%rdx)
428movdqu %xmm3, 144(%rdx)
429movdqu %xmm0, 192(%rdx)
430movdqu %xmm4, 208(%rdx)
431movdqa 384(%rsp), %xmm0
432movdqa 400(%rsp), %xmm1
433movdqa 416(%rsp), %xmm2
434movdqa 432(%rsp), %xmm3
435movdqa 448(%rsp), %xmm4
436movdqa 464(%rsp), %xmm5
437movdqa 480(%rsp), %xmm6
438movdqa 496(%rsp), %xmm7
439movdqa %xmm0, %xmm8
440movdqa %xmm2, %xmm9
441movdqa %xmm4, %xmm10
442movdqa %xmm6, %xmm11
443punpckldq %xmm1, %xmm8
444punpckldq %xmm3, %xmm9
445punpckhdq %xmm1, %xmm0
446punpckhdq %xmm3, %xmm2
447punpckldq %xmm5, %xmm10
448punpckldq %xmm7, %xmm11
449punpckhdq %xmm5, %xmm4
450punpckhdq %xmm7, %xmm6
451movdqa %xmm8, %xmm1
452movdqa %xmm0, %xmm3
453movdqa %xmm10, %xmm5
454movdqa %xmm4, %xmm7
455punpcklqdq %xmm9, %xmm1
456punpcklqdq %xmm11, %xmm5
457punpckhqdq %xmm9, %xmm8
458punpckhqdq %xmm11, %xmm10
459punpcklqdq %xmm2, %xmm3
460punpcklqdq %xmm6, %xmm7
461punpckhqdq %xmm2, %xmm0
462punpckhqdq %xmm6, %xmm4
463movdqu %xmm1, 32(%rdx)
464movdqu %xmm5, 48(%rdx)
465movdqu %xmm8, 96(%rdx)
466movdqu %xmm10, 112(%rdx)
467movdqu %xmm3, 160(%rdx)
468movdqu %xmm7, 176(%rdx)
469movdqu %xmm0, 224(%rdx)
470movdqu %xmm4, 240(%rdx)
471chacha_blocks_sse2_mainloop_cont:
472addq $256, %rdx
473subq $256, %rcx
474cmp $256, %rcx
475jae chacha_blocks_sse2_atleast256
476movdqa 0(%rsp), %xmm8
477movdqa 16(%rsp), %xmm9
478movdqa 32(%rsp), %xmm10
479movdqa 48(%rsp), %xmm11
480movq $1, %r9
481chacha_blocks_sse2_below256:
482movq %r9, %xmm5
483andq %rcx, %rcx
484jz chacha_blocks_sse2_done
485cmpq $64, %rcx
486jae chacha_blocks_sse2_above63
487movq %rdx, %r9
488andq %rsi, %rsi
489jz chacha_blocks_sse2_noinput2
490movq %rcx, %r10
491movq %rsp, %rdx
492addq %r10, %rsi
493addq %r10, %rdx
494negq %r10
495chacha_blocks_sse2_copyinput:
496movb (%rsi, %r10), %al
497movb %al, (%rdx, %r10)
498incq %r10
499jnz chacha_blocks_sse2_copyinput
500movq %rsp, %rsi
501chacha_blocks_sse2_noinput2:
502movq %rsp, %rdx
503chacha_blocks_sse2_above63:
504movdqa %xmm8, %xmm0
505movdqa %xmm9, %xmm1
506movdqa %xmm10, %xmm2
507movdqa %xmm11, %xmm3
508movq 64(%rsp), %rax
509chacha_blocks_sse2_mainloop2:
510paddd %xmm1, %xmm0
511pxor %xmm0, %xmm3
512pshuflw $0xb1,%xmm3,%xmm3
513pshufhw $0xb1,%xmm3,%xmm3
514paddd %xmm3, %xmm2
515pxor %xmm2, %xmm1
516movdqa %xmm1,%xmm4
517pslld $12, %xmm1
518psrld $20, %xmm4
519pxor %xmm4, %xmm1
520paddd %xmm1, %xmm0
521pxor %xmm0, %xmm3
522movdqa %xmm3,%xmm4
523pslld $8, %xmm3
524psrld $24, %xmm4
525pshufd $0x93,%xmm0,%xmm0
526pxor %xmm4, %xmm3
527paddd %xmm3, %xmm2
528pshufd $0x4e,%xmm3,%xmm3
529pxor %xmm2, %xmm1
530pshufd $0x39,%xmm2,%xmm2
531movdqa %xmm1,%xmm4
532pslld $7, %xmm1
533psrld $25, %xmm4
534pxor %xmm4, %xmm1
535subq $2, %rax
536paddd %xmm1, %xmm0
537pxor %xmm0, %xmm3
538pshuflw $0xb1,%xmm3,%xmm3
539pshufhw $0xb1,%xmm3,%xmm3
540paddd %xmm3, %xmm2
541pxor %xmm2, %xmm1
542movdqa %xmm1,%xmm4
543pslld $12, %xmm1
544psrld $20, %xmm4
545pxor %xmm4, %xmm1
546paddd %xmm1, %xmm0
547pxor %xmm0, %xmm3
548movdqa %xmm3,%xmm4
549pslld $8, %xmm3
550psrld $24, %xmm4
551pshufd $0x39,%xmm0,%xmm0
552pxor %xmm4, %xmm3
553paddd %xmm3, %xmm2
554pshufd $0x4e,%xmm3,%xmm3
555pxor %xmm2, %xmm1
556pshufd $0x93,%xmm2,%xmm2
557movdqa %xmm1,%xmm4
558pslld $7, %xmm1
559psrld $25, %xmm4
560pxor %xmm4, %xmm1
561jnz chacha_blocks_sse2_mainloop2
562paddd %xmm8, %xmm0
563paddd %xmm9, %xmm1
564paddd %xmm10, %xmm2
565paddd %xmm11, %xmm3
566andq %rsi, %rsi
567jz chacha_blocks_sse2_noinput3
568movdqu 0(%rsi), %xmm12
569movdqu 16(%rsi), %xmm13
570movdqu 32(%rsi), %xmm14
571movdqu 48(%rsi), %xmm15
572pxor %xmm12, %xmm0
573pxor %xmm13, %xmm1
574pxor %xmm14, %xmm2
575pxor %xmm15, %xmm3
576addq $64, %rsi
577chacha_blocks_sse2_noinput3:
578movdqu %xmm0, 0(%rdx)
579movdqu %xmm1, 16(%rdx)
580movdqu %xmm2, 32(%rdx)
581movdqu %xmm3, 48(%rdx)
582paddq %xmm5, %xmm11
583cmpq $64, %rcx
584jbe chacha_blocks_sse2_mainloop2_finishup
585addq $64, %rdx
586subq $64, %rcx
587jmp chacha_blocks_sse2_below256
588chacha_blocks_sse2_mainloop2_finishup:
589cmpq $64, %rcx
590je chacha_blocks_sse2_done
591addq %rcx, %r9
592addq %rcx, %rdx
593negq %rcx
594chacha_blocks_sse2_copyoutput:
595movb (%rdx, %rcx), %al
596movb %al, (%r9, %rcx)
597incq %rcx
598jnz chacha_blocks_sse2_copyoutput
599chacha_blocks_sse2_done:
600movdqu %xmm11, 32(%rdi)
601movq %rbp, %rsp
602popq %rbp
603popq %rbx
604ret
605FN_END chacha_blocks_sse2
606
607GLOBAL_HIDDEN_FN hchacha_sse2
608hchacha_sse2_local:
609movq $0x3320646e61707865, %rax
610movq $0x6b20657479622d32, %r8
611movd %rax, %xmm0
612movd %r8, %xmm4
613punpcklqdq %xmm4, %xmm0
614movdqu 0(%rdi), %xmm1
615movdqu 16(%rdi), %xmm2
616movdqu 0(%rsi), %xmm3
617hchacha_sse2_mainloop:
618paddd %xmm1, %xmm0
619pxor %xmm0, %xmm3
620pshuflw $0xb1,%xmm3,%xmm3
621pshufhw $0xb1,%xmm3,%xmm3
622paddd %xmm3, %xmm2
623pxor %xmm2, %xmm1
624movdqa %xmm1,%xmm4
625pslld $12, %xmm1
626psrld $20, %xmm4
627pxor %xmm4, %xmm1
628paddd %xmm1, %xmm0
629pxor %xmm0, %xmm3
630movdqa %xmm3,%xmm4
631pslld $8, %xmm3
632psrld $24, %xmm4
633pshufd $0x93,%xmm0,%xmm0
634pxor %xmm4, %xmm3
635paddd %xmm3, %xmm2
636pshufd $0x4e,%xmm3,%xmm3
637pxor %xmm2, %xmm1
638pshufd $0x39,%xmm2,%xmm2
639movdqa %xmm1,%xmm4
640pslld $7, %xmm1
641psrld $25, %xmm4
642pxor %xmm4, %xmm1
643subq $2, %rcx
644paddd %xmm1, %xmm0
645pxor %xmm0, %xmm3
646pshuflw $0xb1,%xmm3,%xmm3
647pshufhw $0xb1,%xmm3,%xmm3
648paddd %xmm3, %xmm2
649pxor %xmm2, %xmm1
650movdqa %xmm1,%xmm4
651pslld $12, %xmm1
652psrld $20, %xmm4
653pxor %xmm4, %xmm1
654paddd %xmm1, %xmm0
655pxor %xmm0, %xmm3
656movdqa %xmm3,%xmm4
657pslld $8, %xmm3
658psrld $24, %xmm4
659pshufd $0x39,%xmm0,%xmm0
660pxor %xmm4, %xmm3
661paddd %xmm3, %xmm2
662pshufd $0x4e,%xmm3,%xmm3
663pxor %xmm2, %xmm1
664pshufd $0x93,%xmm2,%xmm2
665movdqa %xmm1,%xmm4
666pslld $7, %xmm1
667psrld $25, %xmm4
668pxor %xmm4, %xmm1
669ja hchacha_sse2_mainloop
670movdqu %xmm0, 0(%rdx)
671movdqu %xmm3, 16(%rdx)
672ret
673FN_END hchacha_sse2
674
675GLOBAL_HIDDEN_FN_EXT chacha_sse2, 6, 16
676pushq %rbp
677movq %rsp, %rbp
678subq $64, %rsp
679andq $~63, %rsp
680movdqu 0(%rdi), %xmm0
681movdqu 16(%rdi), %xmm1
682movdqa %xmm0, 0(%rsp)
683movdqa %xmm1, 16(%rsp)
684xorq %rdi, %rdi
685movq %rdi, 32(%rsp)
686movq 0(%rsi), %rsi
687movq %rsi, 40(%rsp)
688movq %r9, 48(%rsp)
689movq %rsp, %rdi
690movq %rdx, %rsi
691movq %rcx, %rdx
692movq %r8, %rcx
693call chacha_blocks_sse2_local
694pxor %xmm0, %xmm0
695movdqa %xmm0, 0(%rsp)
696movdqa %xmm0, 16(%rsp)
697movdqa %xmm0, 32(%rsp)
698movq %rbp, %rsp
699popq %rbp
700ret
701FN_END chacha_sse2
702
703GLOBAL_HIDDEN_FN_EXT xchacha_sse2, 6, 16
704pushq %rbp
705pushq %rbx
706movq %rsp, %rbp
707subq $64, %rsp
708andq $~63, %rsp
709movq %rsp, %rbx
710xorq %rax, %rax
711movq %rax, 32(%rbx)
712movq 16(%rsi), %rax
713movq %rax, 40(%rbx)
714movq %r9, 48(%rbx)
715pushq %rdx
716pushq %rcx
717pushq %r8
718movq %rbx, %rdx
719movq %r9, %rcx
720call hchacha_sse2_local
721movq %rbx, %rdi
722popq %rcx
723popq %rdx
724popq %rsi
725call chacha_blocks_sse2_local
726pxor %xmm0, %xmm0
727movdqa %xmm0, 0(%rbx)
728movdqa %xmm0, 16(%rbx)
729movdqa %xmm0, 32(%rbx)
730movq %rbp, %rsp
731popq %rbx
732popq %rbp
733ret
734FN_END xchacha_sse2
735