Fix non-PIC reference in PIC for poly1305/ARMv7-NEON
[libgcrypt.git] / cipher / poly1305-armv7-neon.S
1 /* poly1305-armv7-neon.S  -  ARMv7/NEON implementation of Poly1305
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/poly1305-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)
31
32 .syntax unified
33 .fpu neon
34 .arm
35
36 #ifdef __PIC__
37 #  define GET_DATA_POINTER(reg, name, rtmp) \
38                 ldr reg, 1f; \
39                 ldr rtmp, 2f; \
40                 b 3f; \
41         1:      .word _GLOBAL_OFFSET_TABLE_-(3f+8); \
42         2:      .word name(GOT); \
43         3:      add reg, pc, reg; \
44                 ldr reg, [reg, rtmp];
45 #else
46 #  define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name
47 #endif
48
49 .text
50
51 .p2align 2
52 .Lpoly1305_init_constants_neon:
53 .long 0x3ffff03
54 .long 0x3ffc0ff
55 .long 0x3f03fff
56 .long 0x00fffff
57
58 .globl _gcry_poly1305_armv7_neon_init_ext
59 .type  _gcry_poly1305_armv7_neon_init_ext,%function;
60 _gcry_poly1305_armv7_neon_init_ext:
61 .Lpoly1305_init_ext_neon_local:
62         stmfd sp!, {r4-r11, lr}
63         sub sp, sp, #32
64         mov r14, r2
65         and r2, r2, r2
66         moveq r14, #-1
67         ldmia r1!, {r2-r5}
68         GET_DATA_POINTER(r7,.Lpoly1305_init_constants_neon,r8)
69         mov r6, r2
70         mov r8, r2, lsr #26
71         mov r9, r3, lsr #20
72         mov r10, r4, lsr #14
73         mov r11, r5, lsr #8
74         orr r8, r8, r3, lsl #6
75         orr r9, r9, r4, lsl #12
76         orr r10, r10, r5, lsl #18
77         ldmia r7, {r2-r5}
78         and r2, r2, r8
79         and r3, r3, r9
80         and r4, r4, r10
81         and r5, r5, r11
82         and r6, r6, 0x3ffffff
83         stmia r0!, {r2-r6}
84         eor r8, r8, r8
85         str r8, [sp, #24]
86 .Lpoly1305_init_ext_neon_squareloop:
87         ldr r8, [sp, #24]
88         mov r12, #16
89         cmp r8, #2
90         beq .Lpoly1305_init_ext_neon_donesquaring
91         cmp r8, #1
92         moveq r12, #64
93         cmp r14, r12
94         bls .Lpoly1305_init_ext_neon_donesquaring
95         add r8, #1
96         str r8, [sp, #24]
97         mov r6, r6, lsl #1
98         mov r2, r2, lsl #1
99         umull r7, r8, r3, r3
100         umull r9, r10, r6, r4
101         umlal r7, r8, r6, r5
102         umlal r9, r10, r2, r3
103         add r11, r5, r5, lsl #2
104         umlal r7, r8, r2, r4
105         umlal r9, r10, r5, r11
106         str r7, [sp, #16]
107         str r8, [sp, #20]
108         mov r2, r2, lsr #1
109         mov r5, r5, lsl #1
110         str r9, [sp, #8]
111         str r10, [sp, #12]
112         umull r7, r8, r2, r2
113         umull r9, r10, r6, r2
114         add r11, r3, r3, lsl #2
115         add r12, r4, r4, lsl #2
116         umlal r7, r8, r6, r3
117         umlal r9, r10, r5, r11
118         umlal r7, r8, r5, r12
119         umlal r9, r10, r4, r12
120         mov r6, r6, lsr #1
121         mov r3, r3, lsl #1
122         add r11, r2, r2, lsl #2
123         str r7, [sp, #0]
124         str r8, [sp, #4]
125         umull r7, r8, r6, r6
126         umlal r7, r8, r3, r12
127         umlal r7, r8, r5, r11
128         and r6, r7, 0x3ffffff
129         mov r11, r7, lsr #26
130         orr r11, r11, r8, lsl #6
131         ldr r7, [sp, #0]
132         ldr r8, [sp, #4]
133         adds r9, r9, r11
134         adc r10, r10, #0
135         and r2, r9, 0x3ffffff
136         mov r11, r9, lsr #26
137         orr r11, r11, r10, lsl #6
138         ldr r9, [sp, #8]
139         ldr r10, [sp, #12]
140         adds r7, r7, r11
141         adc r8, r8, #0
142         and r3, r7, 0x3ffffff
143         mov r11, r7, lsr #26
144         orr r11, r11, r8, lsl #6
145         ldr r7, [sp, #16]
146         ldr r8, [sp, #20]
147         adds r9, r9, r11
148         adc r10, r10, #0
149         and r4, r9, 0x3ffffff
150         mov r11, r9, lsr #26
151         orr r11, r11, r10, lsl #6
152         adds r7, r7, r11
153         adc r8, r8, #0
154         and r5, r7, 0x3ffffff
155         mov r11, r7, lsr #26
156         orr r11, r11, r8, lsl #6
157         add r11, r11, r11, lsl #2
158         add r6, r6, r11
159         mov r11, r6, lsr #26
160         and r6, r6, 0x3ffffff
161         add r2, r2, r11
162         stmia r0!, {r2-r6}
163         b .Lpoly1305_init_ext_neon_squareloop
164 .Lpoly1305_init_ext_neon_donesquaring:
165         mov r2, #2
166         ldr r14, [sp, #24]
167         sub r14, r2, r14
168         mov r3, r14, lsl #4
169         add r3, r3, r14, lsl #2
170         add r0, r0, r3
171         eor r2, r2, r2
172         eor r3, r3, r3
173         eor r4, r4, r4
174         eor r5, r5, r5
175         eor r6, r6, r6
176         stmia r0!, {r2-r6}
177         stmia r0!, {r2-r6}
178         ldmia r1!, {r2-r5}
179         stmia r0, {r2-r6}
180         add sp, sp, #32
181         ldmfd sp!, {r4-r11, lr}
182         mov r0, #(9*4+32)
183         bx lr
184 .ltorg
185 .size _gcry_poly1305_armv7_neon_init_ext,.-_gcry_poly1305_armv7_neon_init_ext;
186
187 .globl _gcry_poly1305_armv7_neon_blocks
188 .type  _gcry_poly1305_armv7_neon_blocks,%function;
189 _gcry_poly1305_armv7_neon_blocks:
190 .Lpoly1305_blocks_neon_local:
191         vmov.i32 q0, #0xffffffff
192         vmov.i32 d4, #1
193         vsubw.u32 q0, q0, d4
194         vstmdb sp!, {q4,q5,q6,q7}
195         stmfd sp!, {r4-r11, lr}
196         mov r8, sp
197         and sp, sp, #~63
198         sub sp, sp, #192
199         str r0, [sp, #108]
200         str r1, [sp, #112]
201         str r2, [sp, #116]
202         str r8, [sp, #120]
203         mov r3, r0
204         mov r0, r1
205         mov r1, r2
206         mov r2, r3
207         ldr r8, [r2, #116]
208         veor d15, d15, d15
209         vorr.i32 d15, #(1 << 24)
210         tst r8, #2
211         beq .Lpoly1305_blocks_neon_skip_shift8
212         vshr.u64 d15, #32
213 .Lpoly1305_blocks_neon_skip_shift8:
214         tst r8, #4
215         beq .Lpoly1305_blocks_neon_skip_shift16
216         veor d15, d15, d15
217 .Lpoly1305_blocks_neon_skip_shift16:
218         vst1.64 d15, [sp, :64]
219         tst r8, #1
220         bne .Lpoly1305_blocks_neon_started
221         vld1.64 {q0-q1}, [r0]!
222         vswp d1, d2
223         vmovn.i64 d21, q0
224         vshrn.i64 d22, q0, #26
225         vshrn.u64 d24, q1, #14
226         vext.8 d0, d0, d2, #4
227         vext.8 d1, d1, d3, #4
228         vshr.u64 q1, q1, #32
229         vshrn.i64 d23, q0, #20
230         vshrn.u64 d25, q1, #8
231         vand.i32 d21, #0x03ffffff
232         vand.i32 q11, #0x03ffffff
233         vand.i32 q12, #0x03ffffff
234         orr r8, r8, #1
235         sub r1, r1, #32
236         str r8, [r2, #116]
237         vorr d25, d25, d15
238         b .Lpoly1305_blocks_neon_setupr20
239 .Lpoly1305_blocks_neon_started:
240         add r9, r2, #60
241         vldm r9, {d21-d25}
242 .Lpoly1305_blocks_neon_setupr20:
243         vmov.i32 d0, #5
244         tst r8, #(8|16)
245         beq .Lpoly1305_blocks_neon_setupr20_simple
246         tst r8, #(8)
247         beq .Lpoly1305_blocks_neon_setupr20_r_1
248         mov r9, r2
249         add r10, r2, #20
250         vld1.64 {q9}, [r9]!
251         vld1.64 {q8}, [r10]!
252         vld1.64 {d2}, [r9]
253         vld1.64 {d20}, [r10]
254         b .Lpoly1305_blocks_neon_setupr20_hard
255 .Lpoly1305_blocks_neon_setupr20_r_1:
256         mov r9, r2
257         vmov.i32 d2, #1
258         vld1.64 {q8}, [r9]!
259         veor q9, q9, q9
260         vshr.u64 d2, d2, #32
261         vld1.64 {d20}, [r9]
262 .Lpoly1305_blocks_neon_setupr20_hard:
263         vzip.i32 q8, q9
264         vzip.i32 d20, d2
265         b .Lpoly1305_blocks_neon_setups20
266 .Lpoly1305_blocks_neon_setupr20_simple:
267         add r9, r2, #20
268         vld1.64 {d2-d4}, [r9]
269         vdup.32 d16, d2[0]
270         vdup.32 d17, d2[1]
271         vdup.32 d18, d3[0]
272         vdup.32 d19, d3[1]
273         vdup.32 d20, d4[0]
274 .Lpoly1305_blocks_neon_setups20:
275         vmul.i32 q13, q8, d0[0]
276         vmov.i64 q15, 0x00000000ffffffff
277         vmul.i32 q14, q9, d0[0]
278         vshr.u64 q15, q15, #6
279         cmp r1, #64
280         blo .Lpoly1305_blocks_neon_try32
281         add r9, sp, #16
282         add r10, r2, #40
283         add r11, sp, #64
284         str r1, [sp, #116]
285         vld1.64 {d10-d12}, [r10]
286         vmov d14, d12
287         vmul.i32 q6, q5, d0[0]
288 .Lpoly1305_blocks_neon_mainloop:
289         ldmia r0!, {r2-r5}
290         vmull.u32 q0, d25, d12[0]
291         mov r7, r2, lsr #26
292         vmlal.u32 q0, d24, d12[1]
293         mov r8, r3, lsr #20
294         ldr r6, [sp, #0]
295         vmlal.u32 q0, d23, d13[0]
296         mov r9, r4, lsr #14
297         vmlal.u32 q0, d22, d13[1]
298         orr r6, r6, r5, lsr #8
299         vmlal.u32 q0, d21, d14[0]
300         orr r3, r7, r3, lsl #6
301         vmull.u32 q1, d25, d12[1]
302         orr r4, r8, r4, lsl #12
303         orr r5, r9, r5, lsl #18
304         vmlal.u32 q1, d24, d13[0]
305         ldmia r0!, {r7-r10}
306         vmlal.u32 q1, d23, d13[1]
307         mov r1, r7, lsr #26
308         vmlal.u32 q1, d22, d14[0]
309         ldr r11, [sp, #4]
310         mov r12, r8, lsr #20
311         vmlal.u32 q1, d21, d10[0]
312         mov r14, r9, lsr #14
313         vmull.u32 q2, d25, d13[0]
314         orr r11, r11, r10, lsr #8
315         orr r8, r1, r8, lsl #6
316         vmlal.u32 q2, d24, d13[1]
317         orr r9, r12, r9, lsl #12
318         vmlal.u32 q2, d23, d14[0]
319         orr r10, r14, r10, lsl #18
320         vmlal.u32 q2, d22, d10[0]
321         mov r12, r3
322         and r2, r2, #0x3ffffff
323         vmlal.u32 q2, d21, d10[1]
324         mov r14, r5
325         vmull.u32 q3, d25, d13[1]
326         and r3, r7, #0x3ffffff
327         vmlal.u32 q3, d24, d14[0]
328         and r5, r8, #0x3ffffff
329         vmlal.u32 q3, d23, d10[0]
330         and r7, r9, #0x3ffffff
331         vmlal.u32 q3, d22, d10[1]
332         and r8, r14, #0x3ffffff
333         vmlal.u32 q3, d21, d11[0]
334         and r9, r10, #0x3ffffff
335         add r14, sp, #128
336         vmull.u32 q4, d25, d14[0]
337         mov r10, r6
338         vmlal.u32 q4, d24, d10[0]
339         and r6, r4, #0x3ffffff
340         vmlal.u32 q4, d23, d10[1]
341         and r4, r12, #0x3ffffff
342         vmlal.u32 q4, d22, d11[0]
343         stm r14, {r2-r11}
344         vmlal.u32 q4, d21, d11[1]
345         vld1.64 {d21-d24}, [r14, :256]!
346         vld1.64 {d25}, [r14, :64]
347         ldmia r0!, {r2-r5}
348         vmlal.u32 q0, d25, d26
349         mov r7, r2, lsr #26
350         vmlal.u32 q0, d24, d27
351         ldr r6, [sp, #0]
352         mov r8, r3, lsr #20
353         vmlal.u32 q0, d23, d28
354         mov r9, r4, lsr #14
355         vmlal.u32 q0, d22, d29
356         orr r6, r6, r5, lsr #8
357         vmlal.u32 q0, d21, d20
358         orr r3, r7, r3, lsl #6
359         vmlal.u32 q1, d25, d27
360         orr r4, r8, r4, lsl #12
361         orr r5, r9, r5, lsl #18
362         vmlal.u32 q1, d24, d28
363         ldmia r0!, {r7-r10}
364         vmlal.u32 q1, d23, d29
365         mov r1, r7, lsr #26
366         vmlal.u32 q1, d22, d20
367         ldr r11, [sp, #4]
368         mov r12, r8, lsr #20
369         vmlal.u32 q1, d21, d16
370         mov r14, r9, lsr #14
371         vmlal.u32 q2, d25, d28
372         orr r11, r11, r10, lsr #8
373         orr r8, r1, r8, lsl #6
374         orr r9, r12, r9, lsl #12
375         vmlal.u32 q2, d24, d29
376         orr r10, r14, r10, lsl #18
377         and r2, r2, #0x3ffffff
378         mov r12, r3
379         vmlal.u32 q2, d23, d20
380         mov r14, r5
381         vmlal.u32 q2, d22, d16
382         and r3, r7, #0x3ffffff
383         vmlal.u32 q2, d21, d17
384         and r5, r8, #0x3ffffff
385         vmlal.u32 q3, d25, d29
386         and r7, r9, #0x3ffffff
387         vmlal.u32 q3, d24, d20
388         and r8, r14, #0x3ffffff
389         vmlal.u32 q3, d23, d16
390         and r9, r10, #0x3ffffff
391         vmlal.u32 q3, d22, d17
392         add r14, sp, #128
393         vmlal.u32 q3, d21, d18
394         mov r10, r6
395         vmlal.u32 q4, d25, d20
396         vmlal.u32 q4, d24, d16
397         and r6, r4, #0x3ffffff
398         vmlal.u32 q4, d23, d17
399         and r4, r12, #0x3ffffff
400         vmlal.u32 q4, d22, d18
401         stm r14, {r2-r11}
402         vmlal.u32 q4, d21, d19
403         vld1.64 {d21-d24}, [r14, :256]!
404         vld1.64 {d25}, [r14, :64]
405         vaddw.u32 q0, q0, d21
406         vaddw.u32 q1, q1, d22
407         vaddw.u32 q2, q2, d23
408         vaddw.u32 q3, q3, d24
409         vaddw.u32 q4, q4, d25
410         vshr.u64 q11, q0, #26
411         vand q0, q0, q15
412         vadd.i64 q1, q1, q11
413         vshr.u64 q12, q3, #26
414         vand q3, q3, q15
415         vadd.i64 q4, q4, q12
416         vshr.u64 q11, q1, #26
417         vand q1, q1, q15
418         vadd.i64 q2, q2, q11
419         vshr.u64 q12, q4, #26
420         vand q4, q4, q15
421         vadd.i64 q0, q0, q12
422         vshl.i64 q12, q12, #2
423         ldr r1, [sp, #116]
424         vadd.i64 q0, q0, q12
425         vshr.u64 q11, q2, #26
426         vand q2, q2, q15
427         vadd.i64 q3, q3, q11
428         sub r1, #64
429         vshr.u64 q12, q0, #26
430         vand q0, q0, q15
431         vadd.i64 q1, q1, q12
432         cmp r1, #64
433         vshr.u64 q11, q3, #26
434         vand q3, q3, q15
435         vadd.i64 q4, q4, q11
436         vmovn.i64 d21, q0
437         str r1, [sp, #116]
438         vmovn.i64 d22, q1
439         vmovn.i64 d23, q2
440         vmovn.i64 d24, q3
441         vmovn.i64 d25, q4
442         bhs .Lpoly1305_blocks_neon_mainloop
443 .Lpoly1305_blocks_neon_try32:
444         cmp r1, #32
445         blo .Lpoly1305_blocks_neon_done
446         tst r0, r0
447         bne .Lpoly1305_blocks_loadm32
448         veor q0, q0, q0
449         veor q1, q1, q1
450         veor q2, q2, q2
451         veor q3, q3, q3
452         veor q4, q4, q4
453         b .Lpoly1305_blocks_continue32
454 .Lpoly1305_blocks_loadm32:
455         vld1.64 {q0-q1}, [r0]!
456         veor q4, q4, q4
457         vswp d1, d2
458         veor q3, q3, q3
459         vtrn.32 q0, q4
460         vtrn.32 q1, q3
461         vshl.i64 q2, q1, #12
462         vshl.i64 q3, q3, #18
463         vshl.i64 q1, q4, #6
464         vmovl.u32 q4, d15
465 .Lpoly1305_blocks_continue32:
466         vmlal.u32 q0, d25, d26
467         vmlal.u32 q0, d24, d27
468         vmlal.u32 q0, d23, d28
469         vmlal.u32 q0, d22, d29
470         vmlal.u32 q0, d21, d20
471         vmlal.u32 q1, d25, d27
472         vmlal.u32 q1, d24, d28
473         vmlal.u32 q1, d23, d29
474         vmlal.u32 q1, d22, d20
475         vmlal.u32 q1, d21, d16
476         vmlal.u32 q2, d25, d28
477         vmlal.u32 q2, d24, d29
478         vmlal.u32 q2, d23, d20
479         vmlal.u32 q2, d22, d16
480         vmlal.u32 q2, d21, d17
481         vmlal.u32 q3, d25, d29
482         vmlal.u32 q3, d24, d20
483         vmlal.u32 q3, d23, d16
484         vmlal.u32 q3, d22, d17
485         vmlal.u32 q3, d21, d18
486         vmlal.u32 q4, d25, d20
487         vmlal.u32 q4, d24, d16
488         vmlal.u32 q4, d23, d17
489         vmlal.u32 q4, d22, d18
490         vmlal.u32 q4, d21, d19
491         vshr.u64 q11, q0, #26
492         vand q0, q0, q15
493         vadd.i64 q1, q1, q11
494         vshr.u64 q12, q3, #26
495         vand q3, q3, q15
496         vadd.i64 q4, q4, q12
497         vshr.u64 q11, q1, #26
498         vand q1, q1, q15
499         vadd.i64 q2, q2, q11
500         vshr.u64 q12, q4, #26
501         vand q4, q4, q15
502         vadd.i64 q0, q0, q12
503         vshl.i64 q12, q12, #2
504         vadd.i64 q0, q0, q12
505         vshr.u64 q11, q2, #26
506         vand q2, q2, q15
507         vadd.i64 q3, q3, q11
508         vshr.u64 q12, q0, #26
509         vand q0, q0, q15
510         vadd.i64 q1, q1, q12
511         vshr.u64 q11, q3, #26
512         vand q3, q3, q15
513         vadd.i64 q4, q4, q11
514         vmovn.i64 d21, q0
515         vmovn.i64 d22, q1
516         vmovn.i64 d23, q2
517         vmovn.i64 d24, q3
518         vmovn.i64 d25, q4
519 .Lpoly1305_blocks_neon_done:
520         tst r0, r0
521         beq .Lpoly1305_blocks_neon_final
522         ldr r2, [sp, #108]
523         add r2, r2, #60
524         vst1.64 {d21}, [r2]!
525         vst1.64 {d22-d25}, [r2]
526         b .Lpoly1305_blocks_neon_leave
527 .Lpoly1305_blocks_neon_final:
528         vadd.u32 d10, d0, d1
529         vadd.u32 d13, d2, d3
530         vadd.u32 d11, d4, d5
531         ldr r5, [sp, #108]
532         vadd.u32 d14, d6, d7
533         vadd.u32 d12, d8, d9
534         vtrn.32 d10, d13
535         vtrn.32 d11, d14
536         vst1.64 {d10-d12}, [sp]
537         ldm sp, {r0-r4}
538         mov r12, r0, lsr #26
539         and r0, r0, #0x3ffffff
540         add r1, r1, r12
541         mov r12, r1, lsr #26
542         and r1, r1, #0x3ffffff
543         add r2, r2, r12
544         mov r12, r2, lsr #26
545         and r2, r2, #0x3ffffff
546         add r3, r3, r12
547         mov r12, r3, lsr #26
548         and r3, r3, #0x3ffffff
549         add r4, r4, r12
550         mov r12, r4, lsr #26
551         and r4, r4, #0x3ffffff
552         add r12, r12, r12, lsl #2
553         add r0, r0, r12
554         mov r12, r0, lsr #26
555         and r0, r0, #0x3ffffff
556         add r1, r1, r12
557         mov r12, r1, lsr #26
558         and r1, r1, #0x3ffffff
559         add r2, r2, r12
560         mov r12, r2, lsr #26
561         and r2, r2, #0x3ffffff
562         add r3, r3, r12
563         mov r12, r3, lsr #26
564         and r3, r3, #0x3ffffff
565         add r4, r4, r12
566         mov r12, r4, lsr #26
567         and r4, r4, #0x3ffffff
568         add r12, r12, r12, lsl #2
569         add r0, r0, r12
570         mov r12, r0, lsr #26
571         and r0, r0, #0x3ffffff
572         add r1, r1, r12
573         add r6, r0, #5
574         mov r12, r6, lsr #26
575         and r6, r6, #0x3ffffff
576         add r7, r1, r12
577         mov r12, r7, lsr #26
578         and r7, r7, #0x3ffffff
579         add r10, r2, r12
580         mov r12, r10, lsr #26
581         and r10, r10, #0x3ffffff
582         add r11, r3, r12
583         mov r12, #-(1 << 26)
584         add r12, r12, r11, lsr #26
585         and r11, r11, #0x3ffffff
586         add r14, r4, r12
587         mov r12, r14, lsr #31
588         sub r12, #1
589         and r6, r6, r12
590         and r7, r7, r12
591         and r10, r10, r12
592         and r11, r11, r12
593         and r14, r14, r12
594         mvn r12, r12
595         and r0, r0, r12
596         and r1, r1, r12
597         and r2, r2, r12
598         and r3, r3, r12
599         and r4, r4, r12
600         orr r0, r0, r6
601         orr r1, r1, r7
602         orr r2, r2, r10
603         orr r3, r3, r11
604         orr r4, r4, r14
605         orr r0, r0, r1, lsl #26
606         lsr r1, r1, #6
607         orr r1, r1, r2, lsl #20
608         lsr r2, r2, #12
609         orr r2, r2, r3, lsl #14
610         lsr r3, r3, #18
611         orr r3, r3, r4, lsl #8
612         add r5, r5, #60
613         stm r5, {r0-r3}
614 .Lpoly1305_blocks_neon_leave:
615         sub r0, sp, #8
616         ldr sp, [sp, #120]
617         ldmfd sp!, {r4-r11, lr}
618         vldm sp!, {q4-q7}
619         sub r0, sp, r0
620         bx lr
621 .size _gcry_poly1305_armv7_neon_blocks,.-_gcry_poly1305_armv7_neon_blocks;
622
623 .globl _gcry_poly1305_armv7_neon_finish_ext
624 .type  _gcry_poly1305_armv7_neon_finish_ext,%function;
625 _gcry_poly1305_armv7_neon_finish_ext:
626 .Lpoly1305_finish_ext_neon_local:
627         stmfd sp!, {r4-r11, lr}
628         sub sp, sp, #32
629         mov r5, r0
630         mov r6, r1
631         mov r7, r2
632         mov r8, r3
633         ands r7, r7, r7
634         beq .Lpoly1305_finish_ext_neon_noremaining
635         mov r9, sp
636         veor q0, q0, q0
637         veor q1, q1, q1
638         vst1.64 {q0-q1}, [sp]
639         tst r7, #16
640         beq .Lpoly1305_finish_ext_neon_skip16
641         vld1.u64 {q0}, [r1]!
642         vst1.64 {q0}, [r9]!
643 .Lpoly1305_finish_ext_neon_skip16:
644         tst r7, #8
645         beq .Lpoly1305_finish_ext_neon_skip8
646         ldmia r1!, {r10-r11}
647         stmia r9!, {r10-r11}
648 .Lpoly1305_finish_ext_neon_skip8:
649         tst r7, #4
650         beq .Lpoly1305_finish_ext_neon_skip4
651         ldr r10, [r1], #4
652         str r10, [r9], #4
653 .Lpoly1305_finish_ext_neon_skip4:
654         tst r7, #2
655         beq .Lpoly1305_finish_ext_neon_skip2
656         ldrh r10, [r1], #2
657         strh r10, [r9], #2
658 .Lpoly1305_finish_ext_neon_skip2:
659         tst r7, #1
660         beq .Lpoly1305_finish_ext_neon_skip1
661         ldrb r10, [r1], #1
662         strb r10, [r9], #1
663 .Lpoly1305_finish_ext_neon_skip1:
664         cmp r7, #16
665         beq .Lpoly1305_finish_ext_neon_skipfinalbit
666         mov r10, #1
667         strb r10, [r9]
668 .Lpoly1305_finish_ext_neon_skipfinalbit:
669         ldr r10, [r5, #116]
670         orrhs r10, #2
671         orrlo r10, #4
672         str r10, [r5, #116]
673         mov r0, r5
674         mov r1, sp
675         mov r2, #32
676         bl .Lpoly1305_blocks_neon_local
677 .Lpoly1305_finish_ext_neon_noremaining:
678         ldr r10, [r5, #116]
679         tst r10, #1
680         beq .Lpoly1305_finish_ext_neon_notstarted
681         cmp r7, #0
682         beq .Lpoly1305_finish_ext_neon_user2r
683         cmp r7, #16
684         bls .Lpoly1305_finish_ext_neon_user1
685 .Lpoly1305_finish_ext_neon_user2r:
686         orr r10, r10, #8
687         b .Lpoly1305_finish_ext_neon_finalblock
688 .Lpoly1305_finish_ext_neon_user1:
689         orr r10, r10, #16
690 .Lpoly1305_finish_ext_neon_finalblock:
691         str r10, [r5, #116]
692         mov r0, r5
693         eor r1, r1, r1
694         mov r2, #32
695         bl .Lpoly1305_blocks_neon_local
696 .Lpoly1305_finish_ext_neon_notstarted:
697         add r0, r5, #60
698         add r9, r5, #100
699         ldm r0, {r0-r3}
700         ldm r9, {r9-r12}
701         adds r0, r0, r9
702         adcs r1, r1, r10
703         adcs r2, r2, r11
704         adcs r3, r3, r12
705         stm r8, {r0-r3}
706         veor q0, q0, q0
707         veor q1, q1, q1
708         veor q2, q2, q2
709         veor q3, q3, q3
710         vstmia r5!, {q0-q3}
711         vstm r5, {q0-q3}
712         add sp, sp, #32
713         ldmfd sp!, {r4-r11, lr}
714         mov r0, #(9*4+32)
715         bx lr
716 .size _gcry_poly1305_armv7_neon_finish_ext,.-_gcry_poly1305_armv7_neon_finish_ext;
717
718 #endif