Home | History | Annotate | Download | only in asm
      1 #include "arm_arch.h"
      2 
      3 .text
      4 .code	32
      5 
      6 #if __ARM_ARCH__>=7
      7 .align	5
      8 .LOPENSSL_armcap:
      9 .word	OPENSSL_armcap_P-bn_mul_mont
     10 #endif
     11 
     12 .global	bn_mul_mont
     13 .type	bn_mul_mont,%function
     14 
     15 .align	5
     16 bn_mul_mont:
     17 	ldr	ip,[sp,#4]		@ load num
     18 	stmdb	sp!,{r0,r2}		@ sp points at argument block
     19 #if __ARM_ARCH__>=7
     20 	tst	ip,#7
     21 	bne	.Lialu
     22 	adr	r0,bn_mul_mont
     23 	ldr	r2,.LOPENSSL_armcap
     24 	ldr	r0,[r0,r2]
     25 	tst	r0,#1			@ NEON available?
     26 	ldmia	sp, {r0,r2}
     27 	beq	.Lialu
     28 	add	sp,sp,#8
     29 	b	bn_mul8x_mont_neon
     30 .align	4
     31 .Lialu:
     32 #endif
     33 	cmp	ip,#2
     34 	mov	r0,ip			@ load num
     35 	movlt	r0,#0
     36 	addlt	sp,sp,#2*4
     37 	blt	.Labrt
     38 
     39 	stmdb	sp!,{r4-r12,lr}		@ save 10 registers
     40 
     41 	mov	r0,r0,lsl#2		@ rescale r0 for byte count
     42 	sub	sp,sp,r0		@ alloca(4*num)
     43 	sub	sp,sp,#4		@ +extra dword
     44 	sub	r0,r0,#4		@ "num=num-1"
     45 	add	r4,r2,r0		@ &bp[num-1]
     46 
     47 	add	r0,sp,r0		@ r0 to point at &tp[num-1]
     48 	ldr	r8,[r0,#14*4]		@ &n0
     49 	ldr	r2,[r2]		@ bp[0]
     50 	ldr	r5,[r1],#4		@ ap[0],ap++
     51 	ldr	r6,[r3],#4		@ np[0],np++
     52 	ldr	r8,[r8]		@ *n0
     53 	str	r4,[r0,#15*4]		@ save &bp[num]
     54 
     55 	umull	r10,r11,r5,r2	@ ap[0]*bp[0]
     56 	str	r8,[r0,#14*4]		@ save n0 value
     57 	mul	r8,r10,r8		@ "tp[0]"*n0
     58 	mov	r12,#0
     59 	umlal	r10,r12,r6,r8	@ np[0]*n0+"t[0]"
     60 	mov	r4,sp
     61 
     62 .L1st:
     63 	ldr	r5,[r1],#4		@ ap[j],ap++
     64 	mov	r10,r11
     65 	ldr	r6,[r3],#4		@ np[j],np++
     66 	mov	r11,#0
     67 	umlal	r10,r11,r5,r2	@ ap[j]*bp[0]
     68 	mov	r14,#0
     69 	umlal	r12,r14,r6,r8	@ np[j]*n0
     70 	adds	r12,r12,r10
     71 	str	r12,[r4],#4		@ tp[j-1]=,tp++
     72 	adc	r12,r14,#0
     73 	cmp	r4,r0
     74 	bne	.L1st
     75 
     76 	adds	r12,r12,r11
     77 	ldr	r4,[r0,#13*4]		@ restore bp
     78 	mov	r14,#0
     79 	ldr	r8,[r0,#14*4]		@ restore n0
     80 	adc	r14,r14,#0
     81 	str	r12,[r0]		@ tp[num-1]=
     82 	str	r14,[r0,#4]		@ tp[num]=
     83 
     84 .Louter:
     86 	sub	r7,r0,sp		@ "original" r0-1 value
     87 	sub	r1,r1,r7		@ "rewind" ap to &ap[1]
     88 	ldr	r2,[r4,#4]!		@ *(++bp)
     89 	sub	r3,r3,r7		@ "rewind" np to &np[1]
     90 	ldr	r5,[r1,#-4]		@ ap[0]
     91 	ldr	r10,[sp]		@ tp[0]
     92 	ldr	r6,[r3,#-4]		@ np[0]
     93 	ldr	r7,[sp,#4]		@ tp[1]
     94 
     95 	mov	r11,#0
     96 	umlal	r10,r11,r5,r2	@ ap[0]*bp[i]+tp[0]
     97 	str	r4,[r0,#13*4]		@ save bp
     98 	mul	r8,r10,r8
     99 	mov	r12,#0
    100 	umlal	r10,r12,r6,r8	@ np[0]*n0+"tp[0]"
    101 	mov	r4,sp
    102 
    103 .Linner:
    104 	ldr	r5,[r1],#4		@ ap[j],ap++
    105 	adds	r10,r11,r7		@ +=tp[j]
    106 	ldr	r6,[r3],#4		@ np[j],np++
    107 	mov	r11,#0
    108 	umlal	r10,r11,r5,r2	@ ap[j]*bp[i]
    109 	mov	r14,#0
    110 	umlal	r12,r14,r6,r8	@ np[j]*n0
    111 	adc	r11,r11,#0
    112 	ldr	r7,[r4,#8]		@ tp[j+1]
    113 	adds	r12,r12,r10
    114 	str	r12,[r4],#4		@ tp[j-1]=,tp++
    115 	adc	r12,r14,#0
    116 	cmp	r4,r0
    117 	bne	.Linner
    118 
    119 	adds	r12,r12,r11
    120 	mov	r14,#0
    121 	ldr	r4,[r0,#13*4]		@ restore bp
    122 	adc	r14,r14,#0
    123 	ldr	r8,[r0,#14*4]		@ restore n0
    124 	adds	r12,r12,r7
    125 	ldr	r7,[r0,#15*4]		@ restore &bp[num]
    126 	adc	r14,r14,#0
    127 	str	r12,[r0]		@ tp[num-1]=
    128 	str	r14,[r0,#4]		@ tp[num]=
    129 
    130 	cmp	r4,r7
    131 	bne	.Louter
    132 
    133 	ldr	r2,[r0,#12*4]		@ pull rp
    135 	add	r0,r0,#4		@ r0 to point at &tp[num]
    136 	sub	r5,r0,sp		@ "original" num value
    137 	mov	r4,sp			@ "rewind" r4
    138 	mov	r1,r4			@ "borrow" r1
    139 	sub	r3,r3,r5		@ "rewind" r3 to &np[0]
    140 
    141 	subs	r7,r7,r7		@ "clear" carry flag
    142 .Lsub:	ldr	r7,[r4],#4
    143 	ldr	r6,[r3],#4
    144 	sbcs	r7,r7,r6		@ tp[j]-np[j]
    145 	str	r7,[r2],#4		@ rp[j]=
    146 	teq	r4,r0		@ preserve carry
    147 	bne	.Lsub
    148 	sbcs	r14,r14,#0		@ upmost carry
    149 	mov	r4,sp			@ "rewind" r4
    150 	sub	r2,r2,r5		@ "rewind" r2
    151 
    152 	and	r1,r4,r14
    153 	bic	r3,r2,r14
    154 	orr	r1,r1,r3		@ ap=borrow?tp:rp
    155 
    156 .Lcopy:	ldr	r7,[r1],#4		@ copy or in-place refresh
    157 	str	sp,[r4],#4		@ zap tp
    158 	str	r7,[r2],#4
    159 	cmp	r4,r0
    160 	bne	.Lcopy
    161 
    162 	add	sp,r0,#4		@ skip over tp[num+1]
    163 	ldmia	sp!,{r4-r12,lr}		@ restore registers
    164 	add	sp,sp,#2*4		@ skip over {r0,r2}
    165 	mov	r0,#1
    166 .Labrt:
    167 #if __ARM_ARCH__>=5
    168 	bx	lr				@ .word	0xe12fff1e
    169 #else
    170 	tst	lr,#1
    171 	moveq	pc,lr			@ be binary compatible with V4, yet
    172 	.word	0xe12fff1e			@ interoperable with Thumb ISA:-)
    173 #endif
    174 .size	bn_mul_mont,.-bn_mul_mont
    175 #if __ARM_ARCH__>=7
    176 .fpu	neon
    177 
    178 .type	bn_mul8x_mont_neon,%function
    179 .align	5
    180 bn_mul8x_mont_neon:
    181 	mov	ip,sp
    182 	stmdb	sp!,{r4-r11}
    183 	vstmdb	sp!,{d8-d15}		@ ABI specification says so
    184 	ldmia	ip,{r4-r5}		@ load rest of parameter block
    185 
    186 	sub		r7,sp,#16
    187 	vld1.32		{d28[0]}, [r2,:32]!
    188 	sub		r7,r7,r5,lsl#4
    189 	vld1.32		{d0-d3},  [r1]!		@ can't specify :32 :-(
    190 	and		r7,r7,#-64
    191 	vld1.32		{d30[0]}, [r4,:32]
    192 	mov		sp,r7			@ alloca
    193 	veor		d8,d8,d8
    194 	subs		r8,r5,#8
    195 	vzip.16		d28,d8
    196 
    197 	vmull.u32	q6,d28,d0[0]
    198 	vmull.u32	q7,d28,d0[1]
    199 	vmull.u32	q8,d28,d1[0]
    200 	vshl.i64	d10,d13,#16
    201 	vmull.u32	q9,d28,d1[1]
    202 
    203 	vadd.u64	d10,d10,d12
    204 	veor		d8,d8,d8
    205 	vmul.u32	d29,d10,d30
    206 
    207 	vmull.u32	q10,d28,d2[0]
    208 	 vld1.32	{d4-d7}, [r3]!
    209 	vmull.u32	q11,d28,d2[1]
    210 	vmull.u32	q12,d28,d3[0]
    211 	vzip.16		d29,d8
    212 	vmull.u32	q13,d28,d3[1]
    213 
    214 	bne	.LNEON_1st
    215 
    216 	@ special case for num=8, everything is in register bank...
    217 
    218 	vmlal.u32	q6,d29,d4[0]
    219 	sub		r9,r5,#1
    220 	vmlal.u32	q7,d29,d4[1]
    221 	vmlal.u32	q8,d29,d5[0]
    222 	vmlal.u32	q9,d29,d5[1]
    223 
    224 	vmlal.u32	q10,d29,d6[0]
    225 	vmov		q5,q6
    226 	vmlal.u32	q11,d29,d6[1]
    227 	vmov		q6,q7
    228 	vmlal.u32	q12,d29,d7[0]
    229 	vmov		q7,q8
    230 	vmlal.u32	q13,d29,d7[1]
    231 	vmov		q8,q9
    232 	vmov		q9,q10
    233 	vshr.u64	d10,d10,#16
    234 	vmov		q10,q11
    235 	vmov		q11,q12
    236 	vadd.u64	d10,d10,d11
    237 	vmov		q12,q13
    238 	veor		q13,q13
    239 	vshr.u64	d10,d10,#16
    240 
    241 	b	.LNEON_outer8
    242 
    243 .align	4
    244 .LNEON_outer8:
    245 	vld1.32		{d28[0]}, [r2,:32]!
    246 	veor		d8,d8,d8
    247 	vzip.16		d28,d8
    248 	vadd.u64	d12,d12,d10
    249 
    250 	vmlal.u32	q6,d28,d0[0]
    251 	vmlal.u32	q7,d28,d0[1]
    252 	vmlal.u32	q8,d28,d1[0]
    253 	vshl.i64	d10,d13,#16
    254 	vmlal.u32	q9,d28,d1[1]
    255 
    256 	vadd.u64	d10,d10,d12
    257 	veor		d8,d8,d8
    258 	subs		r9,r9,#1
    259 	vmul.u32	d29,d10,d30
    260 
    261 	vmlal.u32	q10,d28,d2[0]
    262 	vmlal.u32	q11,d28,d2[1]
    263 	vmlal.u32	q12,d28,d3[0]
    264 	vzip.16		d29,d8
    265 	vmlal.u32	q13,d28,d3[1]
    266 
    267 	vmlal.u32	q6,d29,d4[0]
    268 	vmlal.u32	q7,d29,d4[1]
    269 	vmlal.u32	q8,d29,d5[0]
    270 	vmlal.u32	q9,d29,d5[1]
    271 
    272 	vmlal.u32	q10,d29,d6[0]
    273 	vmov		q5,q6
    274 	vmlal.u32	q11,d29,d6[1]
    275 	vmov		q6,q7
    276 	vmlal.u32	q12,d29,d7[0]
    277 	vmov		q7,q8
    278 	vmlal.u32	q13,d29,d7[1]
    279 	vmov		q8,q9
    280 	vmov		q9,q10
    281 	vshr.u64	d10,d10,#16
    282 	vmov		q10,q11
    283 	vmov		q11,q12
    284 	vadd.u64	d10,d10,d11
    285 	vmov		q12,q13
    286 	veor		q13,q13
    287 	vshr.u64	d10,d10,#16
    288 
    289 	bne	.LNEON_outer8
    290 
    291 	vadd.u64	d12,d12,d10
    292 	mov		r7,sp
    293 	vshr.u64	d10,d12,#16
    294 	mov		r8,r5
    295 	vadd.u64	d13,d13,d10
    296 	add		r6,sp,#16
    297 	vshr.u64	d10,d13,#16
    298 	vzip.16		d12,d13
    299 
    300 	b	.LNEON_tail2
    301 
    302 .align	4
    303 .LNEON_1st:
    304 	vmlal.u32	q6,d29,d4[0]
    305 	 vld1.32	{d0-d3}, [r1]!
    306 	vmlal.u32	q7,d29,d4[1]
    307 	subs		r8,r8,#8
    308 	vmlal.u32	q8,d29,d5[0]
    309 	vmlal.u32	q9,d29,d5[1]
    310 
    311 	vmlal.u32	q10,d29,d6[0]
    312 	 vld1.32	{d4-d5}, [r3]!
    313 	vmlal.u32	q11,d29,d6[1]
    314 	 vst1.64	{q6-q7}, [r7,:256]!
    315 	vmlal.u32	q12,d29,d7[0]
    316 	vmlal.u32	q13,d29,d7[1]
    317 	 vst1.64	{q8-q9}, [r7,:256]!
    318 
    319 	vmull.u32	q6,d28,d0[0]
    320 	 vld1.32	{d6-d7}, [r3]!
    321 	vmull.u32	q7,d28,d0[1]
    322 	 vst1.64	{q10-q11}, [r7,:256]!
    323 	vmull.u32	q8,d28,d1[0]
    324 	vmull.u32	q9,d28,d1[1]
    325 	 vst1.64	{q12-q13}, [r7,:256]!
    326 
    327 	vmull.u32	q10,d28,d2[0]
    328 	vmull.u32	q11,d28,d2[1]
    329 	vmull.u32	q12,d28,d3[0]
    330 	vmull.u32	q13,d28,d3[1]
    331 
    332 	bne	.LNEON_1st
    333 
    334 	vmlal.u32	q6,d29,d4[0]
    335 	add		r6,sp,#16
    336 	vmlal.u32	q7,d29,d4[1]
    337 	sub		r1,r1,r5,lsl#2		@ rewind r1
    338 	vmlal.u32	q8,d29,d5[0]
    339 	 vld1.64	{q5}, [sp,:128]
    340 	vmlal.u32	q9,d29,d5[1]
    341 	sub		r9,r5,#1
    342 
    343 	vmlal.u32	q10,d29,d6[0]
    344 	vst1.64		{q6-q7}, [r7,:256]!
    345 	vmlal.u32	q11,d29,d6[1]
    346 	vshr.u64	d10,d10,#16
    347 	 vld1.64	{q6},       [r6, :128]!
    348 	vmlal.u32	q12,d29,d7[0]
    349 	vst1.64		{q8-q9}, [r7,:256]!
    350 	vmlal.u32	q13,d29,d7[1]
    351 
    352 	vst1.64		{q10-q11}, [r7,:256]!
    353 	vadd.u64	d10,d10,d11
    354 	veor		q4,q4,q4
    355 	vst1.64		{q12-q13}, [r7,:256]!
    356 	 vld1.64	{q7-q8}, [r6, :256]!
    357 	vst1.64		{q4},          [r7,:128]
    358 	vshr.u64	d10,d10,#16
    359 
    360 	b		.LNEON_outer
    361 
    362 .align	4
    363 .LNEON_outer:
    364 	vld1.32		{d28[0]}, [r2,:32]!
    365 	sub		r3,r3,r5,lsl#2		@ rewind r3
    366 	vld1.32		{d0-d3},  [r1]!
    367 	veor		d8,d8,d8
    368 	mov		r7,sp
    369 	vzip.16		d28,d8
    370 	sub		r8,r5,#8
    371 	vadd.u64	d12,d12,d10
    372 
    373 	vmlal.u32	q6,d28,d0[0]
    374 	 vld1.64	{q9-q10},[r6,:256]!
    375 	vmlal.u32	q7,d28,d0[1]
    376 	vmlal.u32	q8,d28,d1[0]
    377 	 vld1.64	{q11-q12},[r6,:256]!
    378 	vmlal.u32	q9,d28,d1[1]
    379 
    380 	vshl.i64	d10,d13,#16
    381 	veor		d8,d8,d8
    382 	vadd.u64	d10,d10,d12
    383 	 vld1.64	{q13},[r6,:128]!
    384 	vmul.u32	d29,d10,d30
    385 
    386 	vmlal.u32	q10,d28,d2[0]
    387 	 vld1.32	{d4-d7}, [r3]!
    388 	vmlal.u32	q11,d28,d2[1]
    389 	vmlal.u32	q12,d28,d3[0]
    390 	vzip.16		d29,d8
    391 	vmlal.u32	q13,d28,d3[1]
    392 
    393 .LNEON_inner:
    394 	vmlal.u32	q6,d29,d4[0]
    395 	 vld1.32	{d0-d3}, [r1]!
    396 	vmlal.u32	q7,d29,d4[1]
    397 	 subs		r8,r8,#8
    398 	vmlal.u32	q8,d29,d5[0]
    399 	vmlal.u32	q9,d29,d5[1]
    400 	vst1.64		{q6-q7}, [r7,:256]!
    401 
    402 	vmlal.u32	q10,d29,d6[0]
    403 	 vld1.64	{q6},       [r6, :128]!
    404 	vmlal.u32	q11,d29,d6[1]
    405 	vst1.64		{q8-q9}, [r7,:256]!
    406 	vmlal.u32	q12,d29,d7[0]
    407 	 vld1.64	{q7-q8}, [r6, :256]!
    408 	vmlal.u32	q13,d29,d7[1]
    409 	vst1.64		{q10-q11}, [r7,:256]!
    410 
    411 	vmlal.u32	q6,d28,d0[0]
    412 	 vld1.64	{q9-q10}, [r6, :256]!
    413 	vmlal.u32	q7,d28,d0[1]
    414 	vst1.64		{q12-q13}, [r7,:256]!
    415 	vmlal.u32	q8,d28,d1[0]
    416 	 vld1.64	{q11-q12}, [r6, :256]!
    417 	vmlal.u32	q9,d28,d1[1]
    418 	 vld1.32	{d4-d7}, [r3]!
    419 
    420 	vmlal.u32	q10,d28,d2[0]
    421 	 vld1.64	{q13},       [r6, :128]!
    422 	vmlal.u32	q11,d28,d2[1]
    423 	vmlal.u32	q12,d28,d3[0]
    424 	vmlal.u32	q13,d28,d3[1]
    425 
    426 	bne	.LNEON_inner
    427 
    428 	vmlal.u32	q6,d29,d4[0]
    429 	add		r6,sp,#16
    430 	vmlal.u32	q7,d29,d4[1]
    431 	sub		r1,r1,r5,lsl#2		@ rewind r1
    432 	vmlal.u32	q8,d29,d5[0]
    433 	 vld1.64	{q5}, [sp,:128]
    434 	vmlal.u32	q9,d29,d5[1]
    435 	subs		r9,r9,#1
    436 
    437 	vmlal.u32	q10,d29,d6[0]
    438 	vst1.64		{q6-q7}, [r7,:256]!
    439 	vmlal.u32	q11,d29,d6[1]
    440 	 vld1.64	{q6},       [r6, :128]!
    441 	vshr.u64	d10,d10,#16
    442 	vst1.64		{q8-q9}, [r7,:256]!
    443 	vmlal.u32	q12,d29,d7[0]
    444 	 vld1.64	{q7-q8}, [r6, :256]!
    445 	vmlal.u32	q13,d29,d7[1]
    446 
    447 	vst1.64		{q10-q11}, [r7,:256]!
    448 	vadd.u64	d10,d10,d11
    449 	vst1.64		{q12-q13}, [r7,:256]!
    450 	vshr.u64	d10,d10,#16
    451 
    452 	bne	.LNEON_outer
    453 
    454 	mov		r7,sp
    455 	mov		r8,r5
    456 
    457 .LNEON_tail:
    458 	vadd.u64	d12,d12,d10
    459 	vld1.64		{q9-q10}, [r6, :256]!
    460 	vshr.u64	d10,d12,#16
    461 	vadd.u64	d13,d13,d10
    462 	vld1.64		{q11-q12}, [r6, :256]!
    463 	vshr.u64	d10,d13,#16
    464 	vld1.64		{q13},       [r6, :128]!
    465 	vzip.16		d12,d13
    466 
    467 .LNEON_tail2:
    468 	vadd.u64	d14,d14,d10
    469 	vst1.32		{d12[0]}, [r7, :32]!
    470 	vshr.u64	d10,d14,#16
    471 	vadd.u64	d15,d15,d10
    472 	vshr.u64	d10,d15,#16
    473 	vzip.16		d14,d15
    474 
    475 	vadd.u64	d16,d16,d10
    476 	vst1.32		{d14[0]}, [r7, :32]!
    477 	vshr.u64	d10,d16,#16
    478 	vadd.u64	d17,d17,d10
    479 	vshr.u64	d10,d17,#16
    480 	vzip.16		d16,d17
    481 
    482 	vadd.u64	d18,d18,d10
    483 	vst1.32		{d16[0]}, [r7, :32]!
    484 	vshr.u64	d10,d18,#16
    485 	vadd.u64	d19,d19,d10
    486 	vshr.u64	d10,d19,#16
    487 	vzip.16		d18,d19
    488 
    489 	vadd.u64	d20,d20,d10
    490 	vst1.32		{d18[0]}, [r7, :32]!
    491 	vshr.u64	d10,d20,#16
    492 	vadd.u64	d21,d21,d10
    493 	vshr.u64	d10,d21,#16
    494 	vzip.16		d20,d21
    495 
    496 	vadd.u64	d22,d22,d10
    497 	vst1.32		{d20[0]}, [r7, :32]!
    498 	vshr.u64	d10,d22,#16
    499 	vadd.u64	d23,d23,d10
    500 	vshr.u64	d10,d23,#16
    501 	vzip.16		d22,d23
    502 
    503 	vadd.u64	d24,d24,d10
    504 	vst1.32		{d22[0]}, [r7, :32]!
    505 	vshr.u64	d10,d24,#16
    506 	vadd.u64	d25,d25,d10
    507 	vld1.64		{q6}, [r6, :128]!
    508 	vshr.u64	d10,d25,#16
    509 	vzip.16		d24,d25
    510 
    511 	vadd.u64	d26,d26,d10
    512 	vst1.32		{d24[0]}, [r7, :32]!
    513 	vshr.u64	d10,d26,#16
    514 	vadd.u64	d27,d27,d10
    515 	vld1.64		{q7-q8},	[r6, :256]!
    516 	vshr.u64	d10,d27,#16
    517 	vzip.16		d26,d27
    518 	subs		r8,r8,#8
    519 	vst1.32		{d26[0]}, [r7, :32]!
    520 
    521 	bne	.LNEON_tail
    522 
    523 	vst1.32	{d10[0]}, [r7, :32]		@ top-most bit
    524 	sub	r3,r3,r5,lsl#2			@ rewind r3
    525 	subs	r1,sp,#0				@ clear carry flag
    526 	add	r2,sp,r5,lsl#2
    527 
    528 .LNEON_sub:
    529 	ldmia	r1!, {r4-r7}
    530 	ldmia	r3!, {r8-r11}
    531 	sbcs	r8, r4,r8
    532 	sbcs	r9, r5,r9
    533 	sbcs	r10,r6,r10
    534 	sbcs	r11,r7,r11
    535 	teq	r1,r2				@ preserves carry
    536 	stmia	r0!, {r8-r11}
    537 	bne	.LNEON_sub
    538 
    539 	ldr	r10, [r1]				@ load top-most bit
    540 	veor	q0,q0,q0
    541 	sub	r11,r2,sp				@ this is num*4
    542 	veor	q1,q1,q1
    543 	mov	r1,sp
    544 	sub	r0,r0,r11				@ rewind r0
    545 	mov	r3,r2				@ second 3/4th of frame
    546 	sbcs	r10,r10,#0				@ result is carry flag
    547 
    548 .LNEON_copy_n_zap:
    549 	ldmia	r1!, {r4-r7}
    550 	ldmia	r0,  {r8-r11}
    551 	movcc	r8, r4
    552 	vst1.64	{q0-q1}, [r3,:256]!			@ wipe
    553 	movcc	r9, r5
    554 	movcc	r10,r6
    555 	vst1.64	{q0-q1}, [r3,:256]!			@ wipe
    556 	movcc	r11,r7
    557 	ldmia	r1, {r4-r7}
    558 	stmia	r0!, {r8-r11}
    559 	sub	r1,r1,#16
    560 	ldmia	r0, {r8-r11}
    561 	movcc	r8, r4
    562 	vst1.64	{q0-q1}, [r1,:256]!			@ wipe
    563 	movcc	r9, r5
    564 	movcc	r10,r6
    565 	vst1.64	{q0-q1}, [r3,:256]!			@ wipe
    566 	movcc	r11,r7
    567 	teq	r1,r2				@ preserves carry
    568 	stmia	r0!, {r8-r11}
    569 	bne	.LNEON_copy_n_zap
    570 
    571 	sub	sp,ip,#96
    572         vldmia  sp!,{d8-d15}
    573         ldmia   sp!,{r4-r11}
    574 	bx	lr						@ .word	0xe12fff1e
    575 .size	bn_mul8x_mont_neon,.-bn_mul8x_mont_neon
    576 #endif
    577 .asciz	"Montgomery multiplication for ARMv4/NEON, CRYPTOGAMS by <appro (at) openssl.org>"
    578 .align	2
    579 #if __ARM_ARCH__>=7
    580 .comm	OPENSSL_armcap_P,4,4
    581 #endif
    582