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