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