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