• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// This file is generated from a similarly-named Perl script in the BoringSSL
2// source tree. Do not edit by hand.
3
4#if !defined(__has_feature)
5#define __has_feature(x) 0
6#endif
7#if __has_feature(memory_sanitizer) && !defined(OPENSSL_NO_ASM)
8#define OPENSSL_NO_ASM
9#endif
10
11#if !defined(OPENSSL_NO_ASM)
12#if defined(BORINGSSL_PREFIX)
13#include <boringssl_prefix_symbols_asm.h>
14#endif
15#include <openssl/arm_arch.h>
16
17@ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
18@ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
19
20
21.text
22#if defined(__thumb2__) || defined(__clang__)
23.syntax	unified
24#endif
25#if defined(__thumb2__)
26.thumb
27#else
28.code	32
29#endif
30
31#if defined(__thumb2__) || defined(__clang__)
32#define ldrhsb	ldrbhs
33#endif
34
35.align	5
36Lsigma:
37.long	0x61707865,0x3320646e,0x79622d32,0x6b206574	@ endian-neutral
38Lone:
39.long	1,0,0,0
40#if __ARM_MAX_ARCH__>=7
41LOPENSSL_armcap:
42.word	OPENSSL_armcap_P-LChaCha20_ctr32
43#else
44.word	-1
45#endif
46
47.globl	_ChaCha20_ctr32
48.private_extern	_ChaCha20_ctr32
49#ifdef __thumb2__
50.thumb_func	_ChaCha20_ctr32
51#endif
52.align	5
53_ChaCha20_ctr32:
54LChaCha20_ctr32:
55	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
56	stmdb	sp!,{r0,r1,r2,r4-r11,lr}
57#if __ARM_ARCH__<7 && !defined(__thumb2__)
58	sub	r14,pc,#16		@ _ChaCha20_ctr32
59#else
60	adr	r14,LChaCha20_ctr32
61#endif
62	cmp	r2,#0			@ len==0?
63#ifdef	__thumb2__
64	itt	eq
65#endif
66	addeq	sp,sp,#4*3
67	beq	Lno_data
68#if __ARM_MAX_ARCH__>=7
69	cmp	r2,#192			@ test len
70	bls	Lshort
71	ldr	r4,[r14,#-32]
72	ldr	r4,[r14,r4]
73# ifdef	__APPLE__
74	ldr	r4,[r4]
75# endif
76	tst	r4,#ARMV7_NEON
77	bne	LChaCha20_neon
78Lshort:
79#endif
80	ldmia	r12,{r4,r5,r6,r7}		@ load counter and nonce
81	sub	sp,sp,#4*(16)		@ off-load area
82	sub	r14,r14,#64		@ Lsigma
83	stmdb	sp!,{r4,r5,r6,r7}		@ copy counter and nonce
84	ldmia	r3,{r4,r5,r6,r7,r8,r9,r10,r11}		@ load key
85	ldmia	r14,{r0,r1,r2,r3}		@ load sigma
86	stmdb	sp!,{r4,r5,r6,r7,r8,r9,r10,r11}		@ copy key
87	stmdb	sp!,{r0,r1,r2,r3}		@ copy sigma
88	str	r10,[sp,#4*(16+10)]	@ off-load "rx"
89	str	r11,[sp,#4*(16+11)]	@ off-load "rx"
90	b	Loop_outer_enter
91
92.align	4
93Loop_outer:
94	ldmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9}		@ load key material
95	str	r11,[sp,#4*(32+2)]	@ save len
96	str	r12,  [sp,#4*(32+1)]	@ save inp
97	str	r14,  [sp,#4*(32+0)]	@ save out
98Loop_outer_enter:
99	ldr	r11, [sp,#4*(15)]
100	ldr	r12,[sp,#4*(12)]	@ modulo-scheduled load
101	ldr	r10, [sp,#4*(13)]
102	ldr	r14,[sp,#4*(14)]
103	str	r11, [sp,#4*(16+15)]
104	mov	r11,#10
105	b	Loop
106
107.align	4
108Loop:
109	subs	r11,r11,#1
110	add	r0,r0,r4
111	mov	r12,r12,ror#16
112	add	r1,r1,r5
113	mov	r10,r10,ror#16
114	eor	r12,r12,r0,ror#16
115	eor	r10,r10,r1,ror#16
116	add	r8,r8,r12
117	mov	r4,r4,ror#20
118	add	r9,r9,r10
119	mov	r5,r5,ror#20
120	eor	r4,r4,r8,ror#20
121	eor	r5,r5,r9,ror#20
122	add	r0,r0,r4
123	mov	r12,r12,ror#24
124	add	r1,r1,r5
125	mov	r10,r10,ror#24
126	eor	r12,r12,r0,ror#24
127	eor	r10,r10,r1,ror#24
128	add	r8,r8,r12
129	mov	r4,r4,ror#25
130	add	r9,r9,r10
131	mov	r5,r5,ror#25
132	str	r10,[sp,#4*(16+13)]
133	ldr	r10,[sp,#4*(16+15)]
134	eor	r4,r4,r8,ror#25
135	eor	r5,r5,r9,ror#25
136	str	r8,[sp,#4*(16+8)]
137	ldr	r8,[sp,#4*(16+10)]
138	add	r2,r2,r6
139	mov	r14,r14,ror#16
140	str	r9,[sp,#4*(16+9)]
141	ldr	r9,[sp,#4*(16+11)]
142	add	r3,r3,r7
143	mov	r10,r10,ror#16
144	eor	r14,r14,r2,ror#16
145	eor	r10,r10,r3,ror#16
146	add	r8,r8,r14
147	mov	r6,r6,ror#20
148	add	r9,r9,r10
149	mov	r7,r7,ror#20
150	eor	r6,r6,r8,ror#20
151	eor	r7,r7,r9,ror#20
152	add	r2,r2,r6
153	mov	r14,r14,ror#24
154	add	r3,r3,r7
155	mov	r10,r10,ror#24
156	eor	r14,r14,r2,ror#24
157	eor	r10,r10,r3,ror#24
158	add	r8,r8,r14
159	mov	r6,r6,ror#25
160	add	r9,r9,r10
161	mov	r7,r7,ror#25
162	eor	r6,r6,r8,ror#25
163	eor	r7,r7,r9,ror#25
164	add	r0,r0,r5
165	mov	r10,r10,ror#16
166	add	r1,r1,r6
167	mov	r12,r12,ror#16
168	eor	r10,r10,r0,ror#16
169	eor	r12,r12,r1,ror#16
170	add	r8,r8,r10
171	mov	r5,r5,ror#20
172	add	r9,r9,r12
173	mov	r6,r6,ror#20
174	eor	r5,r5,r8,ror#20
175	eor	r6,r6,r9,ror#20
176	add	r0,r0,r5
177	mov	r10,r10,ror#24
178	add	r1,r1,r6
179	mov	r12,r12,ror#24
180	eor	r10,r10,r0,ror#24
181	eor	r12,r12,r1,ror#24
182	add	r8,r8,r10
183	mov	r5,r5,ror#25
184	str	r10,[sp,#4*(16+15)]
185	ldr	r10,[sp,#4*(16+13)]
186	add	r9,r9,r12
187	mov	r6,r6,ror#25
188	eor	r5,r5,r8,ror#25
189	eor	r6,r6,r9,ror#25
190	str	r8,[sp,#4*(16+10)]
191	ldr	r8,[sp,#4*(16+8)]
192	add	r2,r2,r7
193	mov	r10,r10,ror#16
194	str	r9,[sp,#4*(16+11)]
195	ldr	r9,[sp,#4*(16+9)]
196	add	r3,r3,r4
197	mov	r14,r14,ror#16
198	eor	r10,r10,r2,ror#16
199	eor	r14,r14,r3,ror#16
200	add	r8,r8,r10
201	mov	r7,r7,ror#20
202	add	r9,r9,r14
203	mov	r4,r4,ror#20
204	eor	r7,r7,r8,ror#20
205	eor	r4,r4,r9,ror#20
206	add	r2,r2,r7
207	mov	r10,r10,ror#24
208	add	r3,r3,r4
209	mov	r14,r14,ror#24
210	eor	r10,r10,r2,ror#24
211	eor	r14,r14,r3,ror#24
212	add	r8,r8,r10
213	mov	r7,r7,ror#25
214	add	r9,r9,r14
215	mov	r4,r4,ror#25
216	eor	r7,r7,r8,ror#25
217	eor	r4,r4,r9,ror#25
218	bne	Loop
219
220	ldr	r11,[sp,#4*(32+2)]	@ load len
221
222	str	r8, [sp,#4*(16+8)]	@ modulo-scheduled store
223	str	r9, [sp,#4*(16+9)]
224	str	r12,[sp,#4*(16+12)]
225	str	r10, [sp,#4*(16+13)]
226	str	r14,[sp,#4*(16+14)]
227
228	@ at this point we have first half of 512-bit result in
229	@ rx and second half at sp+4*(16+8)
230
231	cmp	r11,#64		@ done yet?
232#ifdef	__thumb2__
233	itete	lo
234#endif
235	addlo	r12,sp,#4*(0)		@ shortcut or ...
236	ldrhs	r12,[sp,#4*(32+1)]	@ ... load inp
237	addlo	r14,sp,#4*(0)		@ shortcut or ...
238	ldrhs	r14,[sp,#4*(32+0)]	@ ... load out
239
240	ldr	r8,[sp,#4*(0)]	@ load key material
241	ldr	r9,[sp,#4*(1)]
242
243#if __ARM_ARCH__>=6 || !defined(__ARMEB__)
244# if __ARM_ARCH__<7
245	orr	r10,r12,r14
246	tst	r10,#3		@ are input and output aligned?
247	ldr	r10,[sp,#4*(2)]
248	bne	Lunaligned
249	cmp	r11,#64		@ restore flags
250# else
251	ldr	r10,[sp,#4*(2)]
252# endif
253	ldr	r11,[sp,#4*(3)]
254
255	add	r0,r0,r8	@ accumulate key material
256	add	r1,r1,r9
257# ifdef	__thumb2__
258	itt	hs
259# endif
260	ldrhs	r8,[r12],#16		@ load input
261	ldrhs	r9,[r12,#-12]
262
263	add	r2,r2,r10
264	add	r3,r3,r11
265# ifdef	__thumb2__
266	itt	hs
267# endif
268	ldrhs	r10,[r12,#-8]
269	ldrhs	r11,[r12,#-4]
270# if __ARM_ARCH__>=6 && defined(__ARMEB__)
271	rev	r0,r0
272	rev	r1,r1
273	rev	r2,r2
274	rev	r3,r3
275# endif
276# ifdef	__thumb2__
277	itt	hs
278# endif
279	eorhs	r0,r0,r8	@ xor with input
280	eorhs	r1,r1,r9
281	add	r8,sp,#4*(4)
282	str	r0,[r14],#16		@ store output
283# ifdef	__thumb2__
284	itt	hs
285# endif
286	eorhs	r2,r2,r10
287	eorhs	r3,r3,r11
288	ldmia	r8,{r8,r9,r10,r11}	@ load key material
289	str	r1,[r14,#-12]
290	str	r2,[r14,#-8]
291	str	r3,[r14,#-4]
292
293	add	r4,r4,r8	@ accumulate key material
294	add	r5,r5,r9
295# ifdef	__thumb2__
296	itt	hs
297# endif
298	ldrhs	r8,[r12],#16		@ load input
299	ldrhs	r9,[r12,#-12]
300	add	r6,r6,r10
301	add	r7,r7,r11
302# ifdef	__thumb2__
303	itt	hs
304# endif
305	ldrhs	r10,[r12,#-8]
306	ldrhs	r11,[r12,#-4]
307# if __ARM_ARCH__>=6 && defined(__ARMEB__)
308	rev	r4,r4
309	rev	r5,r5
310	rev	r6,r6
311	rev	r7,r7
312# endif
313# ifdef	__thumb2__
314	itt	hs
315# endif
316	eorhs	r4,r4,r8
317	eorhs	r5,r5,r9
318	add	r8,sp,#4*(8)
319	str	r4,[r14],#16		@ store output
320# ifdef	__thumb2__
321	itt	hs
322# endif
323	eorhs	r6,r6,r10
324	eorhs	r7,r7,r11
325	str	r5,[r14,#-12]
326	ldmia	r8,{r8,r9,r10,r11}	@ load key material
327	str	r6,[r14,#-8]
328	add	r0,sp,#4*(16+8)
329	str	r7,[r14,#-4]
330
331	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
332
333	add	r0,r0,r8	@ accumulate key material
334	add	r1,r1,r9
335# ifdef	__thumb2__
336	itt	hs
337# endif
338	ldrhs	r8,[r12],#16		@ load input
339	ldrhs	r9,[r12,#-12]
340# ifdef	__thumb2__
341	itt	hi
342# endif
343	strhi	r10,[sp,#4*(16+10)]	@ copy "rx" while at it
344	strhi	r11,[sp,#4*(16+11)]	@ copy "rx" while at it
345	add	r2,r2,r10
346	add	r3,r3,r11
347# ifdef	__thumb2__
348	itt	hs
349# endif
350	ldrhs	r10,[r12,#-8]
351	ldrhs	r11,[r12,#-4]
352# if __ARM_ARCH__>=6 && defined(__ARMEB__)
353	rev	r0,r0
354	rev	r1,r1
355	rev	r2,r2
356	rev	r3,r3
357# endif
358# ifdef	__thumb2__
359	itt	hs
360# endif
361	eorhs	r0,r0,r8
362	eorhs	r1,r1,r9
363	add	r8,sp,#4*(12)
364	str	r0,[r14],#16		@ store output
365# ifdef	__thumb2__
366	itt	hs
367# endif
368	eorhs	r2,r2,r10
369	eorhs	r3,r3,r11
370	str	r1,[r14,#-12]
371	ldmia	r8,{r8,r9,r10,r11}	@ load key material
372	str	r2,[r14,#-8]
373	str	r3,[r14,#-4]
374
375	add	r4,r4,r8	@ accumulate key material
376	add	r5,r5,r9
377# ifdef	__thumb2__
378	itt	hi
379# endif
380	addhi	r8,r8,#1		@ next counter value
381	strhi	r8,[sp,#4*(12)]	@ save next counter value
382# ifdef	__thumb2__
383	itt	hs
384# endif
385	ldrhs	r8,[r12],#16		@ load input
386	ldrhs	r9,[r12,#-12]
387	add	r6,r6,r10
388	add	r7,r7,r11
389# ifdef	__thumb2__
390	itt	hs
391# endif
392	ldrhs	r10,[r12,#-8]
393	ldrhs	r11,[r12,#-4]
394# if __ARM_ARCH__>=6 && defined(__ARMEB__)
395	rev	r4,r4
396	rev	r5,r5
397	rev	r6,r6
398	rev	r7,r7
399# endif
400# ifdef	__thumb2__
401	itt	hs
402# endif
403	eorhs	r4,r4,r8
404	eorhs	r5,r5,r9
405# ifdef	__thumb2__
406	it	ne
407# endif
408	ldrne	r8,[sp,#4*(32+2)]	@ re-load len
409# ifdef	__thumb2__
410	itt	hs
411# endif
412	eorhs	r6,r6,r10
413	eorhs	r7,r7,r11
414	str	r4,[r14],#16		@ store output
415	str	r5,[r14,#-12]
416# ifdef	__thumb2__
417	it	hs
418# endif
419	subhs	r11,r8,#64		@ len-=64
420	str	r6,[r14,#-8]
421	str	r7,[r14,#-4]
422	bhi	Loop_outer
423
424	beq	Ldone
425# if __ARM_ARCH__<7
426	b	Ltail
427
428.align	4
429Lunaligned:@ unaligned endian-neutral path
430	cmp	r11,#64		@ restore flags
431# endif
432#endif
433#if __ARM_ARCH__<7
434	ldr	r11,[sp,#4*(3)]
435	add	r0,r0,r8		@ accumulate key material
436	add	r1,r1,r9
437	add	r2,r2,r10
438# ifdef	__thumb2__
439	itete	lo
440# endif
441	eorlo	r8,r8,r8		@ zero or ...
442	ldrhsb	r8,[r12],#16			@ ... load input
443	eorlo	r9,r9,r9
444	ldrhsb	r9,[r12,#-12]
445
446	add	r3,r3,r11
447# ifdef	__thumb2__
448	itete	lo
449# endif
450	eorlo	r10,r10,r10
451	ldrhsb	r10,[r12,#-8]
452	eorlo	r11,r11,r11
453	ldrhsb	r11,[r12,#-4]
454
455	eor	r0,r8,r0		@ xor with input (or zero)
456	eor	r1,r9,r1
457# ifdef	__thumb2__
458	itt	hs
459# endif
460	ldrhsb	r8,[r12,#-15]		@ load more input
461	ldrhsb	r9,[r12,#-11]
462	eor	r2,r10,r2
463	strb	r0,[r14],#16		@ store output
464	eor	r3,r11,r3
465# ifdef	__thumb2__
466	itt	hs
467# endif
468	ldrhsb	r10,[r12,#-7]
469	ldrhsb	r11,[r12,#-3]
470	strb	r1,[r14,#-12]
471	eor	r0,r8,r0,lsr#8
472	strb	r2,[r14,#-8]
473	eor	r1,r9,r1,lsr#8
474# ifdef	__thumb2__
475	itt	hs
476# endif
477	ldrhsb	r8,[r12,#-14]		@ load more input
478	ldrhsb	r9,[r12,#-10]
479	strb	r3,[r14,#-4]
480	eor	r2,r10,r2,lsr#8
481	strb	r0,[r14,#-15]
482	eor	r3,r11,r3,lsr#8
483# ifdef	__thumb2__
484	itt	hs
485# endif
486	ldrhsb	r10,[r12,#-6]
487	ldrhsb	r11,[r12,#-2]
488	strb	r1,[r14,#-11]
489	eor	r0,r8,r0,lsr#8
490	strb	r2,[r14,#-7]
491	eor	r1,r9,r1,lsr#8
492# ifdef	__thumb2__
493	itt	hs
494# endif
495	ldrhsb	r8,[r12,#-13]		@ load more input
496	ldrhsb	r9,[r12,#-9]
497	strb	r3,[r14,#-3]
498	eor	r2,r10,r2,lsr#8
499	strb	r0,[r14,#-14]
500	eor	r3,r11,r3,lsr#8
501# ifdef	__thumb2__
502	itt	hs
503# endif
504	ldrhsb	r10,[r12,#-5]
505	ldrhsb	r11,[r12,#-1]
506	strb	r1,[r14,#-10]
507	strb	r2,[r14,#-6]
508	eor	r0,r8,r0,lsr#8
509	strb	r3,[r14,#-2]
510	eor	r1,r9,r1,lsr#8
511	strb	r0,[r14,#-13]
512	eor	r2,r10,r2,lsr#8
513	strb	r1,[r14,#-9]
514	eor	r3,r11,r3,lsr#8
515	strb	r2,[r14,#-5]
516	strb	r3,[r14,#-1]
517	add	r8,sp,#4*(4+0)
518	ldmia	r8,{r8,r9,r10,r11}		@ load key material
519	add	r0,sp,#4*(16+8)
520	add	r4,r4,r8		@ accumulate key material
521	add	r5,r5,r9
522	add	r6,r6,r10
523# ifdef	__thumb2__
524	itete	lo
525# endif
526	eorlo	r8,r8,r8		@ zero or ...
527	ldrhsb	r8,[r12],#16			@ ... load input
528	eorlo	r9,r9,r9
529	ldrhsb	r9,[r12,#-12]
530
531	add	r7,r7,r11
532# ifdef	__thumb2__
533	itete	lo
534# endif
535	eorlo	r10,r10,r10
536	ldrhsb	r10,[r12,#-8]
537	eorlo	r11,r11,r11
538	ldrhsb	r11,[r12,#-4]
539
540	eor	r4,r8,r4		@ xor with input (or zero)
541	eor	r5,r9,r5
542# ifdef	__thumb2__
543	itt	hs
544# endif
545	ldrhsb	r8,[r12,#-15]		@ load more input
546	ldrhsb	r9,[r12,#-11]
547	eor	r6,r10,r6
548	strb	r4,[r14],#16		@ store output
549	eor	r7,r11,r7
550# ifdef	__thumb2__
551	itt	hs
552# endif
553	ldrhsb	r10,[r12,#-7]
554	ldrhsb	r11,[r12,#-3]
555	strb	r5,[r14,#-12]
556	eor	r4,r8,r4,lsr#8
557	strb	r6,[r14,#-8]
558	eor	r5,r9,r5,lsr#8
559# ifdef	__thumb2__
560	itt	hs
561# endif
562	ldrhsb	r8,[r12,#-14]		@ load more input
563	ldrhsb	r9,[r12,#-10]
564	strb	r7,[r14,#-4]
565	eor	r6,r10,r6,lsr#8
566	strb	r4,[r14,#-15]
567	eor	r7,r11,r7,lsr#8
568# ifdef	__thumb2__
569	itt	hs
570# endif
571	ldrhsb	r10,[r12,#-6]
572	ldrhsb	r11,[r12,#-2]
573	strb	r5,[r14,#-11]
574	eor	r4,r8,r4,lsr#8
575	strb	r6,[r14,#-7]
576	eor	r5,r9,r5,lsr#8
577# ifdef	__thumb2__
578	itt	hs
579# endif
580	ldrhsb	r8,[r12,#-13]		@ load more input
581	ldrhsb	r9,[r12,#-9]
582	strb	r7,[r14,#-3]
583	eor	r6,r10,r6,lsr#8
584	strb	r4,[r14,#-14]
585	eor	r7,r11,r7,lsr#8
586# ifdef	__thumb2__
587	itt	hs
588# endif
589	ldrhsb	r10,[r12,#-5]
590	ldrhsb	r11,[r12,#-1]
591	strb	r5,[r14,#-10]
592	strb	r6,[r14,#-6]
593	eor	r4,r8,r4,lsr#8
594	strb	r7,[r14,#-2]
595	eor	r5,r9,r5,lsr#8
596	strb	r4,[r14,#-13]
597	eor	r6,r10,r6,lsr#8
598	strb	r5,[r14,#-9]
599	eor	r7,r11,r7,lsr#8
600	strb	r6,[r14,#-5]
601	strb	r7,[r14,#-1]
602	add	r8,sp,#4*(4+4)
603	ldmia	r8,{r8,r9,r10,r11}		@ load key material
604	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}		@ load second half
605# ifdef	__thumb2__
606	itt	hi
607# endif
608	strhi	r10,[sp,#4*(16+10)]		@ copy "rx"
609	strhi	r11,[sp,#4*(16+11)]		@ copy "rx"
610	add	r0,r0,r8		@ accumulate key material
611	add	r1,r1,r9
612	add	r2,r2,r10
613# ifdef	__thumb2__
614	itete	lo
615# endif
616	eorlo	r8,r8,r8		@ zero or ...
617	ldrhsb	r8,[r12],#16			@ ... load input
618	eorlo	r9,r9,r9
619	ldrhsb	r9,[r12,#-12]
620
621	add	r3,r3,r11
622# ifdef	__thumb2__
623	itete	lo
624# endif
625	eorlo	r10,r10,r10
626	ldrhsb	r10,[r12,#-8]
627	eorlo	r11,r11,r11
628	ldrhsb	r11,[r12,#-4]
629
630	eor	r0,r8,r0		@ xor with input (or zero)
631	eor	r1,r9,r1
632# ifdef	__thumb2__
633	itt	hs
634# endif
635	ldrhsb	r8,[r12,#-15]		@ load more input
636	ldrhsb	r9,[r12,#-11]
637	eor	r2,r10,r2
638	strb	r0,[r14],#16		@ store output
639	eor	r3,r11,r3
640# ifdef	__thumb2__
641	itt	hs
642# endif
643	ldrhsb	r10,[r12,#-7]
644	ldrhsb	r11,[r12,#-3]
645	strb	r1,[r14,#-12]
646	eor	r0,r8,r0,lsr#8
647	strb	r2,[r14,#-8]
648	eor	r1,r9,r1,lsr#8
649# ifdef	__thumb2__
650	itt	hs
651# endif
652	ldrhsb	r8,[r12,#-14]		@ load more input
653	ldrhsb	r9,[r12,#-10]
654	strb	r3,[r14,#-4]
655	eor	r2,r10,r2,lsr#8
656	strb	r0,[r14,#-15]
657	eor	r3,r11,r3,lsr#8
658# ifdef	__thumb2__
659	itt	hs
660# endif
661	ldrhsb	r10,[r12,#-6]
662	ldrhsb	r11,[r12,#-2]
663	strb	r1,[r14,#-11]
664	eor	r0,r8,r0,lsr#8
665	strb	r2,[r14,#-7]
666	eor	r1,r9,r1,lsr#8
667# ifdef	__thumb2__
668	itt	hs
669# endif
670	ldrhsb	r8,[r12,#-13]		@ load more input
671	ldrhsb	r9,[r12,#-9]
672	strb	r3,[r14,#-3]
673	eor	r2,r10,r2,lsr#8
674	strb	r0,[r14,#-14]
675	eor	r3,r11,r3,lsr#8
676# ifdef	__thumb2__
677	itt	hs
678# endif
679	ldrhsb	r10,[r12,#-5]
680	ldrhsb	r11,[r12,#-1]
681	strb	r1,[r14,#-10]
682	strb	r2,[r14,#-6]
683	eor	r0,r8,r0,lsr#8
684	strb	r3,[r14,#-2]
685	eor	r1,r9,r1,lsr#8
686	strb	r0,[r14,#-13]
687	eor	r2,r10,r2,lsr#8
688	strb	r1,[r14,#-9]
689	eor	r3,r11,r3,lsr#8
690	strb	r2,[r14,#-5]
691	strb	r3,[r14,#-1]
692	add	r8,sp,#4*(4+8)
693	ldmia	r8,{r8,r9,r10,r11}		@ load key material
694	add	r4,r4,r8		@ accumulate key material
695# ifdef	__thumb2__
696	itt	hi
697# endif
698	addhi	r8,r8,#1			@ next counter value
699	strhi	r8,[sp,#4*(12)]		@ save next counter value
700	add	r5,r5,r9
701	add	r6,r6,r10
702# ifdef	__thumb2__
703	itete	lo
704# endif
705	eorlo	r8,r8,r8		@ zero or ...
706	ldrhsb	r8,[r12],#16			@ ... load input
707	eorlo	r9,r9,r9
708	ldrhsb	r9,[r12,#-12]
709
710	add	r7,r7,r11
711# ifdef	__thumb2__
712	itete	lo
713# endif
714	eorlo	r10,r10,r10
715	ldrhsb	r10,[r12,#-8]
716	eorlo	r11,r11,r11
717	ldrhsb	r11,[r12,#-4]
718
719	eor	r4,r8,r4		@ xor with input (or zero)
720	eor	r5,r9,r5
721# ifdef	__thumb2__
722	itt	hs
723# endif
724	ldrhsb	r8,[r12,#-15]		@ load more input
725	ldrhsb	r9,[r12,#-11]
726	eor	r6,r10,r6
727	strb	r4,[r14],#16		@ store output
728	eor	r7,r11,r7
729# ifdef	__thumb2__
730	itt	hs
731# endif
732	ldrhsb	r10,[r12,#-7]
733	ldrhsb	r11,[r12,#-3]
734	strb	r5,[r14,#-12]
735	eor	r4,r8,r4,lsr#8
736	strb	r6,[r14,#-8]
737	eor	r5,r9,r5,lsr#8
738# ifdef	__thumb2__
739	itt	hs
740# endif
741	ldrhsb	r8,[r12,#-14]		@ load more input
742	ldrhsb	r9,[r12,#-10]
743	strb	r7,[r14,#-4]
744	eor	r6,r10,r6,lsr#8
745	strb	r4,[r14,#-15]
746	eor	r7,r11,r7,lsr#8
747# ifdef	__thumb2__
748	itt	hs
749# endif
750	ldrhsb	r10,[r12,#-6]
751	ldrhsb	r11,[r12,#-2]
752	strb	r5,[r14,#-11]
753	eor	r4,r8,r4,lsr#8
754	strb	r6,[r14,#-7]
755	eor	r5,r9,r5,lsr#8
756# ifdef	__thumb2__
757	itt	hs
758# endif
759	ldrhsb	r8,[r12,#-13]		@ load more input
760	ldrhsb	r9,[r12,#-9]
761	strb	r7,[r14,#-3]
762	eor	r6,r10,r6,lsr#8
763	strb	r4,[r14,#-14]
764	eor	r7,r11,r7,lsr#8
765# ifdef	__thumb2__
766	itt	hs
767# endif
768	ldrhsb	r10,[r12,#-5]
769	ldrhsb	r11,[r12,#-1]
770	strb	r5,[r14,#-10]
771	strb	r6,[r14,#-6]
772	eor	r4,r8,r4,lsr#8
773	strb	r7,[r14,#-2]
774	eor	r5,r9,r5,lsr#8
775	strb	r4,[r14,#-13]
776	eor	r6,r10,r6,lsr#8
777	strb	r5,[r14,#-9]
778	eor	r7,r11,r7,lsr#8
779	strb	r6,[r14,#-5]
780	strb	r7,[r14,#-1]
781# ifdef	__thumb2__
782	it	ne
783# endif
784	ldrne	r8,[sp,#4*(32+2)]		@ re-load len
785# ifdef	__thumb2__
786	it	hs
787# endif
788	subhs	r11,r8,#64			@ len-=64
789	bhi	Loop_outer
790
791	beq	Ldone
792#endif
793
794Ltail:
795	ldr	r12,[sp,#4*(32+1)]	@ load inp
796	add	r9,sp,#4*(0)
797	ldr	r14,[sp,#4*(32+0)]	@ load out
798
799Loop_tail:
800	ldrb	r10,[r9],#1	@ read buffer on stack
801	ldrb	r11,[r12],#1		@ read input
802	subs	r8,r8,#1
803	eor	r11,r11,r10
804	strb	r11,[r14],#1		@ store output
805	bne	Loop_tail
806
807Ldone:
808	add	sp,sp,#4*(32+3)
809Lno_data:
810	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
811
812#if __ARM_MAX_ARCH__>=7
813
814
815
816#ifdef __thumb2__
817.thumb_func	ChaCha20_neon
818#endif
819.align	5
820ChaCha20_neon:
821	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
822	stmdb	sp!,{r0,r1,r2,r4-r11,lr}
823LChaCha20_neon:
824	adr	r14,Lsigma
825	vstmdb	sp!,{d8,d9,d10,d11,d12,d13,d14,d15}		@ ABI spec says so
826	stmdb	sp!,{r0,r1,r2,r3}
827
828	vld1.32	{q1,q2},[r3]		@ load key
829	ldmia	r3,{r4,r5,r6,r7,r8,r9,r10,r11}		@ load key
830
831	sub	sp,sp,#4*(16+16)
832	vld1.32	{q3},[r12]		@ load counter and nonce
833	add	r12,sp,#4*8
834	ldmia	r14,{r0,r1,r2,r3}		@ load sigma
835	vld1.32	{q0},[r14]!		@ load sigma
836	vld1.32	{q12},[r14]		@ one
837	vst1.32	{q2,q3},[r12]		@ copy 1/2key|counter|nonce
838	vst1.32	{q0,q1},[sp]		@ copy sigma|1/2key
839
840	str	r10,[sp,#4*(16+10)]	@ off-load "rx"
841	str	r11,[sp,#4*(16+11)]	@ off-load "rx"
842	vshl.i32	d26,d24,#1	@ two
843	vstr	d24,[sp,#4*(16+0)]
844	vshl.i32	d28,d24,#2	@ four
845	vstr	d26,[sp,#4*(16+2)]
846	vmov	q4,q0
847	vstr	d28,[sp,#4*(16+4)]
848	vmov	q8,q0
849	vmov	q5,q1
850	vmov	q9,q1
851	b	Loop_neon_enter
852
853.align	4
854Loop_neon_outer:
855	ldmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9}		@ load key material
856	cmp	r11,#64*2		@ if len<=64*2
857	bls	Lbreak_neon		@ switch to integer-only
858	vmov	q4,q0
859	str	r11,[sp,#4*(32+2)]	@ save len
860	vmov	q8,q0
861	str	r12,  [sp,#4*(32+1)]	@ save inp
862	vmov	q5,q1
863	str	r14,  [sp,#4*(32+0)]	@ save out
864	vmov	q9,q1
865Loop_neon_enter:
866	ldr	r11, [sp,#4*(15)]
867	vadd.i32	q7,q3,q12		@ counter+1
868	ldr	r12,[sp,#4*(12)]	@ modulo-scheduled load
869	vmov	q6,q2
870	ldr	r10, [sp,#4*(13)]
871	vmov	q10,q2
872	ldr	r14,[sp,#4*(14)]
873	vadd.i32	q11,q7,q12		@ counter+2
874	str	r11, [sp,#4*(16+15)]
875	mov	r11,#10
876	add	r12,r12,#3	@ counter+3
877	b	Loop_neon
878
879.align	4
880Loop_neon:
881	subs	r11,r11,#1
882	vadd.i32	q0,q0,q1
883	add	r0,r0,r4
884	vadd.i32	q4,q4,q5
885	mov	r12,r12,ror#16
886	vadd.i32	q8,q8,q9
887	add	r1,r1,r5
888	veor	q3,q3,q0
889	mov	r10,r10,ror#16
890	veor	q7,q7,q4
891	eor	r12,r12,r0,ror#16
892	veor	q11,q11,q8
893	eor	r10,r10,r1,ror#16
894	vrev32.16	q3,q3
895	add	r8,r8,r12
896	vrev32.16	q7,q7
897	mov	r4,r4,ror#20
898	vrev32.16	q11,q11
899	add	r9,r9,r10
900	vadd.i32	q2,q2,q3
901	mov	r5,r5,ror#20
902	vadd.i32	q6,q6,q7
903	eor	r4,r4,r8,ror#20
904	vadd.i32	q10,q10,q11
905	eor	r5,r5,r9,ror#20
906	veor	q12,q1,q2
907	add	r0,r0,r4
908	veor	q13,q5,q6
909	mov	r12,r12,ror#24
910	veor	q14,q9,q10
911	add	r1,r1,r5
912	vshr.u32	q1,q12,#20
913	mov	r10,r10,ror#24
914	vshr.u32	q5,q13,#20
915	eor	r12,r12,r0,ror#24
916	vshr.u32	q9,q14,#20
917	eor	r10,r10,r1,ror#24
918	vsli.32	q1,q12,#12
919	add	r8,r8,r12
920	vsli.32	q5,q13,#12
921	mov	r4,r4,ror#25
922	vsli.32	q9,q14,#12
923	add	r9,r9,r10
924	vadd.i32	q0,q0,q1
925	mov	r5,r5,ror#25
926	vadd.i32	q4,q4,q5
927	str	r10,[sp,#4*(16+13)]
928	vadd.i32	q8,q8,q9
929	ldr	r10,[sp,#4*(16+15)]
930	veor	q12,q3,q0
931	eor	r4,r4,r8,ror#25
932	veor	q13,q7,q4
933	eor	r5,r5,r9,ror#25
934	veor	q14,q11,q8
935	str	r8,[sp,#4*(16+8)]
936	vshr.u32	q3,q12,#24
937	ldr	r8,[sp,#4*(16+10)]
938	vshr.u32	q7,q13,#24
939	add	r2,r2,r6
940	vshr.u32	q11,q14,#24
941	mov	r14,r14,ror#16
942	vsli.32	q3,q12,#8
943	str	r9,[sp,#4*(16+9)]
944	vsli.32	q7,q13,#8
945	ldr	r9,[sp,#4*(16+11)]
946	vsli.32	q11,q14,#8
947	add	r3,r3,r7
948	vadd.i32	q2,q2,q3
949	mov	r10,r10,ror#16
950	vadd.i32	q6,q6,q7
951	eor	r14,r14,r2,ror#16
952	vadd.i32	q10,q10,q11
953	eor	r10,r10,r3,ror#16
954	veor	q12,q1,q2
955	add	r8,r8,r14
956	veor	q13,q5,q6
957	mov	r6,r6,ror#20
958	veor	q14,q9,q10
959	add	r9,r9,r10
960	vshr.u32	q1,q12,#25
961	mov	r7,r7,ror#20
962	vshr.u32	q5,q13,#25
963	eor	r6,r6,r8,ror#20
964	vshr.u32	q9,q14,#25
965	eor	r7,r7,r9,ror#20
966	vsli.32	q1,q12,#7
967	add	r2,r2,r6
968	vsli.32	q5,q13,#7
969	mov	r14,r14,ror#24
970	vsli.32	q9,q14,#7
971	add	r3,r3,r7
972	vext.8	q2,q2,q2,#8
973	mov	r10,r10,ror#24
974	vext.8	q6,q6,q6,#8
975	eor	r14,r14,r2,ror#24
976	vext.8	q10,q10,q10,#8
977	eor	r10,r10,r3,ror#24
978	vext.8	q1,q1,q1,#4
979	add	r8,r8,r14
980	vext.8	q5,q5,q5,#4
981	mov	r6,r6,ror#25
982	vext.8	q9,q9,q9,#4
983	add	r9,r9,r10
984	vext.8	q3,q3,q3,#12
985	mov	r7,r7,ror#25
986	vext.8	q7,q7,q7,#12
987	eor	r6,r6,r8,ror#25
988	vext.8	q11,q11,q11,#12
989	eor	r7,r7,r9,ror#25
990	vadd.i32	q0,q0,q1
991	add	r0,r0,r5
992	vadd.i32	q4,q4,q5
993	mov	r10,r10,ror#16
994	vadd.i32	q8,q8,q9
995	add	r1,r1,r6
996	veor	q3,q3,q0
997	mov	r12,r12,ror#16
998	veor	q7,q7,q4
999	eor	r10,r10,r0,ror#16
1000	veor	q11,q11,q8
1001	eor	r12,r12,r1,ror#16
1002	vrev32.16	q3,q3
1003	add	r8,r8,r10
1004	vrev32.16	q7,q7
1005	mov	r5,r5,ror#20
1006	vrev32.16	q11,q11
1007	add	r9,r9,r12
1008	vadd.i32	q2,q2,q3
1009	mov	r6,r6,ror#20
1010	vadd.i32	q6,q6,q7
1011	eor	r5,r5,r8,ror#20
1012	vadd.i32	q10,q10,q11
1013	eor	r6,r6,r9,ror#20
1014	veor	q12,q1,q2
1015	add	r0,r0,r5
1016	veor	q13,q5,q6
1017	mov	r10,r10,ror#24
1018	veor	q14,q9,q10
1019	add	r1,r1,r6
1020	vshr.u32	q1,q12,#20
1021	mov	r12,r12,ror#24
1022	vshr.u32	q5,q13,#20
1023	eor	r10,r10,r0,ror#24
1024	vshr.u32	q9,q14,#20
1025	eor	r12,r12,r1,ror#24
1026	vsli.32	q1,q12,#12
1027	add	r8,r8,r10
1028	vsli.32	q5,q13,#12
1029	mov	r5,r5,ror#25
1030	vsli.32	q9,q14,#12
1031	str	r10,[sp,#4*(16+15)]
1032	vadd.i32	q0,q0,q1
1033	ldr	r10,[sp,#4*(16+13)]
1034	vadd.i32	q4,q4,q5
1035	add	r9,r9,r12
1036	vadd.i32	q8,q8,q9
1037	mov	r6,r6,ror#25
1038	veor	q12,q3,q0
1039	eor	r5,r5,r8,ror#25
1040	veor	q13,q7,q4
1041	eor	r6,r6,r9,ror#25
1042	veor	q14,q11,q8
1043	str	r8,[sp,#4*(16+10)]
1044	vshr.u32	q3,q12,#24
1045	ldr	r8,[sp,#4*(16+8)]
1046	vshr.u32	q7,q13,#24
1047	add	r2,r2,r7
1048	vshr.u32	q11,q14,#24
1049	mov	r10,r10,ror#16
1050	vsli.32	q3,q12,#8
1051	str	r9,[sp,#4*(16+11)]
1052	vsli.32	q7,q13,#8
1053	ldr	r9,[sp,#4*(16+9)]
1054	vsli.32	q11,q14,#8
1055	add	r3,r3,r4
1056	vadd.i32	q2,q2,q3
1057	mov	r14,r14,ror#16
1058	vadd.i32	q6,q6,q7
1059	eor	r10,r10,r2,ror#16
1060	vadd.i32	q10,q10,q11
1061	eor	r14,r14,r3,ror#16
1062	veor	q12,q1,q2
1063	add	r8,r8,r10
1064	veor	q13,q5,q6
1065	mov	r7,r7,ror#20
1066	veor	q14,q9,q10
1067	add	r9,r9,r14
1068	vshr.u32	q1,q12,#25
1069	mov	r4,r4,ror#20
1070	vshr.u32	q5,q13,#25
1071	eor	r7,r7,r8,ror#20
1072	vshr.u32	q9,q14,#25
1073	eor	r4,r4,r9,ror#20
1074	vsli.32	q1,q12,#7
1075	add	r2,r2,r7
1076	vsli.32	q5,q13,#7
1077	mov	r10,r10,ror#24
1078	vsli.32	q9,q14,#7
1079	add	r3,r3,r4
1080	vext.8	q2,q2,q2,#8
1081	mov	r14,r14,ror#24
1082	vext.8	q6,q6,q6,#8
1083	eor	r10,r10,r2,ror#24
1084	vext.8	q10,q10,q10,#8
1085	eor	r14,r14,r3,ror#24
1086	vext.8	q1,q1,q1,#12
1087	add	r8,r8,r10
1088	vext.8	q5,q5,q5,#12
1089	mov	r7,r7,ror#25
1090	vext.8	q9,q9,q9,#12
1091	add	r9,r9,r14
1092	vext.8	q3,q3,q3,#4
1093	mov	r4,r4,ror#25
1094	vext.8	q7,q7,q7,#4
1095	eor	r7,r7,r8,ror#25
1096	vext.8	q11,q11,q11,#4
1097	eor	r4,r4,r9,ror#25
1098	bne	Loop_neon
1099
1100	add	r11,sp,#32
1101	vld1.32	{q12,q13},[sp]		@ load key material
1102	vld1.32	{q14,q15},[r11]
1103
1104	ldr	r11,[sp,#4*(32+2)]	@ load len
1105
1106	str	r8, [sp,#4*(16+8)]	@ modulo-scheduled store
1107	str	r9, [sp,#4*(16+9)]
1108	str	r12,[sp,#4*(16+12)]
1109	str	r10, [sp,#4*(16+13)]
1110	str	r14,[sp,#4*(16+14)]
1111
1112	@ at this point we have first half of 512-bit result in
1113	@ rx and second half at sp+4*(16+8)
1114
1115	ldr	r12,[sp,#4*(32+1)]	@ load inp
1116	ldr	r14,[sp,#4*(32+0)]	@ load out
1117
1118	vadd.i32	q0,q0,q12		@ accumulate key material
1119	vadd.i32	q4,q4,q12
1120	vadd.i32	q8,q8,q12
1121	vldr	d24,[sp,#4*(16+0)]	@ one
1122
1123	vadd.i32	q1,q1,q13
1124	vadd.i32	q5,q5,q13
1125	vadd.i32	q9,q9,q13
1126	vldr	d26,[sp,#4*(16+2)]	@ two
1127
1128	vadd.i32	q2,q2,q14
1129	vadd.i32	q6,q6,q14
1130	vadd.i32	q10,q10,q14
1131	vadd.i32	d14,d14,d24	@ counter+1
1132	vadd.i32	d22,d22,d26	@ counter+2
1133
1134	vadd.i32	q3,q3,q15
1135	vadd.i32	q7,q7,q15
1136	vadd.i32	q11,q11,q15
1137
1138	cmp	r11,#64*4
1139	blo	Ltail_neon
1140
1141	vld1.8	{q12,q13},[r12]!	@ load input
1142	mov	r11,sp
1143	vld1.8	{q14,q15},[r12]!
1144	veor	q0,q0,q12		@ xor with input
1145	veor	q1,q1,q13
1146	vld1.8	{q12,q13},[r12]!
1147	veor	q2,q2,q14
1148	veor	q3,q3,q15
1149	vld1.8	{q14,q15},[r12]!
1150
1151	veor	q4,q4,q12
1152	vst1.8	{q0,q1},[r14]!	@ store output
1153	veor	q5,q5,q13
1154	vld1.8	{q12,q13},[r12]!
1155	veor	q6,q6,q14
1156	vst1.8	{q2,q3},[r14]!
1157	veor	q7,q7,q15
1158	vld1.8	{q14,q15},[r12]!
1159
1160	veor	q8,q8,q12
1161	vld1.32	{q0,q1},[r11]!	@ load for next iteration
1162	veor	d25,d25,d25
1163	vldr	d24,[sp,#4*(16+4)]	@ four
1164	veor	q9,q9,q13
1165	vld1.32	{q2,q3},[r11]
1166	veor	q10,q10,q14
1167	vst1.8	{q4,q5},[r14]!
1168	veor	q11,q11,q15
1169	vst1.8	{q6,q7},[r14]!
1170
1171	vadd.i32	d6,d6,d24	@ next counter value
1172	vldr	d24,[sp,#4*(16+0)]	@ one
1173
1174	ldmia	sp,{r8,r9,r10,r11}	@ load key material
1175	add	r0,r0,r8	@ accumulate key material
1176	ldr	r8,[r12],#16		@ load input
1177	vst1.8	{q8,q9},[r14]!
1178	add	r1,r1,r9
1179	ldr	r9,[r12,#-12]
1180	vst1.8	{q10,q11},[r14]!
1181	add	r2,r2,r10
1182	ldr	r10,[r12,#-8]
1183	add	r3,r3,r11
1184	ldr	r11,[r12,#-4]
1185# ifdef	__ARMEB__
1186	rev	r0,r0
1187	rev	r1,r1
1188	rev	r2,r2
1189	rev	r3,r3
1190# endif
1191	eor	r0,r0,r8	@ xor with input
1192	add	r8,sp,#4*(4)
1193	eor	r1,r1,r9
1194	str	r0,[r14],#16		@ store output
1195	eor	r2,r2,r10
1196	str	r1,[r14,#-12]
1197	eor	r3,r3,r11
1198	ldmia	r8,{r8,r9,r10,r11}	@ load key material
1199	str	r2,[r14,#-8]
1200	str	r3,[r14,#-4]
1201
1202	add	r4,r4,r8	@ accumulate key material
1203	ldr	r8,[r12],#16		@ load input
1204	add	r5,r5,r9
1205	ldr	r9,[r12,#-12]
1206	add	r6,r6,r10
1207	ldr	r10,[r12,#-8]
1208	add	r7,r7,r11
1209	ldr	r11,[r12,#-4]
1210# ifdef	__ARMEB__
1211	rev	r4,r4
1212	rev	r5,r5
1213	rev	r6,r6
1214	rev	r7,r7
1215# endif
1216	eor	r4,r4,r8
1217	add	r8,sp,#4*(8)
1218	eor	r5,r5,r9
1219	str	r4,[r14],#16		@ store output
1220	eor	r6,r6,r10
1221	str	r5,[r14,#-12]
1222	eor	r7,r7,r11
1223	ldmia	r8,{r8,r9,r10,r11}	@ load key material
1224	str	r6,[r14,#-8]
1225	add	r0,sp,#4*(16+8)
1226	str	r7,[r14,#-4]
1227
1228	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
1229
1230	add	r0,r0,r8	@ accumulate key material
1231	ldr	r8,[r12],#16		@ load input
1232	add	r1,r1,r9
1233	ldr	r9,[r12,#-12]
1234# ifdef	__thumb2__
1235	it	hi
1236# endif
1237	strhi	r10,[sp,#4*(16+10)]	@ copy "rx" while at it
1238	add	r2,r2,r10
1239	ldr	r10,[r12,#-8]
1240# ifdef	__thumb2__
1241	it	hi
1242# endif
1243	strhi	r11,[sp,#4*(16+11)]	@ copy "rx" while at it
1244	add	r3,r3,r11
1245	ldr	r11,[r12,#-4]
1246# ifdef	__ARMEB__
1247	rev	r0,r0
1248	rev	r1,r1
1249	rev	r2,r2
1250	rev	r3,r3
1251# endif
1252	eor	r0,r0,r8
1253	add	r8,sp,#4*(12)
1254	eor	r1,r1,r9
1255	str	r0,[r14],#16		@ store output
1256	eor	r2,r2,r10
1257	str	r1,[r14,#-12]
1258	eor	r3,r3,r11
1259	ldmia	r8,{r8,r9,r10,r11}	@ load key material
1260	str	r2,[r14,#-8]
1261	str	r3,[r14,#-4]
1262
1263	add	r4,r4,r8	@ accumulate key material
1264	add	r8,r8,#4		@ next counter value
1265	add	r5,r5,r9
1266	str	r8,[sp,#4*(12)]	@ save next counter value
1267	ldr	r8,[r12],#16		@ load input
1268	add	r6,r6,r10
1269	add	r4,r4,#3		@ counter+3
1270	ldr	r9,[r12,#-12]
1271	add	r7,r7,r11
1272	ldr	r10,[r12,#-8]
1273	ldr	r11,[r12,#-4]
1274# ifdef	__ARMEB__
1275	rev	r4,r4
1276	rev	r5,r5
1277	rev	r6,r6
1278	rev	r7,r7
1279# endif
1280	eor	r4,r4,r8
1281# ifdef	__thumb2__
1282	it	hi
1283# endif
1284	ldrhi	r8,[sp,#4*(32+2)]	@ re-load len
1285	eor	r5,r5,r9
1286	eor	r6,r6,r10
1287	str	r4,[r14],#16		@ store output
1288	eor	r7,r7,r11
1289	str	r5,[r14,#-12]
1290	sub	r11,r8,#64*4	@ len-=64*4
1291	str	r6,[r14,#-8]
1292	str	r7,[r14,#-4]
1293	bhi	Loop_neon_outer
1294
1295	b	Ldone_neon
1296
1297.align	4
1298Lbreak_neon:
1299	@ harmonize NEON and integer-only stack frames: load data
1300	@ from NEON frame, but save to integer-only one; distance
1301	@ between the two is 4*(32+4+16-32)=4*(20).
1302
1303	str	r11, [sp,#4*(20+32+2)]	@ save len
1304	add	r11,sp,#4*(32+4)
1305	str	r12,   [sp,#4*(20+32+1)]	@ save inp
1306	str	r14,   [sp,#4*(20+32+0)]	@ save out
1307
1308	ldr	r12,[sp,#4*(16+10)]
1309	ldr	r14,[sp,#4*(16+11)]
1310	vldmia	r11,{d8,d9,d10,d11,d12,d13,d14,d15}			@ fulfill ABI requirement
1311	str	r12,[sp,#4*(20+16+10)]	@ copy "rx"
1312	str	r14,[sp,#4*(20+16+11)]	@ copy "rx"
1313
1314	ldr	r11, [sp,#4*(15)]
1315	ldr	r12,[sp,#4*(12)]		@ modulo-scheduled load
1316	ldr	r10, [sp,#4*(13)]
1317	ldr	r14,[sp,#4*(14)]
1318	str	r11, [sp,#4*(20+16+15)]
1319	add	r11,sp,#4*(20)
1320	vst1.32	{q0,q1},[r11]!		@ copy key
1321	add	sp,sp,#4*(20)			@ switch frame
1322	vst1.32	{q2,q3},[r11]
1323	mov	r11,#10
1324	b	Loop				@ go integer-only
1325
1326.align	4
1327Ltail_neon:
1328	cmp	r11,#64*3
1329	bhs	L192_or_more_neon
1330	cmp	r11,#64*2
1331	bhs	L128_or_more_neon
1332	cmp	r11,#64*1
1333	bhs	L64_or_more_neon
1334
1335	add	r8,sp,#4*(8)
1336	vst1.8	{q0,q1},[sp]
1337	add	r10,sp,#4*(0)
1338	vst1.8	{q2,q3},[r8]
1339	b	Loop_tail_neon
1340
1341.align	4
1342L64_or_more_neon:
1343	vld1.8	{q12,q13},[r12]!
1344	vld1.8	{q14,q15},[r12]!
1345	veor	q0,q0,q12
1346	veor	q1,q1,q13
1347	veor	q2,q2,q14
1348	veor	q3,q3,q15
1349	vst1.8	{q0,q1},[r14]!
1350	vst1.8	{q2,q3},[r14]!
1351
1352	beq	Ldone_neon
1353
1354	add	r8,sp,#4*(8)
1355	vst1.8	{q4,q5},[sp]
1356	add	r10,sp,#4*(0)
1357	vst1.8	{q6,q7},[r8]
1358	sub	r11,r11,#64*1	@ len-=64*1
1359	b	Loop_tail_neon
1360
1361.align	4
1362L128_or_more_neon:
1363	vld1.8	{q12,q13},[r12]!
1364	vld1.8	{q14,q15},[r12]!
1365	veor	q0,q0,q12
1366	veor	q1,q1,q13
1367	vld1.8	{q12,q13},[r12]!
1368	veor	q2,q2,q14
1369	veor	q3,q3,q15
1370	vld1.8	{q14,q15},[r12]!
1371
1372	veor	q4,q4,q12
1373	veor	q5,q5,q13
1374	vst1.8	{q0,q1},[r14]!
1375	veor	q6,q6,q14
1376	vst1.8	{q2,q3},[r14]!
1377	veor	q7,q7,q15
1378	vst1.8	{q4,q5},[r14]!
1379	vst1.8	{q6,q7},[r14]!
1380
1381	beq	Ldone_neon
1382
1383	add	r8,sp,#4*(8)
1384	vst1.8	{q8,q9},[sp]
1385	add	r10,sp,#4*(0)
1386	vst1.8	{q10,q11},[r8]
1387	sub	r11,r11,#64*2	@ len-=64*2
1388	b	Loop_tail_neon
1389
1390.align	4
1391L192_or_more_neon:
1392	vld1.8	{q12,q13},[r12]!
1393	vld1.8	{q14,q15},[r12]!
1394	veor	q0,q0,q12
1395	veor	q1,q1,q13
1396	vld1.8	{q12,q13},[r12]!
1397	veor	q2,q2,q14
1398	veor	q3,q3,q15
1399	vld1.8	{q14,q15},[r12]!
1400
1401	veor	q4,q4,q12
1402	veor	q5,q5,q13
1403	vld1.8	{q12,q13},[r12]!
1404	veor	q6,q6,q14
1405	vst1.8	{q0,q1},[r14]!
1406	veor	q7,q7,q15
1407	vld1.8	{q14,q15},[r12]!
1408
1409	veor	q8,q8,q12
1410	vst1.8	{q2,q3},[r14]!
1411	veor	q9,q9,q13
1412	vst1.8	{q4,q5},[r14]!
1413	veor	q10,q10,q14
1414	vst1.8	{q6,q7},[r14]!
1415	veor	q11,q11,q15
1416	vst1.8	{q8,q9},[r14]!
1417	vst1.8	{q10,q11},[r14]!
1418
1419	beq	Ldone_neon
1420
1421	ldmia	sp,{r8,r9,r10,r11}	@ load key material
1422	add	r0,r0,r8	@ accumulate key material
1423	add	r8,sp,#4*(4)
1424	add	r1,r1,r9
1425	add	r2,r2,r10
1426	add	r3,r3,r11
1427	ldmia	r8,{r8,r9,r10,r11}	@ load key material
1428
1429	add	r4,r4,r8	@ accumulate key material
1430	add	r8,sp,#4*(8)
1431	add	r5,r5,r9
1432	add	r6,r6,r10
1433	add	r7,r7,r11
1434	ldmia	r8,{r8,r9,r10,r11}	@ load key material
1435# ifdef	__ARMEB__
1436	rev	r0,r0
1437	rev	r1,r1
1438	rev	r2,r2
1439	rev	r3,r3
1440	rev	r4,r4
1441	rev	r5,r5
1442	rev	r6,r6
1443	rev	r7,r7
1444# endif
1445	stmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7}
1446	add	r0,sp,#4*(16+8)
1447
1448	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
1449
1450	add	r0,r0,r8	@ accumulate key material
1451	add	r8,sp,#4*(12)
1452	add	r1,r1,r9
1453	add	r2,r2,r10
1454	add	r3,r3,r11
1455	ldmia	r8,{r8,r9,r10,r11}	@ load key material
1456
1457	add	r4,r4,r8	@ accumulate key material
1458	add	r8,sp,#4*(8)
1459	add	r5,r5,r9
1460	add	r4,r4,#3		@ counter+3
1461	add	r6,r6,r10
1462	add	r7,r7,r11
1463	ldr	r11,[sp,#4*(32+2)]	@ re-load len
1464# ifdef	__ARMEB__
1465	rev	r0,r0
1466	rev	r1,r1
1467	rev	r2,r2
1468	rev	r3,r3
1469	rev	r4,r4
1470	rev	r5,r5
1471	rev	r6,r6
1472	rev	r7,r7
1473# endif
1474	stmia	r8,{r0,r1,r2,r3,r4,r5,r6,r7}
1475	add	r10,sp,#4*(0)
1476	sub	r11,r11,#64*3	@ len-=64*3
1477
1478Loop_tail_neon:
1479	ldrb	r8,[r10],#1	@ read buffer on stack
1480	ldrb	r9,[r12],#1		@ read input
1481	subs	r11,r11,#1
1482	eor	r8,r8,r9
1483	strb	r8,[r14],#1		@ store output
1484	bne	Loop_tail_neon
1485
1486Ldone_neon:
1487	add	sp,sp,#4*(32+4)
1488	vldmia	sp,{d8,d9,d10,d11,d12,d13,d14,d15}
1489	add	sp,sp,#4*(16+3)
1490	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
1491
1492.comm	_OPENSSL_armcap_P,4
1493.non_lazy_symbol_pointer
1494OPENSSL_armcap_P:
1495.indirect_symbol	_OPENSSL_armcap_P
1496.long	0
1497#endif
1498#endif  // !OPENSSL_NO_ASM
1499