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