Merge pull request #244 from svost/frombitcoin
[novacoin.git] / src / scrypt-asm / scrypt-x86.S
1 /*
2  * Copyright 2011-2012 pooler@litecoinpool.org
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26
27 #if defined(__linux__) && defined(__ELF__)
28         .section .note.GNU-stack,"",%progbits
29 #endif
30
31 #if defined(__i386__)
32         
33 .macro scrypt_shuffle src, so, dest, do
34         movl    \so+60(\src), %eax
35         movl    \so+44(\src), %ebx
36         movl    \so+28(\src), %ecx
37         movl    \so+12(\src), %edx
38         movl    %eax, \do+12(\dest)
39         movl    %ebx, \do+28(\dest)
40         movl    %ecx, \do+44(\dest)
41         movl    %edx, \do+60(\dest)
42         movl    \so+40(\src), %eax
43         movl    \so+8(\src), %ebx
44         movl    \so+48(\src), %ecx
45         movl    \so+16(\src), %edx
46         movl    %eax, \do+8(\dest)
47         movl    %ebx, \do+40(\dest)
48         movl    %ecx, \do+16(\dest)
49         movl    %edx, \do+48(\dest)
50         movl    \so+20(\src), %eax
51         movl    \so+4(\src), %ebx
52         movl    \so+52(\src), %ecx
53         movl    \so+36(\src), %edx
54         movl    %eax, \do+4(\dest)
55         movl    %ebx, \do+20(\dest)
56         movl    %ecx, \do+36(\dest)
57         movl    %edx, \do+52(\dest)
58         movl    \so+0(\src), %eax
59         movl    \so+24(\src), %ebx
60         movl    \so+32(\src), %ecx
61         movl    \so+56(\src), %edx
62         movl    %eax, \do+0(\dest)
63         movl    %ebx, \do+24(\dest)
64         movl    %ecx, \do+32(\dest)
65         movl    %edx, \do+56(\dest)
66 .endm
67
68 .macro salsa8_core_gen_quadround
69         movl    52(%esp), %ecx
70         movl    4(%esp), %edx
71         movl    20(%esp), %ebx
72         movl    8(%esp), %esi
73         leal    (%ecx, %edx), %edi
74         roll    $7, %edi
75         xorl    %edi, %ebx
76         movl    %ebx, 4(%esp)
77         movl    36(%esp), %edi
78         leal    (%edx, %ebx), %ebp
79         roll    $9, %ebp
80         xorl    %ebp, %edi
81         movl    24(%esp), %ebp
82         movl    %edi, 8(%esp)
83         addl    %edi, %ebx
84         roll    $13, %ebx
85         xorl    %ebx, %ecx
86         movl    40(%esp), %ebx
87         movl    %ecx, 20(%esp)
88         addl    %edi, %ecx
89         roll    $18, %ecx
90         leal    (%esi, %ebp), %edi
91         roll    $7, %edi
92         xorl    %edi, %ebx
93         movl    %ebx, 24(%esp)
94         movl    56(%esp), %edi
95         xorl    %ecx, %edx
96         leal    (%ebp, %ebx), %ecx
97         roll    $9, %ecx
98         xorl    %ecx, %edi
99         movl    %edi, 36(%esp)
100         movl    28(%esp), %ecx
101         movl    %edx, 28(%esp)
102         movl    44(%esp), %edx
103         addl    %edi, %ebx
104         roll    $13, %ebx
105         xorl    %ebx, %esi
106         movl    60(%esp), %ebx
107         movl    %esi, 40(%esp)
108         addl    %edi, %esi
109         roll    $18, %esi
110         leal    (%ecx, %edx), %edi
111         roll    $7, %edi
112         xorl    %edi, %ebx
113         movl    %ebx, 44(%esp)
114         movl    12(%esp), %edi
115         xorl    %esi, %ebp
116         leal    (%edx, %ebx), %esi
117         roll    $9, %esi
118         xorl    %esi, %edi
119         movl    %edi, 12(%esp)
120         movl    48(%esp), %esi
121         movl    %ebp, 48(%esp)
122         movl    64(%esp), %ebp
123         addl    %edi, %ebx
124         roll    $13, %ebx
125         xorl    %ebx, %ecx
126         movl    16(%esp), %ebx
127         movl    %ecx, 16(%esp)
128         addl    %edi, %ecx
129         roll    $18, %ecx
130         leal    (%esi, %ebp), %edi
131         roll    $7, %edi
132         xorl    %edi, %ebx
133         movl    32(%esp), %edi
134         xorl    %ecx, %edx
135         leal    (%ebp, %ebx), %ecx
136         roll    $9, %ecx
137         xorl    %ecx, %edi
138         movl    %edi, 32(%esp)
139         movl    %ebx, %ecx
140         movl    %edx, 52(%esp)
141         movl    28(%esp), %edx
142         addl    %edi, %ebx
143         roll    $13, %ebx
144         xorl    %ebx, %esi
145         movl    40(%esp), %ebx
146         movl    %esi, 28(%esp)
147         addl    %edi, %esi
148         roll    $18, %esi
149         leal    (%ecx, %edx), %edi
150         roll    $7, %edi
151         xorl    %edi, %ebx
152         movl    %ebx, 40(%esp)
153         movl    12(%esp), %edi
154         xorl    %esi, %ebp
155         leal    (%edx, %ebx), %esi
156         roll    $9, %esi
157         xorl    %esi, %edi
158         movl    %edi, 12(%esp)
159         movl    4(%esp), %esi
160         movl    %ebp, 4(%esp)
161         movl    48(%esp), %ebp
162         addl    %edi, %ebx
163         roll    $13, %ebx
164         xorl    %ebx, %ecx
165         movl    16(%esp), %ebx
166         movl    %ecx, 16(%esp)
167         addl    %edi, %ecx
168         roll    $18, %ecx
169         leal    (%esi, %ebp), %edi
170         roll    $7, %edi
171         xorl    %edi, %ebx
172         movl    %ebx, 48(%esp)
173         movl    32(%esp), %edi
174         xorl    %ecx, %edx
175         leal    (%ebp, %ebx), %ecx
176         roll    $9, %ecx
177         xorl    %ecx, %edi
178         movl    %edi, 32(%esp)
179         movl    24(%esp), %ecx
180         movl    %edx, 24(%esp)
181         movl    52(%esp), %edx
182         addl    %edi, %ebx
183         roll    $13, %ebx
184         xorl    %ebx, %esi
185         movl    28(%esp), %ebx
186         movl    %esi, 28(%esp)
187         addl    %edi, %esi
188         roll    $18, %esi
189         leal    (%ecx, %edx), %edi
190         roll    $7, %edi
191         xorl    %edi, %ebx
192         movl    %ebx, 52(%esp)
193         movl    8(%esp), %edi
194         xorl    %esi, %ebp
195         leal    (%edx, %ebx), %esi
196         roll    $9, %esi
197         xorl    %esi, %edi
198         movl    %edi, 8(%esp)
199         movl    44(%esp), %esi
200         movl    %ebp, 44(%esp)
201         movl    4(%esp), %ebp
202         addl    %edi, %ebx
203         roll    $13, %ebx
204         xorl    %ebx, %ecx
205         movl    20(%esp), %ebx
206         movl    %ecx, 4(%esp)
207         addl    %edi, %ecx
208         roll    $18, %ecx
209         leal    (%esi, %ebp), %edi
210         roll    $7, %edi
211         xorl    %edi, %ebx
212         movl    36(%esp), %edi
213         xorl    %ecx, %edx
214         leal    (%ebp, %ebx), %ecx
215         roll    $9, %ecx
216         xorl    %ecx, %edi
217         movl    %edi, 20(%esp)
218         movl    %ebx, %ecx
219         movl    %edx, 36(%esp)
220         movl    24(%esp), %edx
221         addl    %edi, %ebx
222         roll    $13, %ebx
223         xorl    %ebx, %esi
224         movl    28(%esp), %ebx
225         movl    %esi, 24(%esp)
226         addl    %edi, %esi
227         roll    $18, %esi
228         leal    (%ecx, %edx), %edi
229         roll    $7, %edi
230         xorl    %edi, %ebx
231         movl    %ebx, 28(%esp)
232         xorl    %esi, %ebp
233         movl    8(%esp), %esi
234         leal    (%edx, %ebx), %edi
235         roll    $9, %edi
236         xorl    %edi, %esi
237         movl    40(%esp), %edi
238         movl    %ebp, 8(%esp)
239         movl    44(%esp), %ebp
240         movl    %esi, 40(%esp)
241         addl    %esi, %ebx
242         roll    $13, %ebx
243         xorl    %ebx, %ecx
244         movl    4(%esp), %ebx
245         movl    %ecx, 44(%esp)
246         addl    %esi, %ecx
247         roll    $18, %ecx
248         leal    (%edi, %ebp), %esi
249         roll    $7, %esi
250         xorl    %esi, %ebx
251         movl    %ebx, 4(%esp)
252         movl    20(%esp), %esi
253         xorl    %ecx, %edx
254         leal    (%ebp, %ebx), %ecx
255         roll    $9, %ecx
256         xorl    %ecx, %esi
257         movl    %esi, 56(%esp)
258         movl    48(%esp), %ecx
259         movl    %edx, 20(%esp)
260         movl    36(%esp), %edx
261         addl    %esi, %ebx
262         roll    $13, %ebx
263         xorl    %ebx, %edi
264         movl    24(%esp), %ebx
265         movl    %edi, 24(%esp)
266         addl    %esi, %edi
267         roll    $18, %edi
268         leal    (%ecx, %edx), %esi
269         roll    $7, %esi
270         xorl    %esi, %ebx
271         movl    %ebx, 60(%esp)
272         movl    12(%esp), %esi
273         xorl    %edi, %ebp
274         leal    (%edx, %ebx), %edi
275         roll    $9, %edi
276         xorl    %edi, %esi
277         movl    %esi, 12(%esp)
278         movl    52(%esp), %edi
279         movl    %ebp, 36(%esp)
280         movl    8(%esp), %ebp
281         addl    %esi, %ebx
282         roll    $13, %ebx
283         xorl    %ebx, %ecx
284         movl    16(%esp), %ebx
285         movl    %ecx, 16(%esp)
286         addl    %esi, %ecx
287         roll    $18, %ecx
288         leal    (%edi, %ebp), %esi
289         roll    $7, %esi
290         xorl    %esi, %ebx
291         movl    32(%esp), %esi
292         xorl    %ecx, %edx
293         leal    (%ebp, %ebx), %ecx
294         roll    $9, %ecx
295         xorl    %ecx, %esi
296         movl    %esi, 32(%esp)
297         movl    %ebx, %ecx
298         movl    %edx, 48(%esp)
299         movl    20(%esp), %edx
300         addl    %esi, %ebx
301         roll    $13, %ebx
302         xorl    %ebx, %edi
303         movl    24(%esp), %ebx
304         movl    %edi, 20(%esp)
305         addl    %esi, %edi
306         roll    $18, %edi
307         leal    (%ecx, %edx), %esi
308         roll    $7, %esi
309         xorl    %esi, %ebx
310         movl    %ebx, 8(%esp)
311         movl    12(%esp), %esi
312         xorl    %edi, %ebp
313         leal    (%edx, %ebx), %edi
314         roll    $9, %edi
315         xorl    %edi, %esi
316         movl    %esi, 12(%esp)
317         movl    28(%esp), %edi
318         movl    %ebp, 52(%esp)
319         movl    36(%esp), %ebp
320         addl    %esi, %ebx
321         roll    $13, %ebx
322         xorl    %ebx, %ecx
323         movl    16(%esp), %ebx
324         movl    %ecx, 16(%esp)
325         addl    %esi, %ecx
326         roll    $18, %ecx
327         leal    (%edi, %ebp), %esi
328         roll    $7, %esi
329         xorl    %esi, %ebx
330         movl    %ebx, 28(%esp)
331         movl    32(%esp), %esi
332         xorl    %ecx, %edx
333         leal    (%ebp, %ebx), %ecx
334         roll    $9, %ecx
335         xorl    %ecx, %esi
336         movl    %esi, 32(%esp)
337         movl    4(%esp), %ecx
338         movl    %edx, 4(%esp)
339         movl    48(%esp), %edx
340         addl    %esi, %ebx
341         roll    $13, %ebx
342         xorl    %ebx, %edi
343         movl    20(%esp), %ebx
344         movl    %edi, 20(%esp)
345         addl    %esi, %edi
346         roll    $18, %edi
347         leal    (%ecx, %edx), %esi
348         roll    $7, %esi
349         xorl    %esi, %ebx
350         movl    %ebx, 48(%esp)
351         movl    40(%esp), %esi
352         xorl    %edi, %ebp
353         leal    (%edx, %ebx), %edi
354         roll    $9, %edi
355         xorl    %edi, %esi
356         movl    %esi, 36(%esp)
357         movl    60(%esp), %edi
358         movl    %ebp, 24(%esp)
359         movl    52(%esp), %ebp
360         addl    %esi, %ebx
361         roll    $13, %ebx
362         xorl    %ebx, %ecx
363         movl    44(%esp), %ebx
364         movl    %ecx, 40(%esp)
365         addl    %esi, %ecx
366         roll    $18, %ecx
367         leal    (%edi, %ebp), %esi
368         roll    $7, %esi
369         xorl    %esi, %ebx
370         movl    %ebx, 52(%esp)
371         movl    56(%esp), %esi
372         xorl    %ecx, %edx
373         leal    (%ebp, %ebx), %ecx
374         roll    $9, %ecx
375         xorl    %ecx, %esi
376         movl    %esi, 56(%esp)
377         addl    %esi, %ebx
378         movl    %edx, 44(%esp)
379         roll    $13, %ebx
380         xorl    %ebx, %edi
381         movl    %edi, 60(%esp)
382         addl    %esi, %edi
383         roll    $18, %edi
384         xorl    %edi, %ebp
385         movl    %ebp, 64(%esp)
386 .endm
387
388         .text
389         .p2align 5
390 salsa8_core_gen:
391         salsa8_core_gen_quadround
392         salsa8_core_gen_quadround
393         ret
394         
395         
396         .text
397         .p2align 5
398         .globl scrypt_core
399         .globl _scrypt_core
400 scrypt_core:
401 _scrypt_core:
402         pushl   %ebx
403         pushl   %ebp
404         pushl   %edi
405         pushl   %esi
406         
407         /* Check for SSE2 availability */
408         movl    $1, %eax
409         cpuid
410         andl    $0x04000000, %edx
411         jnz scrypt_core_sse2
412         
413 scrypt_core_gen:
414         movl    20(%esp), %edi
415         movl    24(%esp), %esi
416         subl    $72, %esp
417         
418 .macro scrypt_core_macro1a p, q
419         movl    \p(%edi), %eax
420         movl    \q(%edi), %edx
421         movl    %eax, \p(%esi)
422         movl    %edx, \q(%esi)
423         xorl    %edx, %eax
424         movl    %eax, \p(%edi)
425         movl    %eax, \p(%esp)
426 .endm
427         
428 .macro scrypt_core_macro1b p, q
429         movl    \p(%edi), %eax
430         xorl    \p(%esi, %edx), %eax
431         movl    \q(%edi), %ebx
432         xorl    \q(%esi, %edx), %ebx
433         movl    %ebx, \q(%edi)
434         xorl    %ebx, %eax
435         movl    %eax, \p(%edi)
436         movl    %eax, \p(%esp)
437 .endm
438         
439 .macro scrypt_core_macro2 p, q
440         movl    \p(%esp), %eax
441         addl    \p(%edi), %eax
442         movl    %eax, \p(%edi)
443         xorl    \q(%edi), %eax
444         movl    %eax, \q(%edi)
445         movl    %eax, \p(%esp)
446 .endm
447         
448 .macro scrypt_core_macro3 p, q
449         movl    \p(%esp), %eax
450         addl    \q(%edi), %eax
451         movl    %eax, \q(%edi)
452 .endm
453         
454         leal    131072(%esi), %ecx
455 scrypt_core_gen_loop1:
456         movl    %esi, 64(%esp)
457         movl    %ecx, 68(%esp)
458         
459         scrypt_core_macro1a     0, 64
460         scrypt_core_macro1a     4, 68
461         scrypt_core_macro1a     8, 72
462         scrypt_core_macro1a     12, 76
463         scrypt_core_macro1a     16, 80
464         scrypt_core_macro1a     20, 84
465         scrypt_core_macro1a     24, 88
466         scrypt_core_macro1a     28, 92
467         scrypt_core_macro1a     32, 96
468         scrypt_core_macro1a     36, 100
469         scrypt_core_macro1a     40, 104
470         scrypt_core_macro1a     44, 108
471         scrypt_core_macro1a     48, 112
472         scrypt_core_macro1a     52, 116
473         scrypt_core_macro1a     56, 120
474         scrypt_core_macro1a     60, 124
475         
476         call salsa8_core_gen
477         
478         movl    92(%esp), %edi
479         scrypt_core_macro2      0, 64
480         scrypt_core_macro2      4, 68
481         scrypt_core_macro2      8, 72
482         scrypt_core_macro2      12, 76
483         scrypt_core_macro2      16, 80
484         scrypt_core_macro2      20, 84
485         scrypt_core_macro2      24, 88
486         scrypt_core_macro2      28, 92
487         scrypt_core_macro2      32, 96
488         scrypt_core_macro2      36, 100
489         scrypt_core_macro2      40, 104
490         scrypt_core_macro2      44, 108
491         scrypt_core_macro2      48, 112
492         scrypt_core_macro2      52, 116
493         scrypt_core_macro2      56, 120
494         scrypt_core_macro2      60, 124
495         
496         call salsa8_core_gen
497         
498         movl    92(%esp), %edi
499         scrypt_core_macro3      0, 64
500         scrypt_core_macro3      4, 68
501         scrypt_core_macro3      8, 72
502         scrypt_core_macro3      12, 76
503         scrypt_core_macro3      16, 80
504         scrypt_core_macro3      20, 84
505         scrypt_core_macro3      24, 88
506         scrypt_core_macro3      28, 92
507         scrypt_core_macro3      32, 96
508         scrypt_core_macro3      36, 100
509         scrypt_core_macro3      40, 104
510         scrypt_core_macro3      44, 108
511         scrypt_core_macro3      48, 112
512         scrypt_core_macro3      52, 116
513         scrypt_core_macro3      56, 120
514         scrypt_core_macro3      60, 124
515         
516         movl    64(%esp), %esi
517         movl    68(%esp), %ecx
518         addl    $128, %esi
519         cmpl    %ecx, %esi
520         jne scrypt_core_gen_loop1
521
522         movl    96(%esp), %esi
523         movl    $1024, %ecx
524 scrypt_core_gen_loop2:
525         movl    %ecx, 68(%esp)
526         
527         movl    64(%edi), %edx
528         andl    $1023, %edx
529         shll    $7, %edx
530         
531         scrypt_core_macro1b     0, 64
532         scrypt_core_macro1b     4, 68
533         scrypt_core_macro1b     8, 72
534         scrypt_core_macro1b     12, 76
535         scrypt_core_macro1b     16, 80
536         scrypt_core_macro1b     20, 84
537         scrypt_core_macro1b     24, 88
538         scrypt_core_macro1b     28, 92
539         scrypt_core_macro1b     32, 96
540         scrypt_core_macro1b     36, 100
541         scrypt_core_macro1b     40, 104
542         scrypt_core_macro1b     44, 108
543         scrypt_core_macro1b     48, 112
544         scrypt_core_macro1b     52, 116
545         scrypt_core_macro1b     56, 120
546         scrypt_core_macro1b     60, 124
547         
548         call salsa8_core_gen
549         
550         movl    92(%esp), %edi
551         scrypt_core_macro2      0, 64
552         scrypt_core_macro2      4, 68
553         scrypt_core_macro2      8, 72
554         scrypt_core_macro2      12, 76
555         scrypt_core_macro2      16, 80
556         scrypt_core_macro2      20, 84
557         scrypt_core_macro2      24, 88
558         scrypt_core_macro2      28, 92
559         scrypt_core_macro2      32, 96
560         scrypt_core_macro2      36, 100
561         scrypt_core_macro2      40, 104
562         scrypt_core_macro2      44, 108
563         scrypt_core_macro2      48, 112
564         scrypt_core_macro2      52, 116
565         scrypt_core_macro2      56, 120
566         scrypt_core_macro2      60, 124
567         
568         call salsa8_core_gen
569         
570         movl    92(%esp), %edi
571         movl    96(%esp), %esi
572         scrypt_core_macro3      0, 64
573         scrypt_core_macro3      4, 68
574         scrypt_core_macro3      8, 72
575         scrypt_core_macro3      12, 76
576         scrypt_core_macro3      16, 80
577         scrypt_core_macro3      20, 84
578         scrypt_core_macro3      24, 88
579         scrypt_core_macro3      28, 92
580         scrypt_core_macro3      32, 96
581         scrypt_core_macro3      36, 100
582         scrypt_core_macro3      40, 104
583         scrypt_core_macro3      44, 108
584         scrypt_core_macro3      48, 112
585         scrypt_core_macro3      52, 116
586         scrypt_core_macro3      56, 120
587         scrypt_core_macro3      60, 124
588         
589         movl    68(%esp), %ecx
590         subl    $1, %ecx
591         ja scrypt_core_gen_loop2
592         
593         addl    $72, %esp
594         popl    %esi
595         popl    %edi
596         popl    %ebp
597         popl    %ebx
598         ret
599
600
601 .macro salsa8_core_sse2_doubleround
602         movdqa  %xmm1, %xmm4
603         paddd   %xmm0, %xmm4
604         movdqa  %xmm4, %xmm5
605         pslld   $7, %xmm4
606         psrld   $25, %xmm5
607         pxor    %xmm4, %xmm3
608         movdqa  %xmm0, %xmm4
609         pxor    %xmm5, %xmm3
610         
611         paddd   %xmm3, %xmm4
612         movdqa  %xmm4, %xmm5
613         pslld   $9, %xmm4
614         psrld   $23, %xmm5
615         pxor    %xmm4, %xmm2
616         movdqa  %xmm3, %xmm4
617         pxor    %xmm5, %xmm2
618         pshufd  $0x93, %xmm3, %xmm3
619         
620         paddd   %xmm2, %xmm4
621         movdqa  %xmm4, %xmm5
622         pslld   $13, %xmm4
623         psrld   $19, %xmm5
624         pxor    %xmm4, %xmm1
625         movdqa  %xmm2, %xmm4
626         pxor    %xmm5, %xmm1
627         pshufd  $0x4e, %xmm2, %xmm2
628         
629         paddd   %xmm1, %xmm4
630         movdqa  %xmm4, %xmm5
631         pslld   $18, %xmm4
632         psrld   $14, %xmm5
633         pxor    %xmm4, %xmm0
634         movdqa  %xmm3, %xmm4
635         pxor    %xmm5, %xmm0
636         pshufd  $0x39, %xmm1, %xmm1
637         
638         paddd   %xmm0, %xmm4
639         movdqa  %xmm4, %xmm5
640         pslld   $7, %xmm4
641         psrld   $25, %xmm5
642         pxor    %xmm4, %xmm1
643         movdqa  %xmm0, %xmm4
644         pxor    %xmm5, %xmm1
645         
646         paddd   %xmm1, %xmm4
647         movdqa  %xmm4, %xmm5
648         pslld   $9, %xmm4
649         psrld   $23, %xmm5
650         pxor    %xmm4, %xmm2
651         movdqa  %xmm1, %xmm4
652         pxor    %xmm5, %xmm2
653         pshufd  $0x93, %xmm1, %xmm1
654         
655         paddd   %xmm2, %xmm4
656         movdqa  %xmm4, %xmm5
657         pslld   $13, %xmm4
658         psrld   $19, %xmm5
659         pxor    %xmm4, %xmm3
660         movdqa  %xmm2, %xmm4
661         pxor    %xmm5, %xmm3
662         pshufd  $0x4e, %xmm2, %xmm2
663         
664         paddd   %xmm3, %xmm4
665         movdqa  %xmm4, %xmm5
666         pslld   $18, %xmm4
667         psrld   $14, %xmm5
668         pxor    %xmm4, %xmm0
669         pshufd  $0x39, %xmm3, %xmm3
670         pxor    %xmm5, %xmm0
671 .endm
672
673 .macro salsa8_core_sse2
674         salsa8_core_sse2_doubleround
675         salsa8_core_sse2_doubleround
676         salsa8_core_sse2_doubleround
677         salsa8_core_sse2_doubleround
678 .endm
679         
680         .p2align 5
681 scrypt_core_sse2:
682         movl    20(%esp), %edi
683         movl    24(%esp), %esi
684         movl    %esp, %ebp
685         subl    $128, %esp
686         andl    $-16, %esp
687         
688         scrypt_shuffle %edi, 0, %esp, 0
689         scrypt_shuffle %edi, 64, %esp, 64
690         
691         movdqa  96(%esp), %xmm6
692         movdqa  112(%esp), %xmm7
693         
694         movl    %esi, %edx
695         leal    131072(%esi), %ecx
696 scrypt_core_sse2_loop1:
697         movdqa  0(%esp), %xmm0
698         movdqa  16(%esp), %xmm1
699         movdqa  32(%esp), %xmm2
700         movdqa  48(%esp), %xmm3
701         movdqa  64(%esp), %xmm4
702         movdqa  80(%esp), %xmm5
703         pxor    %xmm4, %xmm0
704         pxor    %xmm5, %xmm1
705         movdqa  %xmm0, 0(%edx)
706         movdqa  %xmm1, 16(%edx)
707         pxor    %xmm6, %xmm2
708         pxor    %xmm7, %xmm3
709         movdqa  %xmm2, 32(%edx)
710         movdqa  %xmm3, 48(%edx)
711         movdqa  %xmm4, 64(%edx)
712         movdqa  %xmm5, 80(%edx)
713         movdqa  %xmm6, 96(%edx)
714         movdqa  %xmm7, 112(%edx)
715         
716         salsa8_core_sse2
717         paddd   0(%edx), %xmm0
718         paddd   16(%edx), %xmm1
719         paddd   32(%edx), %xmm2
720         paddd   48(%edx), %xmm3
721         movdqa  %xmm0, 0(%esp)
722         movdqa  %xmm1, 16(%esp)
723         movdqa  %xmm2, 32(%esp)
724         movdqa  %xmm3, 48(%esp)
725         
726         pxor    64(%esp), %xmm0
727         pxor    80(%esp), %xmm1
728         pxor    %xmm6, %xmm2
729         pxor    %xmm7, %xmm3
730         movdqa  %xmm0, 64(%esp)
731         movdqa  %xmm1, 80(%esp)
732         movdqa  %xmm2, %xmm6
733         movdqa  %xmm3, %xmm7
734         salsa8_core_sse2
735         paddd   64(%esp), %xmm0
736         paddd   80(%esp), %xmm1
737         paddd   %xmm2, %xmm6
738         paddd   %xmm3, %xmm7
739         movdqa  %xmm0, 64(%esp)
740         movdqa  %xmm1, 80(%esp)
741         
742         addl    $128, %edx
743         cmpl    %ecx, %edx
744         jne scrypt_core_sse2_loop1
745         
746         movdqa  64(%esp), %xmm4
747         movdqa  80(%esp), %xmm5
748         
749         movl    $1024, %ecx
750 scrypt_core_sse2_loop2:
751         movd    %xmm4, %edx
752         movdqa  0(%esp), %xmm0
753         movdqa  16(%esp), %xmm1
754         movdqa  32(%esp), %xmm2
755         movdqa  48(%esp), %xmm3
756         andl    $1023, %edx
757         shll    $7, %edx
758         pxor    0(%esi, %edx), %xmm0
759         pxor    16(%esi, %edx), %xmm1
760         pxor    32(%esi, %edx), %xmm2
761         pxor    48(%esi, %edx), %xmm3
762         
763         pxor    %xmm4, %xmm0
764         pxor    %xmm5, %xmm1
765         movdqa  %xmm0, 0(%esp)
766         movdqa  %xmm1, 16(%esp)
767         pxor    %xmm6, %xmm2
768         pxor    %xmm7, %xmm3
769         movdqa  %xmm2, 32(%esp)
770         movdqa  %xmm3, 48(%esp)
771         salsa8_core_sse2
772         paddd   0(%esp), %xmm0
773         paddd   16(%esp), %xmm1
774         paddd   32(%esp), %xmm2
775         paddd   48(%esp), %xmm3
776         movdqa  %xmm0, 0(%esp)
777         movdqa  %xmm1, 16(%esp)
778         movdqa  %xmm2, 32(%esp)
779         movdqa  %xmm3, 48(%esp)
780         
781         pxor    64(%esi, %edx), %xmm0
782         pxor    80(%esi, %edx), %xmm1
783         pxor    96(%esi, %edx), %xmm2
784         pxor    112(%esi, %edx), %xmm3
785         pxor    64(%esp), %xmm0
786         pxor    80(%esp), %xmm1
787         pxor    %xmm6, %xmm2
788         pxor    %xmm7, %xmm3
789         movdqa  %xmm0, 64(%esp)
790         movdqa  %xmm1, 80(%esp)
791         movdqa  %xmm2, %xmm6
792         movdqa  %xmm3, %xmm7
793         salsa8_core_sse2
794         paddd   64(%esp), %xmm0
795         paddd   80(%esp), %xmm1
796         paddd   %xmm2, %xmm6
797         paddd   %xmm3, %xmm7
798         movdqa  %xmm0, %xmm4
799         movdqa  %xmm1, %xmm5
800         movdqa  %xmm0, 64(%esp)
801         movdqa  %xmm1, 80(%esp)
802         
803         subl    $1, %ecx
804         ja scrypt_core_sse2_loop2
805         
806         movdqa  %xmm6, 96(%esp)
807         movdqa  %xmm7, 112(%esp)
808         
809         scrypt_shuffle %esp, 0, %edi, 0
810         scrypt_shuffle %esp, 64, %edi, 64
811         
812         movl    %ebp, %esp
813         popl    %esi
814         popl    %edi
815         popl    %ebp
816         popl    %ebx
817         ret
818
819 #endif