mpi/ec: fix when 'unsigned long' is 32-bit but limb size is 64-bit
[libgcrypt.git] / cipher / chacha20-armv7-neon.S
1 /* chacha20-armv7-neon.S - ARM/NEON accelerated chacha20 blocks function
2  *
3  * Copyright (C) 2014 Jussi Kivilinna <jussi.kivilinna@iki.fi>
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 /*
22  * Based on public domain implementation by Andrew Moon at
23  *  https://github.com/floodyberry/chacha-opt
24  */
25
26 #include <config.h>
27
28 #if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__) && \
29     defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
30     defined(HAVE_GCC_INLINE_ASM_NEON) && defined(USE_CHACHA20)
31
32 .syntax unified
33 .fpu neon
34 .arm
35
36 #define UNALIGNED_STMIA8(ptr, l0, l1, l2, l3, l4, l5, l6, l7) \
37         tst ptr, #3; \
38         beq 1f; \
39         vpush {d0-d3}; \
40         vmov s0, l0; \
41         vmov s1, l1; \
42         vmov s2, l2; \
43         vmov s3, l3; \
44         vmov s4, l4; \
45         vmov s5, l5; \
46         vmov s6, l6; \
47         vmov s7, l7; \
48         vst1.32 {d0-d3}, [ptr]; \
49         add ptr, #32; \
50         vpop {d0-d3}; \
51         b 2f; \
52      1: stmia ptr!, {l0-l7}; \
53      2: ;
54
55 #define UNALIGNED_LDMIA4(ptr, l0, l1, l2, l3) \
56         tst ptr, #3; \
57         beq 1f; \
58         vpush {d0-d1}; \
59         vld1.32 {d0-d1}, [ptr]; \
60         add ptr, #16; \
61         vmov l0, s0; \
62         vmov l1, s1; \
63         vmov l2, s2; \
64         vmov l3, s3; \
65         vpop {d0-d1}; \
66         b 2f; \
67      1: ldmia ptr!, {l0-l3}; \
68      2: ;
69
70 .text
71
72 .globl _gcry_chacha20_armv7_neon_blocks
73 .type  _gcry_chacha20_armv7_neon_blocks,%function;
74 _gcry_chacha20_armv7_neon_blocks:
75 .Lchacha_blocks_neon_local:
76         tst r3, r3
77         beq .Lchacha_blocks_neon_nobytes
78         vstmdb sp!, {q4,q5,q6,q7}
79         stmfd sp!, {r4-r12, r14}
80         mov r8, sp
81         sub sp, sp, #196
82         and sp, sp, #0xffffffe0
83         str r0, [sp, #60]
84         str r1, [sp, #48]
85         str r2, [sp, #40]
86         str r3, [sp, #52]
87         str r8, [sp, #192]
88         add r1, sp, #64
89         ldmia r0!, {r4-r11}
90         stmia r1!, {r4-r11}
91         ldmia r0!, {r4-r11}
92         stmia r1!, {r4-r11}
93         mov r4, #20
94         str r4, [sp, #44]
95         cmp r3, #256
96         blo .Lchacha_blocks_neon_mainloop2
97 .Lchacha_blocks_neon_mainloop1:
98         ldr r0, [sp, #44]
99         str r0, [sp, #0]
100         add r1, sp, #(64)
101         mov r2, #1
102         veor q12, q12
103         vld1.32 {q0,q1}, [r1,:128]!
104         vld1.32 {q2,q3}, [r1,:128]
105         vmov.32 d24[0], r2
106         vadd.u64 q3, q3, q12
107         vmov q4, q0
108         vmov q5, q1
109         vmov q6, q2
110         vadd.u64 q7, q3, q12
111         vmov q8, q0
112         vmov q9, q1
113         vmov q10, q2
114         vadd.u64 q11, q7, q12
115         add r0, sp, #64
116         ldm r0, {r0-r12}
117         ldr r14, [sp, #(64 +60)]
118         str r6, [sp, #8]
119         str r11, [sp, #12]
120         str r14, [sp, #28]
121         ldr r11, [sp, #(64 +52)]
122         ldr r14, [sp, #(64 +56)]
123 .Lchacha_blocks_neon_rounds1:
124         ldr r6, [sp, #0]
125         vadd.i32 q0, q0, q1
126         add r0, r0, r4
127         vadd.i32 q4, q4, q5
128         add r1, r1, r5
129         vadd.i32 q8, q8, q9
130         eor r12, r12, r0
131         veor q12, q3, q0
132         eor r11, r11, r1
133         veor q13, q7, q4
134         ror r12, r12, #16
135         veor q14, q11, q8
136         ror r11, r11, #16
137         vrev32.16 q3, q12
138         subs r6, r6, #2
139         vrev32.16 q7, q13
140         add r8, r8, r12
141         vrev32.16 q11, q14
142         add r9, r9, r11
143         vadd.i32 q2, q2, q3
144         eor r4, r4, r8
145         vadd.i32 q6, q6, q7
146         eor r5, r5, r9
147         vadd.i32 q10, q10, q11
148         str r6, [sp, #0]
149         veor q12, q1, q2
150         ror r4, r4, #20
151         veor q13, q5, q6
152         ror r5, r5, #20
153         veor q14, q9, q10
154         add r0, r0, r4
155         vshl.i32 q1, q12, #12
156         add r1, r1, r5
157         vshl.i32 q5, q13, #12
158         ldr r6, [sp, #8]
159         vshl.i32 q9, q14, #12
160         eor r12, r12, r0
161         vsri.u32 q1, q12, #20
162         eor r11, r11, r1
163         vsri.u32 q5, q13, #20
164         ror r12, r12, #24
165         vsri.u32 q9, q14, #20
166         ror r11, r11, #24
167         vadd.i32 q0, q0, q1
168         add r8, r8, r12
169         vadd.i32 q4, q4, q5
170         add r9, r9, r11
171         vadd.i32 q8, q8, q9
172         eor r4, r4, r8
173         veor q12, q3, q0
174         eor r5, r5, r9
175         veor q13, q7, q4
176         str r11, [sp, #20]
177         veor q14, q11, q8
178         ror r4, r4, #25
179         vshl.i32 q3, q12, #8
180         ror r5, r5, #25
181         vshl.i32 q7, q13, #8
182         str r4, [sp, #4]
183         vshl.i32 q11, q14, #8
184         ldr r4, [sp, #28]
185         vsri.u32 q3, q12, #24
186         add r2, r2, r6
187         vsri.u32 q7, q13, #24
188         add r3, r3, r7
189         vsri.u32 q11, q14, #24
190         ldr r11, [sp, #12]
191         vadd.i32 q2, q2, q3
192         eor r14, r14, r2
193         vadd.i32 q6, q6, q7
194         eor r4, r4, r3
195         vadd.i32 q10, q10, q11
196         ror r14, r14, #16
197         veor q12, q1, q2
198         ror r4, r4, #16
199         veor q13, q5, q6
200         add r10, r10, r14
201         veor q14, q9, q10
202         add r11, r11, r4
203         vshl.i32 q1, q12, #7
204         eor r6, r6, r10
205         vshl.i32 q5, q13, #7
206         eor r7, r7, r11
207         vshl.i32 q9, q14, #7
208         ror r6, r6, #20
209         vsri.u32 q1, q12, #25
210         ror r7, r7, #20
211         vsri.u32 q5, q13, #25
212         add r2, r2, r6
213         vsri.u32 q9, q14, #25
214         add r3, r3, r7
215         vext.32 q3, q3, q3, #3
216         eor r14, r14, r2
217         vext.32 q7, q7, q7, #3
218         eor r4, r4, r3
219         vext.32 q11, q11, q11, #3
220         ror r14, r14, #24
221         vext.32 q1, q1, q1, #1
222         ror r4, r4, #24
223         vext.32 q5, q5, q5, #1
224         add r10, r10, r14
225         vext.32 q9, q9, q9, #1
226         add r11, r11, r4
227         vext.32 q2, q2, q2, #2
228         eor r6, r6, r10
229         vext.32 q6, q6, q6, #2
230         eor r7, r7, r11
231         vext.32 q10, q10, q10, #2
232         ror r6, r6, #25
233         vadd.i32 q0, q0, q1
234         ror r7, r7, #25
235         vadd.i32 q4, q4, q5
236         add r0, r0, r5
237         vadd.i32 q8, q8, q9
238         add r1, r1, r6
239         veor q12, q3, q0
240         eor r4, r4, r0
241         veor q13, q7, q4
242         eor r12, r12, r1
243         veor q14, q11, q8
244         ror r4, r4, #16
245         vrev32.16 q3, q12
246         ror r12, r12, #16
247         vrev32.16 q7, q13
248         add r10, r10, r4
249         vrev32.16 q11, q14
250         add r11, r11, r12
251         vadd.i32 q2, q2, q3
252         eor r5, r5, r10
253         vadd.i32 q6, q6, q7
254         eor r6, r6, r11
255         vadd.i32 q10, q10, q11
256         ror r5, r5, #20
257         veor q12, q1, q2
258         ror r6, r6, #20
259         veor q13, q5, q6
260         add r0, r0, r5
261         veor q14, q9, q10
262         add r1, r1, r6
263         vshl.i32 q1, q12, #12
264         eor r4, r4, r0
265         vshl.i32 q5, q13, #12
266         eor r12, r12, r1
267         vshl.i32 q9, q14, #12
268         ror r4, r4, #24
269         vsri.u32 q1, q12, #20
270         ror r12, r12, #24
271         vsri.u32 q5, q13, #20
272         add r10, r10, r4
273         vsri.u32 q9, q14, #20
274         add r11, r11, r12
275         vadd.i32 q0, q0, q1
276         eor r5, r5, r10
277         vadd.i32 q4, q4, q5
278         eor r6, r6, r11
279         vadd.i32 q8, q8, q9
280         str r11, [sp, #12]
281         veor q12, q3, q0
282         ror r5, r5, #25
283         veor q13, q7, q4
284         ror r6, r6, #25
285         veor q14, q11, q8
286         str r4, [sp, #28]
287         vshl.i32 q3, q12, #8
288         ldr r4, [sp, #4]
289         vshl.i32 q7, q13, #8
290         add r2, r2, r7
291         vshl.i32 q11, q14, #8
292         add r3, r3, r4
293         vsri.u32 q3, q12, #24
294         ldr r11, [sp, #20]
295         vsri.u32 q7, q13, #24
296         eor r11, r11, r2
297         vsri.u32 q11, q14, #24
298         eor r14, r14, r3
299         vadd.i32 q2, q2, q3
300         ror r11, r11, #16
301         vadd.i32 q6, q6, q7
302         ror r14, r14, #16
303         vadd.i32 q10, q10, q11
304         add r8, r8, r11
305         veor q12, q1, q2
306         add r9, r9, r14
307         veor q13, q5, q6
308         eor r7, r7, r8
309         veor q14, q9, q10
310         eor r4, r4, r9
311         vshl.i32 q1, q12, #7
312         ror r7, r7, #20
313         vshl.i32 q5, q13, #7
314         ror r4, r4, #20
315         vshl.i32 q9, q14, #7
316         str r6, [sp, #8]
317         vsri.u32 q1, q12, #25
318         add r2, r2, r7
319         vsri.u32 q5, q13, #25
320         add r3, r3, r4
321         vsri.u32 q9, q14, #25
322         eor r11, r11, r2
323         vext.32 q3, q3, q3, #1
324         eor r14, r14, r3
325         vext.32 q7, q7, q7, #1
326         ror r11, r11, #24
327         vext.32 q11, q11, q11, #1
328         ror r14, r14, #24
329         vext.32 q1, q1, q1, #3
330         add r8, r8, r11
331         vext.32 q5, q5, q5, #3
332         add r9, r9, r14
333         vext.32 q9, q9, q9, #3
334         eor r7, r7, r8
335         vext.32 q2, q2, q2, #2
336         eor r4, r4, r9
337         vext.32 q6, q6, q6, #2
338         ror r7, r7, #25
339         vext.32 q10, q10, q10, #2
340         ror r4, r4, #25
341         bne .Lchacha_blocks_neon_rounds1
342         str r8, [sp, #0]
343         str r9, [sp, #4]
344         str r10, [sp, #8]
345         str r12, [sp, #16]
346         str r11, [sp, #20]
347         str r14, [sp, #24]
348         add r9, sp, #64
349         vld1.32 {q12,q13}, [r9,:128]!
350         ldr r12, [sp, #48]
351         vld1.32 {q14,q15}, [r9,:128]
352         ldr r14, [sp, #40]
353         vadd.i32 q0, q0, q12
354         ldr r8, [sp, #(64 +0)]
355         vadd.i32 q4, q4, q12
356         ldr r9, [sp, #(64 +4)]
357         vadd.i32 q8, q8, q12
358         ldr r10, [sp, #(64 +8)]
359         vadd.i32 q1, q1, q13
360         ldr r11, [sp, #(64 +12)]
361         vadd.i32 q5, q5, q13
362         add r0, r0, r8
363         vadd.i32 q9, q9, q13
364         add r1, r1, r9
365         vadd.i32 q2, q2, q14
366         add r2, r2, r10
367         vadd.i32 q6, q6, q14
368         ldr r8, [sp, #(64 +16)]
369         vadd.i32 q10, q10, q14
370         add r3, r3, r11
371         veor q14, q14, q14
372         ldr r9, [sp, #(64 +20)]
373         mov r11, #1
374         add r4, r4, r8
375         vmov.32 d28[0], r11
376         ldr r10, [sp, #(64 +24)]
377         vadd.u64 q12, q14, q15
378         add r5, r5, r9
379         vadd.u64 q13, q14, q12
380         ldr r11, [sp, #(64 +28)]
381         vadd.u64 q14, q14, q13
382         add r6, r6, r10
383         vadd.i32 q3, q3, q12
384         tst r12, r12
385         vadd.i32 q7, q7, q13
386         add r7, r7, r11
387         vadd.i32 q11, q11, q14
388         beq .Lchacha_blocks_neon_nomessage11
389         UNALIGNED_LDMIA4(r12, r8, r9, r10, r11)
390         tst r12, r12
391         eor r0, r0, r8
392         eor r1, r1, r9
393         eor r2, r2, r10
394         ldr r8, [r12, #0]
395         eor r3, r3, r11
396         ldr r9, [r12, #4]
397         eor r4, r4, r8
398         ldr r10, [r12, #8]
399         eor r5, r5, r9
400         ldr r11, [r12, #12]
401         eor r6, r6, r10
402         add r12, r12, #16
403         eor r7, r7, r11
404 .Lchacha_blocks_neon_nomessage11:
405         UNALIGNED_STMIA8(r14, r0, r1, r2, r3, r4, r5, r6, r7)
406         tst r12, r12
407         ldm sp, {r0-r7}
408         ldr r8, [sp, #(64 +32)]
409         ldr r9, [sp, #(64 +36)]
410         ldr r10, [sp, #(64 +40)]
411         ldr r11, [sp, #(64 +44)]
412         add r0, r0, r8
413         add r1, r1, r9
414         add r2, r2, r10
415         ldr r8, [sp, #(64 +48)]
416         add r3, r3, r11
417         ldr r9, [sp, #(64 +52)]
418         add r4, r4, r8
419         ldr r10, [sp, #(64 +56)]
420         add r5, r5, r9
421         ldr r11, [sp, #(64 +60)]
422         add r6, r6, r10
423         adds r8, r8, #4
424         add r7, r7, r11
425         adc r9, r9, #0
426         str r8, [sp, #(64 +48)]
427         tst r12, r12
428         str r9, [sp, #(64 +52)]
429         beq .Lchacha_blocks_neon_nomessage12
430         UNALIGNED_LDMIA4(r12, r8, r9, r10, r11)
431         tst r12, r12
432         eor r0, r0, r8
433         eor r1, r1, r9
434         eor r2, r2, r10
435         ldr r8, [r12, #0]
436         eor r3, r3, r11
437         ldr r9, [r12, #4]
438         eor r4, r4, r8
439         ldr r10, [r12, #8]
440         eor r5, r5, r9
441         ldr r11, [r12, #12]
442         eor r6, r6, r10
443         add r12, r12, #16
444         eor r7, r7, r11
445 .Lchacha_blocks_neon_nomessage12:
446         UNALIGNED_STMIA8(r14, r0, r1, r2, r3, r4, r5, r6, r7)
447         tst r12, r12
448         beq .Lchacha_blocks_neon_nomessage13
449         vld1.32 {q12,q13}, [r12]!
450         vld1.32 {q14,q15}, [r12]!
451         veor q0, q0, q12
452         veor q1, q1, q13
453         veor q2, q2, q14
454         veor q3, q3, q15
455 .Lchacha_blocks_neon_nomessage13:
456         vst1.32 {q0,q1}, [r14]!
457         vst1.32 {q2,q3}, [r14]!
458         beq .Lchacha_blocks_neon_nomessage14
459         vld1.32 {q12,q13}, [r12]!
460         vld1.32 {q14,q15}, [r12]!
461         veor q4, q4, q12
462         veor q5, q5, q13
463         veor q6, q6, q14
464         veor q7, q7, q15
465 .Lchacha_blocks_neon_nomessage14:
466         vst1.32 {q4,q5}, [r14]!
467         vst1.32 {q6,q7}, [r14]!
468         beq .Lchacha_blocks_neon_nomessage15
469         vld1.32 {q12,q13}, [r12]!
470         vld1.32 {q14,q15}, [r12]!
471         veor q8, q8, q12
472         veor q9, q9, q13
473         veor q10, q10, q14
474         veor q11, q11, q15
475 .Lchacha_blocks_neon_nomessage15:
476         vst1.32 {q8,q9}, [r14]!
477         vst1.32 {q10,q11}, [r14]!
478         str r12, [sp, #48]
479         str r14, [sp, #40]
480         ldr r3, [sp, #52]
481         sub r3, r3, #256
482         cmp r3, #256
483         str r3, [sp, #52]
484         bhs .Lchacha_blocks_neon_mainloop1
485         tst r3, r3
486         beq .Lchacha_blocks_neon_done
487 .Lchacha_blocks_neon_mainloop2:
488         ldr r3, [sp, #52]
489         ldr r1, [sp, #48]
490         cmp r3, #64
491         bhs .Lchacha_blocks_neon_noswap1
492         add r4, sp, #128
493         mov r5, r4
494         tst r1, r1
495         beq .Lchacha_blocks_neon_nocopy1
496 .Lchacha_blocks_neon_copyinput1:
497         subs r3, r3, #1
498         ldrb r0, [r1], #1
499         strb r0, [r4], #1
500         bne .Lchacha_blocks_neon_copyinput1
501         str r5, [sp, #48]
502 .Lchacha_blocks_neon_nocopy1:
503         ldr r4, [sp, #40]
504         str r5, [sp, #40]
505         str r4, [sp, #56]
506 .Lchacha_blocks_neon_noswap1:
507         ldr r0, [sp, #44]
508         str r0, [sp, #0]
509         add r0, sp, #64
510         ldm r0, {r0-r12}
511         ldr r14, [sp, #(64 +60)]
512         str r6, [sp, #8]
513         str r11, [sp, #12]
514         str r14, [sp, #28]
515         ldr r11, [sp, #(64 +52)]
516         ldr r14, [sp, #(64 +56)]
517 .Lchacha_blocks_neon_rounds2:
518         ldr r6, [sp, #0]
519         add r0, r0, r4
520         add r1, r1, r5
521         eor r12, r12, r0
522         eor r11, r11, r1
523         ror r12, r12, #16
524         ror r11, r11, #16
525         subs r6, r6, #2
526         add r8, r8, r12
527         add r9, r9, r11
528         eor r4, r4, r8
529         eor r5, r5, r9
530         str r6, [sp, #0]
531         ror r4, r4, #20
532         ror r5, r5, #20
533         add r0, r0, r4
534         add r1, r1, r5
535         ldr r6, [sp, #8]
536         eor r12, r12, r0
537         eor r11, r11, r1
538         ror r12, r12, #24
539         ror r11, r11, #24
540         add r8, r8, r12
541         add r9, r9, r11
542         eor r4, r4, r8
543         eor r5, r5, r9
544         str r11, [sp, #20]
545         ror r4, r4, #25
546         ror r5, r5, #25
547         str r4, [sp, #4]
548         ldr r4, [sp, #28]
549         add r2, r2, r6
550         add r3, r3, r7
551         ldr r11, [sp, #12]
552         eor r14, r14, r2
553         eor r4, r4, r3
554         ror r14, r14, #16
555         ror r4, r4, #16
556         add r10, r10, r14
557         add r11, r11, r4
558         eor r6, r6, r10
559         eor r7, r7, r11
560         ror r6, r6, #20
561         ror r7, r7, #20
562         add r2, r2, r6
563         add r3, r3, r7
564         eor r14, r14, r2
565         eor r4, r4, r3
566         ror r14, r14, #24
567         ror r4, r4, #24
568         add r10, r10, r14
569         add r11, r11, r4
570         eor r6, r6, r10
571         eor r7, r7, r11
572         ror r6, r6, #25
573         ror r7, r7, #25
574         add r0, r0, r5
575         add r1, r1, r6
576         eor r4, r4, r0
577         eor r12, r12, r1
578         ror r4, r4, #16
579         ror r12, r12, #16
580         add r10, r10, r4
581         add r11, r11, r12
582         eor r5, r5, r10
583         eor r6, r6, r11
584         ror r5, r5, #20
585         ror r6, r6, #20
586         add r0, r0, r5
587         add r1, r1, r6
588         eor r4, r4, r0
589         eor r12, r12, r1
590         ror r4, r4, #24
591         ror r12, r12, #24
592         add r10, r10, r4
593         add r11, r11, r12
594         eor r5, r5, r10
595         eor r6, r6, r11
596         str r11, [sp, #12]
597         ror r5, r5, #25
598         ror r6, r6, #25
599         str r4, [sp, #28]
600         ldr r4, [sp, #4]
601         add r2, r2, r7
602         add r3, r3, r4
603         ldr r11, [sp, #20]
604         eor r11, r11, r2
605         eor r14, r14, r3
606         ror r11, r11, #16
607         ror r14, r14, #16
608         add r8, r8, r11
609         add r9, r9, r14
610         eor r7, r7, r8
611         eor r4, r4, r9
612         ror r7, r7, #20
613         ror r4, r4, #20
614         str r6, [sp, #8]
615         add r2, r2, r7
616         add r3, r3, r4
617         eor r11, r11, r2
618         eor r14, r14, r3
619         ror r11, r11, #24
620         ror r14, r14, #24
621         add r8, r8, r11
622         add r9, r9, r14
623         eor r7, r7, r8
624         eor r4, r4, r9
625         ror r7, r7, #25
626         ror r4, r4, #25
627         bne .Lchacha_blocks_neon_rounds2
628         str r8, [sp, #0]
629         str r9, [sp, #4]
630         str r10, [sp, #8]
631         str r12, [sp, #16]
632         str r11, [sp, #20]
633         str r14, [sp, #24]
634         ldr r12, [sp, #48]
635         ldr r14, [sp, #40]
636         ldr r8, [sp, #(64 +0)]
637         ldr r9, [sp, #(64 +4)]
638         ldr r10, [sp, #(64 +8)]
639         ldr r11, [sp, #(64 +12)]
640         add r0, r0, r8
641         add r1, r1, r9
642         add r2, r2, r10
643         ldr r8, [sp, #(64 +16)]
644         add r3, r3, r11
645         ldr r9, [sp, #(64 +20)]
646         add r4, r4, r8
647         ldr r10, [sp, #(64 +24)]
648         add r5, r5, r9
649         ldr r11, [sp, #(64 +28)]
650         add r6, r6, r10
651         tst r12, r12
652         add r7, r7, r11
653         beq .Lchacha_blocks_neon_nomessage21
654         UNALIGNED_LDMIA4(r12, r8, r9, r10, r11)
655         tst r12, r12
656         eor r0, r0, r8
657         eor r1, r1, r9
658         eor r2, r2, r10
659         ldr r8, [r12, #0]
660         eor r3, r3, r11
661         ldr r9, [r12, #4]
662         eor r4, r4, r8
663         ldr r10, [r12, #8]
664         eor r5, r5, r9
665         ldr r11, [r12, #12]
666         eor r6, r6, r10
667         add r12, r12, #16
668         eor r7, r7, r11
669 .Lchacha_blocks_neon_nomessage21:
670         UNALIGNED_STMIA8(r14, r0, r1, r2, r3, r4, r5, r6, r7)
671         ldm sp, {r0-r7}
672         ldr r8, [sp, #(64 +32)]
673         ldr r9, [sp, #(64 +36)]
674         ldr r10, [sp, #(64 +40)]
675         ldr r11, [sp, #(64 +44)]
676         add r0, r0, r8
677         add r1, r1, r9
678         add r2, r2, r10
679         ldr r8, [sp, #(64 +48)]
680         add r3, r3, r11
681         ldr r9, [sp, #(64 +52)]
682         add r4, r4, r8
683         ldr r10, [sp, #(64 +56)]
684         add r5, r5, r9
685         ldr r11, [sp, #(64 +60)]
686         add r6, r6, r10
687         adds r8, r8, #1
688         add r7, r7, r11
689         adc r9, r9, #0
690         str r8, [sp, #(64 +48)]
691         tst r12, r12
692         str r9, [sp, #(64 +52)]
693         beq .Lchacha_blocks_neon_nomessage22
694         UNALIGNED_LDMIA4(r12, r8, r9, r10, r11)
695         tst r12, r12
696         eor r0, r0, r8
697         eor r1, r1, r9
698         eor r2, r2, r10
699         ldr r8, [r12, #0]
700         eor r3, r3, r11
701         ldr r9, [r12, #4]
702         eor r4, r4, r8
703         ldr r10, [r12, #8]
704         eor r5, r5, r9
705         ldr r11, [r12, #12]
706         eor r6, r6, r10
707         add r12, r12, #16
708         eor r7, r7, r11
709 .Lchacha_blocks_neon_nomessage22:
710         UNALIGNED_STMIA8(r14, r0, r1, r2, r3, r4, r5, r6, r7)
711         str r12, [sp, #48]
712         str r14, [sp, #40]
713         ldr r3, [sp, #52]
714         cmp r3, #64
715         sub r4, r3, #64
716         str r4, [sp, #52]
717         bhi .Lchacha_blocks_neon_mainloop2
718         cmp r3, #64
719         beq .Lchacha_blocks_neon_nocopy2
720         ldr r1, [sp, #56]
721         sub r14, r14, #64
722 .Lchacha_blocks_neon_copyinput2:
723         subs r3, r3, #1
724         ldrb r0, [r14], #1
725         strb r0, [r1], #1
726         bne .Lchacha_blocks_neon_copyinput2
727 .Lchacha_blocks_neon_nocopy2:
728 .Lchacha_blocks_neon_done:
729         ldr r7, [sp, #60]
730         ldr r8, [sp, #(64 +48)]
731         ldr r9, [sp, #(64 +52)]
732         str r8, [r7, #(48 + 0)]
733         str r9, [r7, #(48 + 4)]
734         mov r12, sp
735         stmia r12!, {r0-r7}
736         add r12, r12, #48
737         stmia r12!, {r0-r7}
738         sub r0, sp, #8
739         ldr sp, [sp, #192]
740         ldmfd sp!, {r4-r12, r14}
741         vldm sp!, {q4-q7}
742         sub r0, sp, r0
743         bx lr
744 .Lchacha_blocks_neon_nobytes:
745         mov r0, #0;
746         bx lr
747 .ltorg
748 .size _gcry_chacha20_armv7_neon_blocks,.-_gcry_chacha20_armv7_neon_blocks;
749
750 #endif