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