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