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