Home | History | Annotate | Download | only in chacha
      1 #include <openssl/arm_arch.h>
      2 
      3 @ Silence ARMv8 deprecated IT instruction warnings. This file is used by both
      4 @ ARMv7 and ARMv8 processors and does not use ARMv8 instructions.
      5 
      6 
      7 .text
      8 #if defined(__thumb2__) || defined(__clang__)
      9 .syntax	unified
     10 #endif
     11 #if defined(__thumb2__)
     12 .thumb
     13 #else
     14 .code	32
     15 #endif
     16 
     17 #if defined(__thumb2__) || defined(__clang__)
     18 #define ldrhsb	ldrbhs
     19 #endif
     20 
     21 .align	5
     22 Lsigma:
     23 .long	0x61707865,0x3320646e,0x79622d32,0x6b206574	@ endian-neutral
     24 Lone:
     25 .long	1,0,0,0
     26 #if __ARM_MAX_ARCH__>=7
     27 LOPENSSL_armcap:
     28 .word	OPENSSL_armcap_P-LChaCha20_ctr32
     29 #else
     30 .word	-1
     31 #endif
     32 
     33 .globl	_ChaCha20_ctr32
     34 .private_extern	_ChaCha20_ctr32
     35 #ifdef __thumb2__
     36 .thumb_func	_ChaCha20_ctr32
     37 #endif
     38 .align	5
     39 _ChaCha20_ctr32:
     40 LChaCha20_ctr32:
     41 	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
     42 	stmdb	sp!,{r0,r1,r2,r4-r11,lr}
     43 #if __ARM_ARCH__<7 && !defined(__thumb2__)
     44 	sub	r14,pc,#16		@ _ChaCha20_ctr32
     45 #else
     46 	adr	r14,LChaCha20_ctr32
     47 #endif
     48 	cmp	r2,#0			@ len==0?
     49 #ifdef	__thumb2__
     50 	itt	eq
     51 #endif
     52 	addeq	sp,sp,#4*3
     53 	beq	Lno_data
     54 #if __ARM_MAX_ARCH__>=7
     55 	cmp	r2,#192			@ test len
     56 	bls	Lshort
     57 	ldr	r4,[r14,#-32]
     58 	ldr	r4,[r14,r4]
     59 # ifdef	__APPLE__
     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 
    798 #if __ARM_MAX_ARCH__>=7
    799 
    800 
    801 
    802 #ifdef __thumb2__
    803 .thumb_func	ChaCha20_neon
    804 #endif
    805 .align	5
    806 ChaCha20_neon:
    807 	ldr	r12,[sp,#0]		@ pull pointer to counter and nonce
    808 	stmdb	sp!,{r0,r1,r2,r4-r11,lr}
    809 LChaCha20_neon:
    810 	adr	r14,Lsigma
    811 	vstmdb	sp!,{d8,d9,d10,d11,d12,d13,d14,d15}		@ ABI spec says so
    812 	stmdb	sp!,{r0,r1,r2,r3}
    813 
    814 	vld1.32	{q1,q2},[r3]		@ load key
    815 	ldmia	r3,{r4,r5,r6,r7,r8,r9,r10,r11}		@ load key
    816 
    817 	sub	sp,sp,#4*(16+16)
    818 	vld1.32	{q3},[r12]		@ load counter and nonce
    819 	add	r12,sp,#4*8
    820 	ldmia	r14,{r0,r1,r2,r3}		@ load sigma
    821 	vld1.32	{q0},[r14]!		@ load sigma
    822 	vld1.32	{q12},[r14]		@ one
    823 	vst1.32	{q2,q3},[r12]		@ copy 1/2key|counter|nonce
    824 	vst1.32	{q0,q1},[sp]		@ copy sigma|1/2key
    825 
    826 	str	r10,[sp,#4*(16+10)]	@ off-load "rx"
    827 	str	r11,[sp,#4*(16+11)]	@ off-load "rx"
    828 	vshl.i32	d26,d24,#1	@ two
    829 	vstr	d24,[sp,#4*(16+0)]
    830 	vshl.i32	d28,d24,#2	@ four
    831 	vstr	d26,[sp,#4*(16+2)]
    832 	vmov	q4,q0
    833 	vstr	d28,[sp,#4*(16+4)]
    834 	vmov	q8,q0
    835 	vmov	q5,q1
    836 	vmov	q9,q1
    837 	b	Loop_neon_enter
    838 
    839 .align	4
    840 Loop_neon_outer:
    841 	ldmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7,r8,r9}		@ load key material
    842 	cmp	r11,#64*2		@ if len<=64*2
    843 	bls	Lbreak_neon		@ switch to integer-only
    844 	vmov	q4,q0
    845 	str	r11,[sp,#4*(32+2)]	@ save len
    846 	vmov	q8,q0
    847 	str	r12,  [sp,#4*(32+1)]	@ save inp
    848 	vmov	q5,q1
    849 	str	r14,  [sp,#4*(32+0)]	@ save out
    850 	vmov	q9,q1
    851 Loop_neon_enter:
    852 	ldr	r11, [sp,#4*(15)]
    853 	vadd.i32	q7,q3,q12		@ counter+1
    854 	ldr	r12,[sp,#4*(12)]	@ modulo-scheduled load
    855 	vmov	q6,q2
    856 	ldr	r10, [sp,#4*(13)]
    857 	vmov	q10,q2
    858 	ldr	r14,[sp,#4*(14)]
    859 	vadd.i32	q11,q7,q12		@ counter+2
    860 	str	r11, [sp,#4*(16+15)]
    861 	mov	r11,#10
    862 	add	r12,r12,#3	@ counter+3
    863 	b	Loop_neon
    864 
    865 .align	4
    866 Loop_neon:
    867 	subs	r11,r11,#1
    868 	vadd.i32	q0,q0,q1
    869 	add	r0,r0,r4
    870 	vadd.i32	q4,q4,q5
    871 	mov	r12,r12,ror#16
    872 	vadd.i32	q8,q8,q9
    873 	add	r1,r1,r5
    874 	veor	q3,q3,q0
    875 	mov	r10,r10,ror#16
    876 	veor	q7,q7,q4
    877 	eor	r12,r12,r0,ror#16
    878 	veor	q11,q11,q8
    879 	eor	r10,r10,r1,ror#16
    880 	vrev32.16	q3,q3
    881 	add	r8,r8,r12
    882 	vrev32.16	q7,q7
    883 	mov	r4,r4,ror#20
    884 	vrev32.16	q11,q11
    885 	add	r9,r9,r10
    886 	vadd.i32	q2,q2,q3
    887 	mov	r5,r5,ror#20
    888 	vadd.i32	q6,q6,q7
    889 	eor	r4,r4,r8,ror#20
    890 	vadd.i32	q10,q10,q11
    891 	eor	r5,r5,r9,ror#20
    892 	veor	q12,q1,q2
    893 	add	r0,r0,r4
    894 	veor	q13,q5,q6
    895 	mov	r12,r12,ror#24
    896 	veor	q14,q9,q10
    897 	add	r1,r1,r5
    898 	vshr.u32	q1,q12,#20
    899 	mov	r10,r10,ror#24
    900 	vshr.u32	q5,q13,#20
    901 	eor	r12,r12,r0,ror#24
    902 	vshr.u32	q9,q14,#20
    903 	eor	r10,r10,r1,ror#24
    904 	vsli.32	q1,q12,#12
    905 	add	r8,r8,r12
    906 	vsli.32	q5,q13,#12
    907 	mov	r4,r4,ror#25
    908 	vsli.32	q9,q14,#12
    909 	add	r9,r9,r10
    910 	vadd.i32	q0,q0,q1
    911 	mov	r5,r5,ror#25
    912 	vadd.i32	q4,q4,q5
    913 	str	r10,[sp,#4*(16+13)]
    914 	vadd.i32	q8,q8,q9
    915 	ldr	r10,[sp,#4*(16+15)]
    916 	veor	q12,q3,q0
    917 	eor	r4,r4,r8,ror#25
    918 	veor	q13,q7,q4
    919 	eor	r5,r5,r9,ror#25
    920 	veor	q14,q11,q8
    921 	str	r8,[sp,#4*(16+8)]
    922 	vshr.u32	q3,q12,#24
    923 	ldr	r8,[sp,#4*(16+10)]
    924 	vshr.u32	q7,q13,#24
    925 	add	r2,r2,r6
    926 	vshr.u32	q11,q14,#24
    927 	mov	r14,r14,ror#16
    928 	vsli.32	q3,q12,#8
    929 	str	r9,[sp,#4*(16+9)]
    930 	vsli.32	q7,q13,#8
    931 	ldr	r9,[sp,#4*(16+11)]
    932 	vsli.32	q11,q14,#8
    933 	add	r3,r3,r7
    934 	vadd.i32	q2,q2,q3
    935 	mov	r10,r10,ror#16
    936 	vadd.i32	q6,q6,q7
    937 	eor	r14,r14,r2,ror#16
    938 	vadd.i32	q10,q10,q11
    939 	eor	r10,r10,r3,ror#16
    940 	veor	q12,q1,q2
    941 	add	r8,r8,r14
    942 	veor	q13,q5,q6
    943 	mov	r6,r6,ror#20
    944 	veor	q14,q9,q10
    945 	add	r9,r9,r10
    946 	vshr.u32	q1,q12,#25
    947 	mov	r7,r7,ror#20
    948 	vshr.u32	q5,q13,#25
    949 	eor	r6,r6,r8,ror#20
    950 	vshr.u32	q9,q14,#25
    951 	eor	r7,r7,r9,ror#20
    952 	vsli.32	q1,q12,#7
    953 	add	r2,r2,r6
    954 	vsli.32	q5,q13,#7
    955 	mov	r14,r14,ror#24
    956 	vsli.32	q9,q14,#7
    957 	add	r3,r3,r7
    958 	vext.8	q2,q2,q2,#8
    959 	mov	r10,r10,ror#24
    960 	vext.8	q6,q6,q6,#8
    961 	eor	r14,r14,r2,ror#24
    962 	vext.8	q10,q10,q10,#8
    963 	eor	r10,r10,r3,ror#24
    964 	vext.8	q1,q1,q1,#4
    965 	add	r8,r8,r14
    966 	vext.8	q5,q5,q5,#4
    967 	mov	r6,r6,ror#25
    968 	vext.8	q9,q9,q9,#4
    969 	add	r9,r9,r10
    970 	vext.8	q3,q3,q3,#12
    971 	mov	r7,r7,ror#25
    972 	vext.8	q7,q7,q7,#12
    973 	eor	r6,r6,r8,ror#25
    974 	vext.8	q11,q11,q11,#12
    975 	eor	r7,r7,r9,ror#25
    976 	vadd.i32	q0,q0,q1
    977 	add	r0,r0,r5
    978 	vadd.i32	q4,q4,q5
    979 	mov	r10,r10,ror#16
    980 	vadd.i32	q8,q8,q9
    981 	add	r1,r1,r6
    982 	veor	q3,q3,q0
    983 	mov	r12,r12,ror#16
    984 	veor	q7,q7,q4
    985 	eor	r10,r10,r0,ror#16
    986 	veor	q11,q11,q8
    987 	eor	r12,r12,r1,ror#16
    988 	vrev32.16	q3,q3
    989 	add	r8,r8,r10
    990 	vrev32.16	q7,q7
    991 	mov	r5,r5,ror#20
    992 	vrev32.16	q11,q11
    993 	add	r9,r9,r12
    994 	vadd.i32	q2,q2,q3
    995 	mov	r6,r6,ror#20
    996 	vadd.i32	q6,q6,q7
    997 	eor	r5,r5,r8,ror#20
    998 	vadd.i32	q10,q10,q11
    999 	eor	r6,r6,r9,ror#20
   1000 	veor	q12,q1,q2
   1001 	add	r0,r0,r5
   1002 	veor	q13,q5,q6
   1003 	mov	r10,r10,ror#24
   1004 	veor	q14,q9,q10
   1005 	add	r1,r1,r6
   1006 	vshr.u32	q1,q12,#20
   1007 	mov	r12,r12,ror#24
   1008 	vshr.u32	q5,q13,#20
   1009 	eor	r10,r10,r0,ror#24
   1010 	vshr.u32	q9,q14,#20
   1011 	eor	r12,r12,r1,ror#24
   1012 	vsli.32	q1,q12,#12
   1013 	add	r8,r8,r10
   1014 	vsli.32	q5,q13,#12
   1015 	mov	r5,r5,ror#25
   1016 	vsli.32	q9,q14,#12
   1017 	str	r10,[sp,#4*(16+15)]
   1018 	vadd.i32	q0,q0,q1
   1019 	ldr	r10,[sp,#4*(16+13)]
   1020 	vadd.i32	q4,q4,q5
   1021 	add	r9,r9,r12
   1022 	vadd.i32	q8,q8,q9
   1023 	mov	r6,r6,ror#25
   1024 	veor	q12,q3,q0
   1025 	eor	r5,r5,r8,ror#25
   1026 	veor	q13,q7,q4
   1027 	eor	r6,r6,r9,ror#25
   1028 	veor	q14,q11,q8
   1029 	str	r8,[sp,#4*(16+10)]
   1030 	vshr.u32	q3,q12,#24
   1031 	ldr	r8,[sp,#4*(16+8)]
   1032 	vshr.u32	q7,q13,#24
   1033 	add	r2,r2,r7
   1034 	vshr.u32	q11,q14,#24
   1035 	mov	r10,r10,ror#16
   1036 	vsli.32	q3,q12,#8
   1037 	str	r9,[sp,#4*(16+11)]
   1038 	vsli.32	q7,q13,#8
   1039 	ldr	r9,[sp,#4*(16+9)]
   1040 	vsli.32	q11,q14,#8
   1041 	add	r3,r3,r4
   1042 	vadd.i32	q2,q2,q3
   1043 	mov	r14,r14,ror#16
   1044 	vadd.i32	q6,q6,q7
   1045 	eor	r10,r10,r2,ror#16
   1046 	vadd.i32	q10,q10,q11
   1047 	eor	r14,r14,r3,ror#16
   1048 	veor	q12,q1,q2
   1049 	add	r8,r8,r10
   1050 	veor	q13,q5,q6
   1051 	mov	r7,r7,ror#20
   1052 	veor	q14,q9,q10
   1053 	add	r9,r9,r14
   1054 	vshr.u32	q1,q12,#25
   1055 	mov	r4,r4,ror#20
   1056 	vshr.u32	q5,q13,#25
   1057 	eor	r7,r7,r8,ror#20
   1058 	vshr.u32	q9,q14,#25
   1059 	eor	r4,r4,r9,ror#20
   1060 	vsli.32	q1,q12,#7
   1061 	add	r2,r2,r7
   1062 	vsli.32	q5,q13,#7
   1063 	mov	r10,r10,ror#24
   1064 	vsli.32	q9,q14,#7
   1065 	add	r3,r3,r4
   1066 	vext.8	q2,q2,q2,#8
   1067 	mov	r14,r14,ror#24
   1068 	vext.8	q6,q6,q6,#8
   1069 	eor	r10,r10,r2,ror#24
   1070 	vext.8	q10,q10,q10,#8
   1071 	eor	r14,r14,r3,ror#24
   1072 	vext.8	q1,q1,q1,#12
   1073 	add	r8,r8,r10
   1074 	vext.8	q5,q5,q5,#12
   1075 	mov	r7,r7,ror#25
   1076 	vext.8	q9,q9,q9,#12
   1077 	add	r9,r9,r14
   1078 	vext.8	q3,q3,q3,#4
   1079 	mov	r4,r4,ror#25
   1080 	vext.8	q7,q7,q7,#4
   1081 	eor	r7,r7,r8,ror#25
   1082 	vext.8	q11,q11,q11,#4
   1083 	eor	r4,r4,r9,ror#25
   1084 	bne	Loop_neon
   1085 
   1086 	add	r11,sp,#32
   1087 	vld1.32	{q12,q13},[sp]		@ load key material
   1088 	vld1.32	{q14,q15},[r11]
   1089 
   1090 	ldr	r11,[sp,#4*(32+2)]	@ load len
   1091 
   1092 	str	r8, [sp,#4*(16+8)]	@ modulo-scheduled store
   1093 	str	r9, [sp,#4*(16+9)]
   1094 	str	r12,[sp,#4*(16+12)]
   1095 	str	r10, [sp,#4*(16+13)]
   1096 	str	r14,[sp,#4*(16+14)]
   1097 
   1098 	@ at this point we have first half of 512-bit result in
   1099 	@ rx and second half at sp+4*(16+8)
   1100 
   1101 	ldr	r12,[sp,#4*(32+1)]	@ load inp
   1102 	ldr	r14,[sp,#4*(32+0)]	@ load out
   1103 
   1104 	vadd.i32	q0,q0,q12		@ accumulate key material
   1105 	vadd.i32	q4,q4,q12
   1106 	vadd.i32	q8,q8,q12
   1107 	vldr	d24,[sp,#4*(16+0)]	@ one
   1108 
   1109 	vadd.i32	q1,q1,q13
   1110 	vadd.i32	q5,q5,q13
   1111 	vadd.i32	q9,q9,q13
   1112 	vldr	d26,[sp,#4*(16+2)]	@ two
   1113 
   1114 	vadd.i32	q2,q2,q14
   1115 	vadd.i32	q6,q6,q14
   1116 	vadd.i32	q10,q10,q14
   1117 	vadd.i32	d14,d14,d24	@ counter+1
   1118 	vadd.i32	d22,d22,d26	@ counter+2
   1119 
   1120 	vadd.i32	q3,q3,q15
   1121 	vadd.i32	q7,q7,q15
   1122 	vadd.i32	q11,q11,q15
   1123 
   1124 	cmp	r11,#64*4
   1125 	blo	Ltail_neon
   1126 
   1127 	vld1.8	{q12,q13},[r12]!	@ load input
   1128 	mov	r11,sp
   1129 	vld1.8	{q14,q15},[r12]!
   1130 	veor	q0,q0,q12		@ xor with input
   1131 	veor	q1,q1,q13
   1132 	vld1.8	{q12,q13},[r12]!
   1133 	veor	q2,q2,q14
   1134 	veor	q3,q3,q15
   1135 	vld1.8	{q14,q15},[r12]!
   1136 
   1137 	veor	q4,q4,q12
   1138 	vst1.8	{q0,q1},[r14]!	@ store output
   1139 	veor	q5,q5,q13
   1140 	vld1.8	{q12,q13},[r12]!
   1141 	veor	q6,q6,q14
   1142 	vst1.8	{q2,q3},[r14]!
   1143 	veor	q7,q7,q15
   1144 	vld1.8	{q14,q15},[r12]!
   1145 
   1146 	veor	q8,q8,q12
   1147 	vld1.32	{q0,q1},[r11]!	@ load for next iteration
   1148 	veor	d25,d25,d25
   1149 	vldr	d24,[sp,#4*(16+4)]	@ four
   1150 	veor	q9,q9,q13
   1151 	vld1.32	{q2,q3},[r11]
   1152 	veor	q10,q10,q14
   1153 	vst1.8	{q4,q5},[r14]!
   1154 	veor	q11,q11,q15
   1155 	vst1.8	{q6,q7},[r14]!
   1156 
   1157 	vadd.i32	d6,d6,d24	@ next counter value
   1158 	vldr	d24,[sp,#4*(16+0)]	@ one
   1159 
   1160 	ldmia	sp,{r8,r9,r10,r11}	@ load key material
   1161 	add	r0,r0,r8	@ accumulate key material
   1162 	ldr	r8,[r12],#16		@ load input
   1163 	vst1.8	{q8,q9},[r14]!
   1164 	add	r1,r1,r9
   1165 	ldr	r9,[r12,#-12]
   1166 	vst1.8	{q10,q11},[r14]!
   1167 	add	r2,r2,r10
   1168 	ldr	r10,[r12,#-8]
   1169 	add	r3,r3,r11
   1170 	ldr	r11,[r12,#-4]
   1171 # ifdef	__ARMEB__
   1172 	rev	r0,r0
   1173 	rev	r1,r1
   1174 	rev	r2,r2
   1175 	rev	r3,r3
   1176 # endif
   1177 	eor	r0,r0,r8	@ xor with input
   1178 	add	r8,sp,#4*(4)
   1179 	eor	r1,r1,r9
   1180 	str	r0,[r14],#16		@ store output
   1181 	eor	r2,r2,r10
   1182 	str	r1,[r14,#-12]
   1183 	eor	r3,r3,r11
   1184 	ldmia	r8,{r8,r9,r10,r11}	@ load key material
   1185 	str	r2,[r14,#-8]
   1186 	str	r3,[r14,#-4]
   1187 
   1188 	add	r4,r4,r8	@ accumulate key material
   1189 	ldr	r8,[r12],#16		@ load input
   1190 	add	r5,r5,r9
   1191 	ldr	r9,[r12,#-12]
   1192 	add	r6,r6,r10
   1193 	ldr	r10,[r12,#-8]
   1194 	add	r7,r7,r11
   1195 	ldr	r11,[r12,#-4]
   1196 # ifdef	__ARMEB__
   1197 	rev	r4,r4
   1198 	rev	r5,r5
   1199 	rev	r6,r6
   1200 	rev	r7,r7
   1201 # endif
   1202 	eor	r4,r4,r8
   1203 	add	r8,sp,#4*(8)
   1204 	eor	r5,r5,r9
   1205 	str	r4,[r14],#16		@ store output
   1206 	eor	r6,r6,r10
   1207 	str	r5,[r14,#-12]
   1208 	eor	r7,r7,r11
   1209 	ldmia	r8,{r8,r9,r10,r11}	@ load key material
   1210 	str	r6,[r14,#-8]
   1211 	add	r0,sp,#4*(16+8)
   1212 	str	r7,[r14,#-4]
   1213 
   1214 	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
   1215 
   1216 	add	r0,r0,r8	@ accumulate key material
   1217 	ldr	r8,[r12],#16		@ load input
   1218 	add	r1,r1,r9
   1219 	ldr	r9,[r12,#-12]
   1220 # ifdef	__thumb2__
   1221 	it	hi
   1222 # endif
   1223 	strhi	r10,[sp,#4*(16+10)]	@ copy "rx" while at it
   1224 	add	r2,r2,r10
   1225 	ldr	r10,[r12,#-8]
   1226 # ifdef	__thumb2__
   1227 	it	hi
   1228 # endif
   1229 	strhi	r11,[sp,#4*(16+11)]	@ copy "rx" while at it
   1230 	add	r3,r3,r11
   1231 	ldr	r11,[r12,#-4]
   1232 # ifdef	__ARMEB__
   1233 	rev	r0,r0
   1234 	rev	r1,r1
   1235 	rev	r2,r2
   1236 	rev	r3,r3
   1237 # endif
   1238 	eor	r0,r0,r8
   1239 	add	r8,sp,#4*(12)
   1240 	eor	r1,r1,r9
   1241 	str	r0,[r14],#16		@ store output
   1242 	eor	r2,r2,r10
   1243 	str	r1,[r14,#-12]
   1244 	eor	r3,r3,r11
   1245 	ldmia	r8,{r8,r9,r10,r11}	@ load key material
   1246 	str	r2,[r14,#-8]
   1247 	str	r3,[r14,#-4]
   1248 
   1249 	add	r4,r4,r8	@ accumulate key material
   1250 	add	r8,r8,#4		@ next counter value
   1251 	add	r5,r5,r9
   1252 	str	r8,[sp,#4*(12)]	@ save next counter value
   1253 	ldr	r8,[r12],#16		@ load input
   1254 	add	r6,r6,r10
   1255 	add	r4,r4,#3		@ counter+3
   1256 	ldr	r9,[r12,#-12]
   1257 	add	r7,r7,r11
   1258 	ldr	r10,[r12,#-8]
   1259 	ldr	r11,[r12,#-4]
   1260 # ifdef	__ARMEB__
   1261 	rev	r4,r4
   1262 	rev	r5,r5
   1263 	rev	r6,r6
   1264 	rev	r7,r7
   1265 # endif
   1266 	eor	r4,r4,r8
   1267 # ifdef	__thumb2__
   1268 	it	hi
   1269 # endif
   1270 	ldrhi	r8,[sp,#4*(32+2)]	@ re-load len
   1271 	eor	r5,r5,r9
   1272 	eor	r6,r6,r10
   1273 	str	r4,[r14],#16		@ store output
   1274 	eor	r7,r7,r11
   1275 	str	r5,[r14,#-12]
   1276 	sub	r11,r8,#64*4	@ len-=64*4
   1277 	str	r6,[r14,#-8]
   1278 	str	r7,[r14,#-4]
   1279 	bhi	Loop_neon_outer
   1280 
   1281 	b	Ldone_neon
   1282 
   1283 .align	4
   1284 Lbreak_neon:
   1285 	@ harmonize NEON and integer-only stack frames: load data
   1286 	@ from NEON frame, but save to integer-only one; distance
   1287 	@ between the two is 4*(32+4+16-32)=4*(20).
   1288 
   1289 	str	r11, [sp,#4*(20+32+2)]	@ save len
   1290 	add	r11,sp,#4*(32+4)
   1291 	str	r12,   [sp,#4*(20+32+1)]	@ save inp
   1292 	str	r14,   [sp,#4*(20+32+0)]	@ save out
   1293 
   1294 	ldr	r12,[sp,#4*(16+10)]
   1295 	ldr	r14,[sp,#4*(16+11)]
   1296 	vldmia	r11,{d8,d9,d10,d11,d12,d13,d14,d15}			@ fulfill ABI requirement
   1297 	str	r12,[sp,#4*(20+16+10)]	@ copy "rx"
   1298 	str	r14,[sp,#4*(20+16+11)]	@ copy "rx"
   1299 
   1300 	ldr	r11, [sp,#4*(15)]
   1301 	ldr	r12,[sp,#4*(12)]		@ modulo-scheduled load
   1302 	ldr	r10, [sp,#4*(13)]
   1303 	ldr	r14,[sp,#4*(14)]
   1304 	str	r11, [sp,#4*(20+16+15)]
   1305 	add	r11,sp,#4*(20)
   1306 	vst1.32	{q0,q1},[r11]!		@ copy key
   1307 	add	sp,sp,#4*(20)			@ switch frame
   1308 	vst1.32	{q2,q3},[r11]
   1309 	mov	r11,#10
   1310 	b	Loop				@ go integer-only
   1311 
   1312 .align	4
   1313 Ltail_neon:
   1314 	cmp	r11,#64*3
   1315 	bhs	L192_or_more_neon
   1316 	cmp	r11,#64*2
   1317 	bhs	L128_or_more_neon
   1318 	cmp	r11,#64*1
   1319 	bhs	L64_or_more_neon
   1320 
   1321 	add	r8,sp,#4*(8)
   1322 	vst1.8	{q0,q1},[sp]
   1323 	add	r10,sp,#4*(0)
   1324 	vst1.8	{q2,q3},[r8]
   1325 	b	Loop_tail_neon
   1326 
   1327 .align	4
   1328 L64_or_more_neon:
   1329 	vld1.8	{q12,q13},[r12]!
   1330 	vld1.8	{q14,q15},[r12]!
   1331 	veor	q0,q0,q12
   1332 	veor	q1,q1,q13
   1333 	veor	q2,q2,q14
   1334 	veor	q3,q3,q15
   1335 	vst1.8	{q0,q1},[r14]!
   1336 	vst1.8	{q2,q3},[r14]!
   1337 
   1338 	beq	Ldone_neon
   1339 
   1340 	add	r8,sp,#4*(8)
   1341 	vst1.8	{q4,q5},[sp]
   1342 	add	r10,sp,#4*(0)
   1343 	vst1.8	{q6,q7},[r8]
   1344 	sub	r11,r11,#64*1	@ len-=64*1
   1345 	b	Loop_tail_neon
   1346 
   1347 .align	4
   1348 L128_or_more_neon:
   1349 	vld1.8	{q12,q13},[r12]!
   1350 	vld1.8	{q14,q15},[r12]!
   1351 	veor	q0,q0,q12
   1352 	veor	q1,q1,q13
   1353 	vld1.8	{q12,q13},[r12]!
   1354 	veor	q2,q2,q14
   1355 	veor	q3,q3,q15
   1356 	vld1.8	{q14,q15},[r12]!
   1357 
   1358 	veor	q4,q4,q12
   1359 	veor	q5,q5,q13
   1360 	vst1.8	{q0,q1},[r14]!
   1361 	veor	q6,q6,q14
   1362 	vst1.8	{q2,q3},[r14]!
   1363 	veor	q7,q7,q15
   1364 	vst1.8	{q4,q5},[r14]!
   1365 	vst1.8	{q6,q7},[r14]!
   1366 
   1367 	beq	Ldone_neon
   1368 
   1369 	add	r8,sp,#4*(8)
   1370 	vst1.8	{q8,q9},[sp]
   1371 	add	r10,sp,#4*(0)
   1372 	vst1.8	{q10,q11},[r8]
   1373 	sub	r11,r11,#64*2	@ len-=64*2
   1374 	b	Loop_tail_neon
   1375 
   1376 .align	4
   1377 L192_or_more_neon:
   1378 	vld1.8	{q12,q13},[r12]!
   1379 	vld1.8	{q14,q15},[r12]!
   1380 	veor	q0,q0,q12
   1381 	veor	q1,q1,q13
   1382 	vld1.8	{q12,q13},[r12]!
   1383 	veor	q2,q2,q14
   1384 	veor	q3,q3,q15
   1385 	vld1.8	{q14,q15},[r12]!
   1386 
   1387 	veor	q4,q4,q12
   1388 	veor	q5,q5,q13
   1389 	vld1.8	{q12,q13},[r12]!
   1390 	veor	q6,q6,q14
   1391 	vst1.8	{q0,q1},[r14]!
   1392 	veor	q7,q7,q15
   1393 	vld1.8	{q14,q15},[r12]!
   1394 
   1395 	veor	q8,q8,q12
   1396 	vst1.8	{q2,q3},[r14]!
   1397 	veor	q9,q9,q13
   1398 	vst1.8	{q4,q5},[r14]!
   1399 	veor	q10,q10,q14
   1400 	vst1.8	{q6,q7},[r14]!
   1401 	veor	q11,q11,q15
   1402 	vst1.8	{q8,q9},[r14]!
   1403 	vst1.8	{q10,q11},[r14]!
   1404 
   1405 	beq	Ldone_neon
   1406 
   1407 	ldmia	sp,{r8,r9,r10,r11}	@ load key material
   1408 	add	r0,r0,r8	@ accumulate key material
   1409 	add	r8,sp,#4*(4)
   1410 	add	r1,r1,r9
   1411 	add	r2,r2,r10
   1412 	add	r3,r3,r11
   1413 	ldmia	r8,{r8,r9,r10,r11}	@ load key material
   1414 
   1415 	add	r4,r4,r8	@ accumulate key material
   1416 	add	r8,sp,#4*(8)
   1417 	add	r5,r5,r9
   1418 	add	r6,r6,r10
   1419 	add	r7,r7,r11
   1420 	ldmia	r8,{r8,r9,r10,r11}	@ load key material
   1421 # ifdef	__ARMEB__
   1422 	rev	r0,r0
   1423 	rev	r1,r1
   1424 	rev	r2,r2
   1425 	rev	r3,r3
   1426 	rev	r4,r4
   1427 	rev	r5,r5
   1428 	rev	r6,r6
   1429 	rev	r7,r7
   1430 # endif
   1431 	stmia	sp,{r0,r1,r2,r3,r4,r5,r6,r7}
   1432 	add	r0,sp,#4*(16+8)
   1433 
   1434 	ldmia	r0,{r0,r1,r2,r3,r4,r5,r6,r7}	@ load second half
   1435 
   1436 	add	r0,r0,r8	@ accumulate key material
   1437 	add	r8,sp,#4*(12)
   1438 	add	r1,r1,r9
   1439 	add	r2,r2,r10
   1440 	add	r3,r3,r11
   1441 	ldmia	r8,{r8,r9,r10,r11}	@ load key material
   1442 
   1443 	add	r4,r4,r8	@ accumulate key material
   1444 	add	r8,sp,#4*(8)
   1445 	add	r5,r5,r9
   1446 	add	r4,r4,#3		@ counter+3
   1447 	add	r6,r6,r10
   1448 	add	r7,r7,r11
   1449 	ldr	r11,[sp,#4*(32+2)]	@ re-load len
   1450 # ifdef	__ARMEB__
   1451 	rev	r0,r0
   1452 	rev	r1,r1
   1453 	rev	r2,r2
   1454 	rev	r3,r3
   1455 	rev	r4,r4
   1456 	rev	r5,r5
   1457 	rev	r6,r6
   1458 	rev	r7,r7
   1459 # endif
   1460 	stmia	r8,{r0,r1,r2,r3,r4,r5,r6,r7}
   1461 	add	r10,sp,#4*(0)
   1462 	sub	r11,r11,#64*3	@ len-=64*3
   1463 
   1464 Loop_tail_neon:
   1465 	ldrb	r8,[r10],#1	@ read buffer on stack
   1466 	ldrb	r9,[r12],#1		@ read input
   1467 	subs	r11,r11,#1
   1468 	eor	r8,r8,r9
   1469 	strb	r8,[r14],#1		@ store output
   1470 	bne	Loop_tail_neon
   1471 
   1472 Ldone_neon:
   1473 	add	sp,sp,#4*(32+4)
   1474 	vldmia	sp,{d8,d9,d10,d11,d12,d13,d14,d15}
   1475 	add	sp,sp,#4*(16+3)
   1476 	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,pc}
   1477 
   1478 .comm	_OPENSSL_armcap_P,4
   1479 .non_lazy_symbol_pointer
   1480 OPENSSL_armcap_P:
   1481 .indirect_symbol	_OPENSSL_armcap_P
   1482 .long	0
   1483 #endif
   1484