doc: Fix typo.
[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 .text
37
38 .globl _gcry_chacha20_armv7_neon_blocks
39 .type  _gcry_chacha20_armv7_neon_blocks,%function;
40 _gcry_chacha20_armv7_neon_blocks:
41 .Lchacha_blocks_neon_local:
42         tst r3, r3
43         beq .Lchacha_blocks_neon_nobytes
44         vstmdb sp!, {q4,q5,q6,q7}
45         stmfd sp!, {r4-r12, r14}
46         mov r8, sp
47         sub sp, sp, #196
48         and sp, sp, #0xffffffe0
49         str r0, [sp, #60]
50         str r1, [sp, #48]
51         str r2, [sp, #40]
52         str r3, [sp, #52]
53         str r8, [sp, #192]
54         add r1, sp, #64
55         ldmia r0!, {r4-r11}
56         stmia r1!, {r4-r11}
57         ldmia r0!, {r4-r11}
58         stmia r1!, {r4-r11}
59         mov r4, #20
60         str r4, [sp, #44]
61         cmp r3, #256
62         blo .Lchacha_blocks_neon_mainloop2
63 .Lchacha_blocks_neon_mainloop1:
64         ldr r0, [sp, #44]
65         str r0, [sp, #0]
66         add r1, sp, #(64)
67         mov r2, #1
68         veor q12, q12
69         vld1.32 {q0,q1}, [r1,:128]!
70         vld1.32 {q2,q3}, [r1,:128]
71         vmov.32 d24[0], r2
72         vadd.u64 q3, q3, q12
73         vmov q4, q0
74         vmov q5, q1
75         vmov q6, q2
76         vadd.u64 q7, q3, q12
77         vmov q8, q0
78         vmov q9, q1
79         vmov q10, q2
80         vadd.u64 q11, q7, q12
81         add r0, sp, #64
82         ldm r0, {r0-r12}
83         ldr r14, [sp, #(64 +60)]
84         str r6, [sp, #8]
85         str r11, [sp, #12]
86         str r14, [sp, #28]
87         ldr r11, [sp, #(64 +52)]
88         ldr r14, [sp, #(64 +56)]
89 .Lchacha_blocks_neon_rounds1:
90         ldr r6, [sp, #0]
91         vadd.i32 q0, q0, q1
92         add r0, r0, r4
93         vadd.i32 q4, q4, q5
94         add r1, r1, r5
95         vadd.i32 q8, q8, q9
96         eor r12, r12, r0
97         veor q12, q3, q0
98         eor r11, r11, r1
99         veor q13, q7, q4
100         ror r12, r12, #16
101         veor q14, q11, q8
102         ror r11, r11, #16
103         vrev32.16 q3, q12
104         subs r6, r6, #2
105         vrev32.16 q7, q13
106         add r8, r8, r12
107         vrev32.16 q11, q14
108         add r9, r9, r11
109         vadd.i32 q2, q2, q3
110         eor r4, r4, r8
111         vadd.i32 q6, q6, q7
112         eor r5, r5, r9
113         vadd.i32 q10, q10, q11
114         str r6, [sp, #0]
115         veor q12, q1, q2
116         ror r4, r4, #20
117         veor q13, q5, q6
118         ror r5, r5, #20
119         veor q14, q9, q10
120         add r0, r0, r4
121         vshl.i32 q1, q12, #12
122         add r1, r1, r5
123         vshl.i32 q5, q13, #12
124         ldr r6, [sp, #8]
125         vshl.i32 q9, q14, #12
126         eor r12, r12, r0
127         vsri.u32 q1, q12, #20
128         eor r11, r11, r1
129         vsri.u32 q5, q13, #20
130         ror r12, r12, #24
131         vsri.u32 q9, q14, #20
132         ror r11, r11, #24
133         vadd.i32 q0, q0, q1
134         add r8, r8, r12
135         vadd.i32 q4, q4, q5
136         add r9, r9, r11
137         vadd.i32 q8, q8, q9
138         eor r4, r4, r8
139         veor q12, q3, q0
140         eor r5, r5, r9
141         veor q13, q7, q4
142         str r11, [sp, #20]
143         veor q14, q11, q8
144         ror r4, r4, #25
145         vshl.i32 q3, q12, #8
146         ror r5, r5, #25
147         vshl.i32 q7, q13, #8
148         str r4, [sp, #4]
149         vshl.i32 q11, q14, #8
150         ldr r4, [sp, #28]
151         vsri.u32 q3, q12, #24
152         add r2, r2, r6
153         vsri.u32 q7, q13, #24
154         add r3, r3, r7
155         vsri.u32 q11, q14, #24
156         ldr r11, [sp, #12]
157         vadd.i32 q2, q2, q3
158         eor r14, r14, r2
159         vadd.i32 q6, q6, q7
160         eor r4, r4, r3
161         vadd.i32 q10, q10, q11
162         ror r14, r14, #16
163         veor q12, q1, q2
164         ror r4, r4, #16
165         veor q13, q5, q6
166         add r10, r10, r14
167         veor q14, q9, q10
168         add r11, r11, r4
169         vshl.i32 q1, q12, #7
170         eor r6, r6, r10
171         vshl.i32 q5, q13, #7
172         eor r7, r7, r11
173         vshl.i32 q9, q14, #7
174         ror r6, r6, #20
175         vsri.u32 q1, q12, #25
176         ror r7, r7, #20
177         vsri.u32 q5, q13, #25
178         add r2, r2, r6
179         vsri.u32 q9, q14, #25
180         add r3, r3, r7
181         vext.32 q3, q3, q3, #3
182         eor r14, r14, r2
183         vext.32 q7, q7, q7, #3
184         eor r4, r4, r3
185         vext.32 q11, q11, q11, #3
186         ror r14, r14, #24
187         vext.32 q1, q1, q1, #1
188         ror r4, r4, #24
189         vext.32 q5, q5, q5, #1
190         add r10, r10, r14
191         vext.32 q9, q9, q9, #1
192         add r11, r11, r4
193         vext.32 q2, q2, q2, #2
194         eor r6, r6, r10
195         vext.32 q6, q6, q6, #2
196         eor r7, r7, r11
197         vext.32 q10, q10, q10, #2
198         ror r6, r6, #25
199         vadd.i32 q0, q0, q1
200         ror r7, r7, #25
201         vadd.i32 q4, q4, q5
202         add r0, r0, r5
203         vadd.i32 q8, q8, q9
204         add r1, r1, r6
205         veor q12, q3, q0
206         eor r4, r4, r0
207         veor q13, q7, q4
208         eor r12, r12, r1
209         veor q14, q11, q8
210         ror r4, r4, #16
211         vrev32.16 q3, q12
212         ror r12, r12, #16
213         vrev32.16 q7, q13
214         add r10, r10, r4
215         vrev32.16 q11, q14
216         add r11, r11, r12
217         vadd.i32 q2, q2, q3
218         eor r5, r5, r10
219         vadd.i32 q6, q6, q7
220         eor r6, r6, r11
221         vadd.i32 q10, q10, q11
222         ror r5, r5, #20
223         veor q12, q1, q2
224         ror r6, r6, #20
225         veor q13, q5, q6
226         add r0, r0, r5
227         veor q14, q9, q10
228         add r1, r1, r6
229         vshl.i32 q1, q12, #12
230         eor r4, r4, r0
231         vshl.i32 q5, q13, #12
232         eor r12, r12, r1
233         vshl.i32 q9, q14, #12
234         ror r4, r4, #24
235         vsri.u32 q1, q12, #20
236         ror r12, r12, #24
237         vsri.u32 q5, q13, #20
238         add r10, r10, r4
239         vsri.u32 q9, q14, #20
240         add r11, r11, r12
241         vadd.i32 q0, q0, q1
242         eor r5, r5, r10
243         vadd.i32 q4, q4, q5
244         eor r6, r6, r11
245         vadd.i32 q8, q8, q9
246         str r11, [sp, #12]
247         veor q12, q3, q0
248         ror r5, r5, #25
249         veor q13, q7, q4
250         ror r6, r6, #25
251         veor q14, q11, q8
252         str r4, [sp, #28]
253         vshl.i32 q3, q12, #8
254         ldr r4, [sp, #4]
255         vshl.i32 q7, q13, #8
256         add r2, r2, r7
257         vshl.i32 q11, q14, #8
258         add r3, r3, r4
259         vsri.u32 q3, q12, #24
260         ldr r11, [sp, #20]
261         vsri.u32 q7, q13, #24
262         eor r11, r11, r2
263         vsri.u32 q11, q14, #24
264         eor r14, r14, r3
265         vadd.i32 q2, q2, q3
266         ror r11, r11, #16
267         vadd.i32 q6, q6, q7
268         ror r14, r14, #16
269         vadd.i32 q10, q10, q11
270         add r8, r8, r11
271         veor q12, q1, q2
272         add r9, r9, r14
273         veor q13, q5, q6
274         eor r7, r7, r8
275         veor q14, q9, q10
276         eor r4, r4, r9
277         vshl.i32 q1, q12, #7
278         ror r7, r7, #20
279         vshl.i32 q5, q13, #7
280         ror r4, r4, #20
281         vshl.i32 q9, q14, #7
282         str r6, [sp, #8]
283         vsri.u32 q1, q12, #25
284         add r2, r2, r7
285         vsri.u32 q5, q13, #25
286         add r3, r3, r4
287         vsri.u32 q9, q14, #25
288         eor r11, r11, r2
289         vext.32 q3, q3, q3, #1
290         eor r14, r14, r3
291         vext.32 q7, q7, q7, #1
292         ror r11, r11, #24
293         vext.32 q11, q11, q11, #1
294         ror r14, r14, #24
295         vext.32 q1, q1, q1, #3
296         add r8, r8, r11
297         vext.32 q5, q5, q5, #3
298         add r9, r9, r14
299         vext.32 q9, q9, q9, #3
300         eor r7, r7, r8
301         vext.32 q2, q2, q2, #2
302         eor r4, r4, r9
303         vext.32 q6, q6, q6, #2
304         ror r7, r7, #25
305         vext.32 q10, q10, q10, #2
306         ror r4, r4, #25
307         bne .Lchacha_blocks_neon_rounds1
308         str r8, [sp, #0]
309         str r9, [sp, #4]
310         str r10, [sp, #8]
311         str r12, [sp, #16]
312         str r11, [sp, #20]
313         str r14, [sp, #24]
314         add r9, sp, #64
315         vld1.32 {q12,q13}, [r9,:128]!
316         ldr r12, [sp, #48]
317         vld1.32 {q14,q15}, [r9,:128]
318         ldr r14, [sp, #40]
319         vadd.i32 q0, q0, q12
320         ldr r8, [sp, #(64 +0)]
321         vadd.i32 q4, q4, q12
322         ldr r9, [sp, #(64 +4)]
323         vadd.i32 q8, q8, q12
324         ldr r10, [sp, #(64 +8)]
325         vadd.i32 q1, q1, q13
326         ldr r11, [sp, #(64 +12)]
327         vadd.i32 q5, q5, q13
328         add r0, r0, r8
329         vadd.i32 q9, q9, q13
330         add r1, r1, r9
331         vadd.i32 q2, q2, q14
332         add r2, r2, r10
333         vadd.i32 q6, q6, q14
334         ldr r8, [sp, #(64 +16)]
335         vadd.i32 q10, q10, q14
336         add r3, r3, r11
337         veor q14, q14, q14
338         ldr r9, [sp, #(64 +20)]
339         mov r11, #1
340         add r4, r4, r8
341         vmov.32 d28[0], r11
342         ldr r10, [sp, #(64 +24)]
343         vadd.u64 q12, q14, q15
344         add r5, r5, r9
345         vadd.u64 q13, q14, q12
346         ldr r11, [sp, #(64 +28)]
347         vadd.u64 q14, q14, q13
348         add r6, r6, r10
349         vadd.i32 q3, q3, q12
350         tst r12, r12
351         vadd.i32 q7, q7, q13
352         add r7, r7, r11
353         vadd.i32 q11, q11, q14
354         beq .Lchacha_blocks_neon_nomessage11
355         ldmia r12!, {r8-r11}
356         eor r0, r0, r8
357         eor r1, r1, r9
358         eor r2, r2, r10
359         ldr r8, [r12, #0]
360         eor r3, r3, r11
361         ldr r9, [r12, #4]
362         eor r4, r4, r8
363         ldr r10, [r12, #8]
364         eor r5, r5, r9
365         ldr r11, [r12, #12]
366         eor r6, r6, r10
367         add r12, r12, #16
368         eor r7, r7, r11
369 .Lchacha_blocks_neon_nomessage11:
370         stmia r14!, {r0-r7}
371         ldm sp, {r0-r7}
372         ldr r8, [sp, #(64 +32)]
373         ldr r9, [sp, #(64 +36)]
374         ldr r10, [sp, #(64 +40)]
375         ldr r11, [sp, #(64 +44)]
376         add r0, r0, r8
377         add r1, r1, r9
378         add r2, r2, r10
379         ldr r8, [sp, #(64 +48)]
380         add r3, r3, r11
381         ldr r9, [sp, #(64 +52)]
382         add r4, r4, r8
383         ldr r10, [sp, #(64 +56)]
384         add r5, r5, r9
385         ldr r11, [sp, #(64 +60)]
386         add r6, r6, r10
387         adds r8, r8, #4
388         add r7, r7, r11
389         adc r9, r9, #0
390         str r8, [sp, #(64 +48)]
391         tst r12, r12
392         str r9, [sp, #(64 +52)]
393         beq .Lchacha_blocks_neon_nomessage12
394         ldmia r12!, {r8-r11}
395         eor r0, r0, r8
396         eor r1, r1, r9
397         eor r2, r2, r10
398         ldr r8, [r12, #0]
399         eor r3, r3, r11
400         ldr r9, [r12, #4]
401         eor r4, r4, r8
402         ldr r10, [r12, #8]
403         eor r5, r5, r9
404         ldr r11, [r12, #12]
405         eor r6, r6, r10
406         add r12, r12, #16
407         eor r7, r7, r11
408 .Lchacha_blocks_neon_nomessage12:
409         stmia r14!, {r0-r7}
410         beq .Lchacha_blocks_neon_nomessage13
411         vld1.32 {q12,q13}, [r12]!
412         vld1.32 {q14,q15}, [r12]!
413         veor q0, q0, q12
414         veor q1, q1, q13
415         veor q2, q2, q14
416         veor q3, q3, q15
417 .Lchacha_blocks_neon_nomessage13:
418         vst1.32 {q0,q1}, [r14]!
419         vst1.32 {q2,q3}, [r14]!
420         beq .Lchacha_blocks_neon_nomessage14
421         vld1.32 {q12,q13}, [r12]!
422         vld1.32 {q14,q15}, [r12]!
423         veor q4, q4, q12
424         veor q5, q5, q13
425         veor q6, q6, q14
426         veor q7, q7, q15
427 .Lchacha_blocks_neon_nomessage14:
428         vst1.32 {q4,q5}, [r14]!
429         vst1.32 {q6,q7}, [r14]!
430         beq .Lchacha_blocks_neon_nomessage15
431         vld1.32 {q12,q13}, [r12]!
432         vld1.32 {q14,q15}, [r12]!
433         veor q8, q8, q12
434         veor q9, q9, q13
435         veor q10, q10, q14
436         veor q11, q11, q15
437 .Lchacha_blocks_neon_nomessage15:
438         vst1.32 {q8,q9}, [r14]!
439         vst1.32 {q10,q11}, [r14]!
440         str r12, [sp, #48]
441         str r14, [sp, #40]
442         ldr r3, [sp, #52]
443         sub r3, r3, #256
444         cmp r3, #256
445         str r3, [sp, #52]
446         bhs .Lchacha_blocks_neon_mainloop1
447         tst r3, r3
448         beq .Lchacha_blocks_neon_done
449 .Lchacha_blocks_neon_mainloop2:
450         ldr r3, [sp, #52]
451         ldr r1, [sp, #48]
452         cmp r3, #64
453         bhs .Lchacha_blocks_neon_noswap1
454         add r4, sp, #128
455         mov r5, r4
456         tst r1, r1
457         beq .Lchacha_blocks_neon_nocopy1
458 .Lchacha_blocks_neon_copyinput1:
459         subs r3, r3, #1
460         ldrb r0, [r1], #1
461         strb r0, [r4], #1
462         bne .Lchacha_blocks_neon_copyinput1
463         str r5, [sp, #48]
464 .Lchacha_blocks_neon_nocopy1:
465         ldr r4, [sp, #40]
466         str r5, [sp, #40]
467         str r4, [sp, #56]
468 .Lchacha_blocks_neon_noswap1:
469         ldr r0, [sp, #44]
470         str r0, [sp, #0]
471         add r0, sp, #64
472         ldm r0, {r0-r12}
473         ldr r14, [sp, #(64 +60)]
474         str r6, [sp, #8]
475         str r11, [sp, #12]
476         str r14, [sp, #28]
477         ldr r11, [sp, #(64 +52)]
478         ldr r14, [sp, #(64 +56)]
479 .Lchacha_blocks_neon_rounds2:
480         ldr r6, [sp, #0]
481         add r0, r0, r4
482         add r1, r1, r5
483         eor r12, r12, r0
484         eor r11, r11, r1
485         ror r12, r12, #16
486         ror r11, r11, #16
487         subs r6, r6, #2
488         add r8, r8, r12
489         add r9, r9, r11
490         eor r4, r4, r8
491         eor r5, r5, r9
492         str r6, [sp, #0]
493         ror r4, r4, #20
494         ror r5, r5, #20
495         add r0, r0, r4
496         add r1, r1, r5
497         ldr r6, [sp, #8]
498         eor r12, r12, r0
499         eor r11, r11, r1
500         ror r12, r12, #24
501         ror r11, r11, #24
502         add r8, r8, r12
503         add r9, r9, r11
504         eor r4, r4, r8
505         eor r5, r5, r9
506         str r11, [sp, #20]
507         ror r4, r4, #25
508         ror r5, r5, #25
509         str r4, [sp, #4]
510         ldr r4, [sp, #28]
511         add r2, r2, r6
512         add r3, r3, r7
513         ldr r11, [sp, #12]
514         eor r14, r14, r2
515         eor r4, r4, r3
516         ror r14, r14, #16
517         ror r4, r4, #16
518         add r10, r10, r14
519         add r11, r11, r4
520         eor r6, r6, r10
521         eor r7, r7, r11
522         ror r6, r6, #20
523         ror r7, r7, #20
524         add r2, r2, r6
525         add r3, r3, r7
526         eor r14, r14, r2
527         eor r4, r4, r3
528         ror r14, r14, #24
529         ror r4, r4, #24
530         add r10, r10, r14
531         add r11, r11, r4
532         eor r6, r6, r10
533         eor r7, r7, r11
534         ror r6, r6, #25
535         ror r7, r7, #25
536         add r0, r0, r5
537         add r1, r1, r6
538         eor r4, r4, r0
539         eor r12, r12, r1
540         ror r4, r4, #16
541         ror r12, r12, #16
542         add r10, r10, r4
543         add r11, r11, r12
544         eor r5, r5, r10
545         eor r6, r6, r11
546         ror r5, r5, #20
547         ror r6, r6, #20
548         add r0, r0, r5
549         add r1, r1, r6
550         eor r4, r4, r0
551         eor r12, r12, r1
552         ror r4, r4, #24
553         ror r12, r12, #24
554         add r10, r10, r4
555         add r11, r11, r12
556         eor r5, r5, r10
557         eor r6, r6, r11
558         str r11, [sp, #12]
559         ror r5, r5, #25
560         ror r6, r6, #25
561         str r4, [sp, #28]
562         ldr r4, [sp, #4]
563         add r2, r2, r7
564         add r3, r3, r4
565         ldr r11, [sp, #20]
566         eor r11, r11, r2
567         eor r14, r14, r3
568         ror r11, r11, #16
569         ror r14, r14, #16
570         add r8, r8, r11
571         add r9, r9, r14
572         eor r7, r7, r8
573         eor r4, r4, r9
574         ror r7, r7, #20
575         ror r4, r4, #20
576         str r6, [sp, #8]
577         add r2, r2, r7
578         add r3, r3, r4
579         eor r11, r11, r2
580         eor r14, r14, r3
581         ror r11, r11, #24
582         ror r14, r14, #24
583         add r8, r8, r11
584         add r9, r9, r14
585         eor r7, r7, r8
586         eor r4, r4, r9
587         ror r7, r7, #25
588         ror r4, r4, #25
589         bne .Lchacha_blocks_neon_rounds2
590         str r8, [sp, #0]
591         str r9, [sp, #4]
592         str r10, [sp, #8]
593         str r12, [sp, #16]
594         str r11, [sp, #20]
595         str r14, [sp, #24]
596         ldr r12, [sp, #48]
597         ldr r14, [sp, #40]
598         ldr r8, [sp, #(64 +0)]
599         ldr r9, [sp, #(64 +4)]
600         ldr r10, [sp, #(64 +8)]
601         ldr r11, [sp, #(64 +12)]
602         add r0, r0, r8
603         add r1, r1, r9
604         add r2, r2, r10
605         ldr r8, [sp, #(64 +16)]
606         add r3, r3, r11
607         ldr r9, [sp, #(64 +20)]
608         add r4, r4, r8
609         ldr r10, [sp, #(64 +24)]
610         add r5, r5, r9
611         ldr r11, [sp, #(64 +28)]
612         add r6, r6, r10
613         tst r12, r12
614         add r7, r7, r11
615         beq .Lchacha_blocks_neon_nomessage21
616         ldmia r12!, {r8-r11}
617         eor r0, r0, r8
618         eor r1, r1, r9
619         eor r2, r2, r10
620         ldr r8, [r12, #0]
621         eor r3, r3, r11
622         ldr r9, [r12, #4]
623         eor r4, r4, r8
624         ldr r10, [r12, #8]
625         eor r5, r5, r9
626         ldr r11, [r12, #12]
627         eor r6, r6, r10
628         add r12, r12, #16
629         eor r7, r7, r11
630 .Lchacha_blocks_neon_nomessage21:
631         stmia r14!, {r0-r7}
632         ldm sp, {r0-r7}
633         ldr r8, [sp, #(64 +32)]
634         ldr r9, [sp, #(64 +36)]
635         ldr r10, [sp, #(64 +40)]
636         ldr r11, [sp, #(64 +44)]
637         add r0, r0, r8
638         add r1, r1, r9
639         add r2, r2, r10
640         ldr r8, [sp, #(64 +48)]
641         add r3, r3, r11
642         ldr r9, [sp, #(64 +52)]
643         add r4, r4, r8
644         ldr r10, [sp, #(64 +56)]
645         add r5, r5, r9
646         ldr r11, [sp, #(64 +60)]
647         add r6, r6, r10
648         adds r8, r8, #1
649         add r7, r7, r11
650         adc r9, r9, #0
651         str r8, [sp, #(64 +48)]
652         tst r12, r12
653         str r9, [sp, #(64 +52)]
654         beq .Lchacha_blocks_neon_nomessage22
655         ldmia r12!, {r8-r11}
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_nomessage22:
670         stmia r14!, {r0-r7}
671         str r12, [sp, #48]
672         str r14, [sp, #40]
673         ldr r3, [sp, #52]
674         cmp r3, #64
675         sub r4, r3, #64
676         str r4, [sp, #52]
677         bhi .Lchacha_blocks_neon_mainloop2
678         cmp r3, #64
679         beq .Lchacha_blocks_neon_nocopy2
680         ldr r1, [sp, #56]
681         sub r14, r14, #64
682 .Lchacha_blocks_neon_copyinput2:
683         subs r3, r3, #1
684         ldrb r0, [r14], #1
685         strb r0, [r1], #1
686         bne .Lchacha_blocks_neon_copyinput2
687 .Lchacha_blocks_neon_nocopy2:
688 .Lchacha_blocks_neon_done:
689         ldr r7, [sp, #60]
690         ldr r8, [sp, #(64 +48)]
691         ldr r9, [sp, #(64 +52)]
692         str r8, [r7, #(48 + 0)]
693         str r9, [r7, #(48 + 4)]
694         mov r12, sp
695         stmia r12!, {r0-r7}
696         add r12, r12, #48
697         stmia r12!, {r0-r7}
698         sub r0, sp, #8
699         ldr sp, [sp, #192]
700         ldmfd sp!, {r4-r12, r14}
701         vldm sp!, {q4-q7}
702         sub r0, sp, r0
703         bx lr
704 .Lchacha_blocks_neon_nobytes:
705         mov r0, #0;
706         bx lr
707 .ltorg
708 .size _gcry_chacha20_armv7_neon_blocks,.-_gcry_chacha20_armv7_neon_blocks;
709
710 #endif