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