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