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