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