143eb3a4b164f9571861c3bdada7cd5b8b317530
[novacoin.git] / src / scrypt-arm.S
1 /*
2  * Copyright 2012 pooler@litecoinpool.org
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the Free
6  * Software Foundation; either version 2 of the License, or (at your option)
7  * any later version.  See COPYING for more details.
8  */
9
10
11 #if defined(OPTIMIZED_SALSA) &&  defined(__arm__) && defined(__APCS_32__)
12
13 #if defined(__linux__) && defined(__ELF__)
14 .section .note.GNU-stack,"",%progbits
15 #endif
16
17 #if defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || \
18         defined(__ARM_ARCH_5TEJ__) || defined(__ARM_ARCH_6__) || \
19         defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || \
20         defined(__ARM_ARCH_6M__) || defined(__ARM_ARCH_6T2__) || \
21         defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__)
22 #define __ARM_ARCH_5E_OR_6__
23 #endif
24
25 #if defined(__ARM_ARCH_5E_OR_6__) || defined(__ARM_ARCH_7__) || \
26         defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || \
27         defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
28 #define __ARM_ARCH_5E_OR_6_OR_7__
29 #endif
30
31 #ifdef __ARM_ARCH_5E_OR_6__
32
33 #define scrypt_shuffle() \
34         add     lr, r0, #9*4; \
35         ldmia   r0, {r2-r7}; \
36         ldmia   lr, {r2, r8-r12, lr}; \
37         str     r3, [r0, #5*4]; \
38         str     r5, [r0, #15*4]; \
39         str     r6, [r0, #12*4]; \
40         str     r7, [r0, #1*4]; \
41         ldr r5, [r0, #7*4]; \
42         str     r2, [r0, #13*4]; \
43         str     r8, [r0, #2*4]; \
44         strd    r4, [r0, #10*4]; \
45         str     r9, [r0, #7*4]; \
46         str     r10, [r0, #4*4]; \
47         str     r11, [r0, #9*4]; \
48         str     lr, [r0, #3*4]; \
49         add     r2, r0, #64+0*4; \
50         add     lr, r0, #64+9*4; \
51         ldmia   r2, {r2-r7}; \
52         ldmia   lr, {r2, r8-r12, lr}; \
53         str     r3, [r0, #64+5*4]; \
54         str     r5, [r0, #64+15*4]; \
55         str     r6, [r0, #64+12*4]; \
56         str     r7, [r0, #64+1*4]; \
57         ldr r5, [r0, #64+7*4]; \
58         str     r2, [r0, #64+13*4]; \
59         str     r8, [r0, #64+2*4]; \
60         strd    r4, [r0, #64+10*4]; \
61         str     r9, [r0, #64+7*4]; \
62         str     r10, [r0, #64+4*4]; \
63         str     r11, [r0, #64+9*4]; \
64         str     lr, [r0, #64+3*4]; \
65
66
67 #define salsa8_core_doubleround_body() \
68         add     r6, r2, r6; \
69         add     r7, r3, r7; \
70         eor     r10, r10, r6, ror #25; \
71         add     r6, r0, r4; \
72         eor     r11, r11, r7, ror #25; \
73         add     r7, r1, r5; \
74         strd    r10, [sp, #14*4]; \
75         eor     r12, r12, r6, ror #25; \
76         eor     lr, lr, r7, ror #25; \
77         ldrd    r6, [sp, #10*4]; \
78         add     r2, r10, r2; \
79         add     r3, r11, r3; \
80         eor     r6, r6, r2, ror #23; \
81         add     r2, r12, r0; \
82         eor     r7, r7, r3, ror #23; \
83         add     r3, lr, r1; \
84         strd    r6, [sp, #10*4]; \
85         eor     r8, r8, r2, ror #23; \
86         eor     r9, r9, r3, ror #23; \
87         ldrd    r2, [sp, #6*4]; \
88         add     r10, r6, r10; \
89         add     r11, r7, r11; \
90         eor     r2, r2, r10, ror #19; \
91         add     r10, r8, r12; \
92         eor     r3, r3, r11, ror #19; \
93         add     r11, r9, lr; \
94         eor     r4, r4, r10, ror #19; \
95         eor     r5, r5, r11, ror #19; \
96         ldrd    r10, [sp, #2*4]; \
97         add     r6, r2, r6; \
98         add     r7, r3, r7; \
99         eor     r10, r10, r6, ror #14; \
100         add     r6, r4, r8; \
101         eor     r11, r11, r7, ror #14; \
102         add     r7, r5, r9; \
103         eor     r0, r0, r6, ror #14; \
104         eor     r1, r1, r7, ror #14; \
105         ldrd    r6, [sp, #14*4]; \
106         strd    r2, [sp, #6*4]; \
107         strd    r10, [sp, #2*4]; \
108         add     r6, r11, r6; \
109         add     r7, r0, r7; \
110         eor     r4, r4, r6, ror #25; \
111         add     r6, r1, r12; \
112         eor     r5, r5, r7, ror #25; \
113         add     r7, r10, lr; \
114         eor     r2, r2, r6, ror #25; \
115         eor     r3, r3, r7, ror #25; \
116         strd    r2, [sp, #6*4]; \
117         add     r10, r3, r10; \
118         ldrd    r6, [sp, #10*4]; \
119         add     r11, r4, r11; \
120         eor     r8, r8, r10, ror #23; \
121         add     r10, r5, r0; \
122         eor     r9, r9, r11, ror #23; \
123         add     r11, r2, r1; \
124         eor     r6, r6, r10, ror #23; \
125         eor     r7, r7, r11, ror #23; \
126         strd    r6, [sp, #10*4]; \
127         add     r2, r7, r2; \
128         ldrd    r10, [sp, #14*4]; \
129         add     r3, r8, r3; \
130         eor     r12, r12, r2, ror #19; \
131         add     r2, r9, r4; \
132         eor     lr, lr, r3, ror #19; \
133         add     r3, r6, r5; \
134         eor     r10, r10, r2, ror #19; \
135         eor     r11, r11, r3, ror #19; \
136         ldrd    r2, [sp, #2*4]; \
137         add     r6, r11, r6; \
138         add     r7, r12, r7; \
139         eor     r0, r0, r6, ror #14; \
140         add     r6, lr, r8; \
141         eor     r1, r1, r7, ror #14; \
142         add     r7, r10, r9; \
143         eor     r2, r2, r6, ror #14; \
144         eor     r3, r3, r7, ror #14; \
145
146
147 #define salsa8_core() \
148         ldmia   sp, {r0-r12, lr}; \
149         ldrd    r10, [sp, #14*4]; \
150         salsa8_core_doubleround_body(); \
151         ldrd    r6, [sp, #6*4]; \
152         strd    r2, [sp, #2*4]; \
153         strd    r10, [sp, #14*4]; \
154         salsa8_core_doubleround_body(); \
155         ldrd    r6, [sp, #6*4]; \
156         strd    r2, [sp, #2*4]; \
157         strd    r10, [sp, #14*4]; \
158         salsa8_core_doubleround_body(); \
159         ldrd    r6, [sp, #6*4]; \
160         strd    r2, [sp, #2*4]; \
161         strd    r10, [sp, #14*4]; \
162         salsa8_core_doubleround_body(); \
163         stmia   sp, {r0-r5}; \
164         strd    r8, [sp, #8*4]; \
165         str     r12, [sp, #12*4]; \
166         str     lr, [sp, #13*4]; \
167         strd    r10, [sp, #14*4]; \
168
169
170 #else
171
172 #define scrypt_shuffle() \
173
174
175 #define salsa8_core_doubleround_body() \
176         ldr     r8, [sp, #8*4]; \
177         add     r11, r11, r10; \
178         ldr     lr, [sp, #13*4]; \
179         add     r12, r12, r3; \
180         eor     r2, r2, r11, ror #23; \
181         add     r11, r4, r0; \
182         eor     r7, r7, r12, ror #23; \
183         add     r12, r9, r5; \
184         str     r9, [sp, #9*4]; \
185         eor     r8, r8, r11, ror #23; \
186         str     r10, [sp, #14*4]; \
187         eor     lr, lr, r12, ror #23; \
188         ldr     r11, [sp, #11*4]; \
189         add     r9, lr, r9; \
190         ldr     r12, [sp, #12*4]; \
191         add     r10, r2, r10; \
192         eor     r1, r1, r9, ror #19; \
193         add     r9, r7, r3; \
194         eor     r6, r6, r10, ror #19; \
195         add     r10, r8, r4; \
196         str     r8, [sp, #8*4]; \
197         eor     r11, r11, r9, ror #19; \
198         str     lr, [sp, #13*4]; \
199         eor     r12, r12, r10, ror #19; \
200         ldr     r9, [sp, #10*4]; \
201         add     r8, r12, r8; \
202         ldr     r10, [sp, #15*4]; \
203         add     lr, r1, lr; \
204         eor     r0, r0, r8, ror #14; \
205         add     r8, r6, r2; \
206         eor     r5, r5, lr, ror #14; \
207         add     lr, r11, r7; \
208         eor     r9, r9, r8, ror #14; \
209         ldr     r8, [sp, #9*4]; \
210         eor     r10, r10, lr, ror #14; \
211         ldr     lr, [sp, #14*4]; \
212         add     r8, r9, r8; \
213         str     r9, [sp, #10*4]; \
214         add     lr, r10, lr; \
215         str     r10, [sp, #15*4]; \
216         eor     r11, r11, r8, ror #25; \
217         add     r8, r0, r3; \
218         eor     r12, r12, lr, ror #25; \
219         add     lr, r5, r4; \
220         eor     r1, r1, r8, ror #25; \
221         ldr     r8, [sp, #8*4]; \
222         eor     r6, r6, lr, ror #25; \
223         add     r9, r11, r9; \
224         ldr     lr, [sp, #13*4]; \
225         add     r10, r12, r10; \
226         eor     r8, r8, r9, ror #23; \
227         add     r9, r1, r0; \
228         eor     lr, lr, r10, ror #23; \
229         add     r10, r6, r5; \
230         str     r11, [sp, #11*4]; \
231         eor     r2, r2, r9, ror #23; \
232         str     r12, [sp, #12*4]; \
233         eor     r7, r7, r10, ror #23; \
234         ldr     r9, [sp, #9*4]; \
235         add     r11, r8, r11; \
236         ldr     r10, [sp, #14*4]; \
237         add     r12, lr, r12; \
238         eor     r9, r9, r11, ror #19; \
239         add     r11, r2, r1; \
240         eor     r10, r10, r12, ror #19; \
241         add     r12, r7, r6; \
242         str     r8, [sp, #8*4]; \
243         eor     r3, r3, r11, ror #19; \
244         str     lr, [sp, #13*4]; \
245         eor     r4, r4, r12, ror #19; \
246
247
248 #define salsa8_core() \
249         ldmia   sp, {r0-r7}; \
250         ldr     r12, [sp, #15*4]; \
251         ldr     r8, [sp, #11*4]; \
252         ldr     lr, [sp, #12*4]; \
253         ldr     r9, [sp, #9*4]; \
254         add     r8, r8, r12; \
255         ldr     r11, [sp, #10*4]; \
256         add     lr, lr, r0; \
257         eor     r3, r3, r8, ror #25; \
258         add     r8, r5, r1; \
259         ldr     r10, [sp, #14*4]; \
260         eor     r4, r4, lr, ror #25; \
261         add     lr, r11, r6; \
262         eor     r9, r9, r8, ror #25; \
263         eor     r10, r10, lr, ror #25; \
264         salsa8_core_doubleround_body(); \
265         ldr     r11, [sp, #10*4]; \
266         add     r8, r9, r8; \
267         ldr     r12, [sp, #15*4]; \
268         add     lr, r10, lr; \
269         eor     r11, r11, r8, ror #14; \
270         add     r8, r3, r2; \
271         eor     r12, r12, lr, ror #14; \
272         add     lr, r4, r7; \
273         eor     r0, r0, r8, ror #14; \
274         ldr     r8, [sp, #11*4]; \
275         eor     r5, r5, lr, ror #14; \
276         ldr     lr, [sp, #12*4]; \
277         add     r8, r8, r12; \
278         str     r11, [sp, #10*4]; \
279         add     lr, lr, r0; \
280         str     r12, [sp, #15*4]; \
281         eor     r3, r3, r8, ror #25; \
282         add     r8, r5, r1; \
283         eor     r4, r4, lr, ror #25; \
284         add     lr, r11, r6; \
285         str     r9, [sp, #9*4]; \
286         eor     r9, r9, r8, ror #25; \
287         str     r10, [sp, #14*4]; \
288         eor     r10, r10, lr, ror #25; \
289         salsa8_core_doubleround_body(); \
290         ldr     r11, [sp, #10*4]; \
291         add     r8, r9, r8; \
292         ldr     r12, [sp, #15*4]; \
293         add     lr, r10, lr; \
294         eor     r11, r11, r8, ror #14; \
295         add     r8, r3, r2; \
296         eor     r12, r12, lr, ror #14; \
297         add     lr, r4, r7; \
298         eor     r0, r0, r8, ror #14; \
299         ldr     r8, [sp, #11*4]; \
300         eor     r5, r5, lr, ror #14; \
301         ldr     lr, [sp, #12*4]; \
302         add     r8, r8, r12; \
303         str     r11, [sp, #10*4]; \
304         add     lr, lr, r0; \
305         str     r12, [sp, #15*4]; \
306         eor     r3, r3, r8, ror #25; \
307         add     r8, r5, r1; \
308         eor     r4, r4, lr, ror #25; \
309         add     lr, r11, r6; \
310         str     r9, [sp, #9*4]; \
311         eor     r9, r9, r8, ror #25; \
312         str     r10, [sp, #14*4]; \
313         eor     r10, r10, lr, ror #25; \
314         salsa8_core_doubleround_body(); \
315         ldr     r11, [sp, #10*4]; \
316         add     r8, r9, r8; \
317         ldr     r12, [sp, #15*4]; \
318         add     lr, r10, lr; \
319         eor     r11, r11, r8, ror #14; \
320         add     r8, r3, r2; \
321         eor     r12, r12, lr, ror #14; \
322         add     lr, r4, r7; \
323         eor     r0, r0, r8, ror #14; \
324         ldr     r8, [sp, #11*4]; \
325         eor     r5, r5, lr, ror #14; \
326         ldr     lr, [sp, #12*4]; \
327         add     r8, r8, r12; \
328         str     r11, [sp, #10*4]; \
329         add     lr, lr, r0; \
330         str     r12, [sp, #15*4]; \
331         eor     r3, r3, r8, ror #25; \
332         add     r8, r5, r1; \
333         eor     r4, r4, lr, ror #25; \
334         add     lr, r11, r6; \
335         str     r9, [sp, #9*4]; \
336         eor     r9, r9, r8, ror #25; \
337         str     r10, [sp, #14*4]; \
338         eor     r10, r10, lr, ror #25; \
339         salsa8_core_doubleround_body(); \
340         ldr     r11, [sp, #10*4]; \
341         add     r8, r9, r8; \
342         ldr     r12, [sp, #15*4]; \
343         add     lr, r10, lr; \
344         str     r9, [sp, #9*4]; \
345         eor     r11, r11, r8, ror #14; \
346         eor     r12, r12, lr, ror #14; \
347         add     r8, r3, r2; \
348         str     r10, [sp, #14*4]; \
349         add     lr, r4, r7; \
350         str     r11, [sp, #10*4]; \
351         eor     r0, r0, r8, ror #14; \
352         str     r12, [sp, #15*4]; \
353         eor     r5, r5, lr, ror #14; \
354         stmia   sp, {r0-r7}; \
355
356
357 #endif
358
359
360 #define scrypt_core_macro1a_x4() \
361         ldmia   r0, {r4-r7}; \
362         ldmia   lr!, {r8-r11}; \
363         stmia   r1!, {r4-r7}; \
364         stmia   r3!, {r8-r11}; \
365         eor     r4, r4, r8; \
366         eor     r5, r5, r9; \
367         eor     r6, r6, r10; \
368         eor     r7, r7, r11; \
369         stmia   r0!, {r4-r7}; \
370         stmia   r12!, {r4-r7}; \
371
372
373 #define scrypt_core_macro1b_x4() \
374         ldmia   r3!, {r8-r11}; \
375         ldmia   r2, {r4-r7}; \
376         eor     r8, r8, r4; \
377         eor     r9, r9, r5; \
378         eor     r10, r10, r6; \
379         eor     r11, r11, r7; \
380         ldmia   r0, {r4-r7}; \
381         stmia   r2!, {r8-r11}; \
382         eor     r4, r4, r8; \
383         eor     r5, r5, r9; \
384         eor     r6, r6, r10; \
385         eor     r7, r7, r11; \
386         ldmia   r1!, {r8-r11}; \
387         eor     r4, r4, r8; \
388         eor     r5, r5, r9; \
389         eor     r6, r6, r10; \
390         eor     r7, r7, r11; \
391         stmia   r0!, {r4-r7}; \
392         stmia   r12!, {r4-r7}; \
393
394
395 #define scrypt_core_macro2_x4() \
396         ldmia   r12, {r4-r7}; \
397         ldmia   r0, {r8-r11}; \
398         add     r4, r4, r8; \
399         add     r5, r5, r9; \
400         add     r6, r6, r10; \
401         add     r7, r7, r11; \
402         stmia   r0!, {r4-r7}; \
403         ldmia   r2, {r8-r11}; \
404         eor     r4, r4, r8; \
405         eor     r5, r5, r9; \
406         eor     r6, r6, r10; \
407         eor     r7, r7, r11; \
408         stmia   r2!, {r4-r7}; \
409         stmia   r12!, {r4-r7}; \
410
411
412 #define scrypt_core_macro3_x4() \
413         ldmia   r1!, {r4-r7}; \
414         ldmia   r0, {r8-r11}; \
415         add     r4, r4, r8; \
416         add     r5, r5, r9; \
417         add     r6, r6, r10; \
418         add     r7, r7, r11; \
419         stmia   r0!, {r4-r7}; \
420
421
422 #define scrypt_core_macro3_x6() \
423         ldmia   r1!, {r2-r7}; \
424         ldmia   r0, {r8-r12, lr}; \
425         add     r2, r2, r8; \
426         add     r3, r3, r9; \
427         add     r4, r4, r10; \
428         add     r5, r5, r11; \
429         add     r6, r6, r12; \
430         add     r7, r7, lr; \
431         stmia   r0!, {r2-r7}; \
432
433
434
435         .text
436         .code 32
437         .align 2
438         .globl scrypt_core
439         .globl _scrypt_core
440 #ifdef __ELF__
441         .type scrypt_core, %function
442 #endif
443 scrypt_core:
444 _scrypt_core:
445         stmfd   sp!, {r4-r11, lr}
446         mov     r12, sp
447         sub     sp, sp, #21*4
448         bic     sp, sp, #63
449         str     r12, [sp, #20*4]
450         
451         scrypt_shuffle()
452         
453         str     r0, [sp, #16*4]
454         add     r12, r1, #1024*32*4
455         str     r12, [sp, #18*4]
456 scrypt_core_loop1:
457         add     lr, r0, #16*4
458         add     r3, r1, #16*4
459         mov     r12, sp
460         scrypt_core_macro1a_x4()
461         scrypt_core_macro1a_x4()
462         scrypt_core_macro1a_x4()
463         scrypt_core_macro1a_x4()
464         str     r1, [sp, #17*4]
465         
466         salsa8_core()
467         
468         ldr     r0, [sp, #16*4]
469         mov     r12, sp
470         add     r2, r0, #16*4
471         scrypt_core_macro2_x4()
472         scrypt_core_macro2_x4()
473         scrypt_core_macro2_x4()
474         scrypt_core_macro2_x4()
475         
476         salsa8_core()
477         
478         ldr     r0, [sp, #16*4]
479         mov     r1, sp
480         add     r0, r0, #16*4
481         scrypt_core_macro3_x6()
482         scrypt_core_macro3_x6()
483         ldr     r3, [sp, #17*4]
484         ldr     r12, [sp, #18*4]
485         scrypt_core_macro3_x4()
486         
487         add     r1, r3, #16*4
488         sub     r0, r0, #32*4
489         cmp     r1, r12
490         bne     scrypt_core_loop1
491         
492         ldr     r4, [r0, #16*4]
493         sub     r1, r1, #1024*32*4
494         str     r1, [sp, #17*4]
495         mov     r4, r4, lsl #32-10
496         mov     r12, #1024
497         add     r1, r1, r4, lsr #32-10-7
498 scrypt_core_loop2:
499         add     r2, r0, #16*4
500         add     r3, r1, #16*4
501         str     r12, [sp, #18*4]
502         mov     r12, sp
503 #ifdef __ARM_ARCH_5E_OR_6_OR_7__
504         pld [r1, #24*4]
505         pld [r1, #8*4]
506 #endif
507         scrypt_core_macro1b_x4()
508         scrypt_core_macro1b_x4()
509         scrypt_core_macro1b_x4()
510         scrypt_core_macro1b_x4()
511         
512         salsa8_core()
513         
514         ldr     r0, [sp, #16*4]
515         mov     r12, sp
516         add     r2, r0, #16*4
517         scrypt_core_macro2_x4()
518         scrypt_core_macro2_x4()
519         scrypt_core_macro2_x4()
520         scrypt_core_macro2_x4()
521         
522         salsa8_core()
523         
524         ldr     r0, [sp, #16*4]
525         mov     r1, sp
526         ldr     r3, [sp, #17*4]
527         add     r0, r0, #16*4
528         scrypt_core_macro3_x4()
529         mov     r4, r4, lsl #32-10
530         add     r3, r3, r4, lsr #32-10-7
531         str     r3, [sp, #19*4]
532 #ifdef __ARM_ARCH_5E_OR_6_OR_7__
533         pld     [r3, #16*4]
534         pld     [r3]
535 #endif
536         scrypt_core_macro3_x6()
537         scrypt_core_macro3_x6()
538         
539         ldr     r12, [sp, #18*4]
540         sub     r0, r0, #32*4
541         ldr     r1, [sp, #19*4]
542         subs    r12, r12, #1
543         bne     scrypt_core_loop2
544         
545         scrypt_shuffle()
546         
547         ldr     sp, [sp, #20*4]
548 #ifdef __thumb__
549         ldmfd   sp!, {r4-r11, lr}
550         bx      lr
551 #else
552         ldmfd   sp!, {r4-r11, pc}
553 #endif
554
555 #endif