armv4-mont.S 11.9 KB
Newer Older
1 2
#if defined(__arm__)
#include <openssl/arm_arch.h>
3 4 5 6

.text
.code	32

7
#if __ARM_MAX_ARCH__>=7
8 9
.align	5
.LOPENSSL_armcap:
10
.word	OPENSSL_armcap_P-.Lbn_mul_mont
11 12
#endif

13
.globl	bn_mul_mont
14 15 16 17 18
.hidden	bn_mul_mont
.type	bn_mul_mont,%function

.align	5
bn_mul_mont:
19
.Lbn_mul_mont:
20 21
	ldr	ip,[sp,#4]		@ load num
	stmdb	sp!,{r0,r2}		@ sp points at argument block
22
#if __ARM_MAX_ARCH__>=7
23 24 25 26 27
	tst	ip,#7
	bne	.Lialu
	adr	r0,bn_mul_mont
	ldr	r2,.LOPENSSL_armcap
	ldr	r0,[r0,r2]
28 29 30
#ifdef	__APPLE__
	ldr	r0,[r0]
#endif
31 32 33 34 35 36 37 38 39 40 41 42 43 44
	tst	r0,#1			@ NEON available?
	ldmia	sp, {r0,r2}
	beq	.Lialu
	add	sp,sp,#8
	b	bn_mul8x_mont_neon
.align	4
.Lialu:
#endif
	cmp	ip,#2
	mov	r0,ip			@ load num
	movlt	r0,#0
	addlt	sp,sp,#2*4
	blt	.Labrt

45
	stmdb	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}		@ save 10 registers
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88

	mov	r0,r0,lsl#2		@ rescale r0 for byte count
	sub	sp,sp,r0		@ alloca(4*num)
	sub	sp,sp,#4		@ +extra dword
	sub	r0,r0,#4		@ "num=num-1"
	add	r4,r2,r0		@ &bp[num-1]

	add	r0,sp,r0		@ r0 to point at &tp[num-1]
	ldr	r8,[r0,#14*4]		@ &n0
	ldr	r2,[r2]		@ bp[0]
	ldr	r5,[r1],#4		@ ap[0],ap++
	ldr	r6,[r3],#4		@ np[0],np++
	ldr	r8,[r8]		@ *n0
	str	r4,[r0,#15*4]		@ save &bp[num]

	umull	r10,r11,r5,r2	@ ap[0]*bp[0]
	str	r8,[r0,#14*4]		@ save n0 value
	mul	r8,r10,r8		@ "tp[0]"*n0
	mov	r12,#0
	umlal	r10,r12,r6,r8	@ np[0]*n0+"t[0]"
	mov	r4,sp

.L1st:
	ldr	r5,[r1],#4		@ ap[j],ap++
	mov	r10,r11
	ldr	r6,[r3],#4		@ np[j],np++
	mov	r11,#0
	umlal	r10,r11,r5,r2	@ ap[j]*bp[0]
	mov	r14,#0
	umlal	r12,r14,r6,r8	@ np[j]*n0
	adds	r12,r12,r10
	str	r12,[r4],#4		@ tp[j-1]=,tp++
	adc	r12,r14,#0
	cmp	r4,r0
	bne	.L1st

	adds	r12,r12,r11
	ldr	r4,[r0,#13*4]		@ restore bp
	mov	r14,#0
	ldr	r8,[r0,#14*4]		@ restore n0
	adc	r14,r14,#0
	str	r12,[r0]		@ tp[num-1]=
	str	r14,[r0,#4]		@ tp[num]=
89

90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
.Louter:
	sub	r7,r0,sp		@ "original" r0-1 value
	sub	r1,r1,r7		@ "rewind" ap to &ap[1]
	ldr	r2,[r4,#4]!		@ *(++bp)
	sub	r3,r3,r7		@ "rewind" np to &np[1]
	ldr	r5,[r1,#-4]		@ ap[0]
	ldr	r10,[sp]		@ tp[0]
	ldr	r6,[r3,#-4]		@ np[0]
	ldr	r7,[sp,#4]		@ tp[1]

	mov	r11,#0
	umlal	r10,r11,r5,r2	@ ap[0]*bp[i]+tp[0]
	str	r4,[r0,#13*4]		@ save bp
	mul	r8,r10,r8
	mov	r12,#0
	umlal	r10,r12,r6,r8	@ np[0]*n0+"tp[0]"
	mov	r4,sp

.Linner:
	ldr	r5,[r1],#4		@ ap[j],ap++
	adds	r10,r11,r7		@ +=tp[j]
	ldr	r6,[r3],#4		@ np[j],np++
	mov	r11,#0
	umlal	r10,r11,r5,r2	@ ap[j]*bp[i]
	mov	r14,#0
	umlal	r12,r14,r6,r8	@ np[j]*n0
	adc	r11,r11,#0
	ldr	r7,[r4,#8]		@ tp[j+1]
	adds	r12,r12,r10
	str	r12,[r4],#4		@ tp[j-1]=,tp++
	adc	r12,r14,#0
	cmp	r4,r0
	bne	.Linner

	adds	r12,r12,r11
	mov	r14,#0
	ldr	r4,[r0,#13*4]		@ restore bp
	adc	r14,r14,#0
	ldr	r8,[r0,#14*4]		@ restore n0
	adds	r12,r12,r7
	ldr	r7,[r0,#15*4]		@ restore &bp[num]
	adc	r14,r14,#0
	str	r12,[r0]		@ tp[num-1]=
	str	r14,[r0,#4]		@ tp[num]=

	cmp	r4,r7
	bne	.Louter
137

138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	ldr	r2,[r0,#12*4]		@ pull rp
	add	r0,r0,#4		@ r0 to point at &tp[num]
	sub	r5,r0,sp		@ "original" num value
	mov	r4,sp			@ "rewind" r4
	mov	r1,r4			@ "borrow" r1
	sub	r3,r3,r5		@ "rewind" r3 to &np[0]

	subs	r7,r7,r7		@ "clear" carry flag
.Lsub:	ldr	r7,[r4],#4
	ldr	r6,[r3],#4
	sbcs	r7,r7,r6		@ tp[j]-np[j]
	str	r7,[r2],#4		@ rp[j]=
	teq	r4,r0		@ preserve carry
	bne	.Lsub
	sbcs	r14,r14,#0		@ upmost carry
	mov	r4,sp			@ "rewind" r4
	sub	r2,r2,r5		@ "rewind" r2

	and	r1,r4,r14
	bic	r3,r2,r14
	orr	r1,r1,r3		@ ap=borrow?tp:rp

.Lcopy:	ldr	r7,[r1],#4		@ copy or in-place refresh
	str	sp,[r4],#4		@ zap tp
	str	r7,[r2],#4
	cmp	r4,r0
	bne	.Lcopy

	add	sp,r0,#4		@ skip over tp[num+1]
167
	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr}		@ restore registers
168 169
	add	sp,sp,#2*4		@ skip over {r0,r2}
	mov	r0,#1
170 171 172 173 174
.Labrt:
#if __ARM_ARCH__>=5
	bx	lr				@ .word	0xe12fff1e
#else
	tst	lr,#1
175
	moveq	pc,lr			@ be binary compatible with V4, yet
176 177
.word	0xe12fff1e			@ interoperable with Thumb ISA:-)
#endif
178
.size	bn_mul_mont,.-bn_mul_mont
179 180
#if __ARM_MAX_ARCH__>=7
.arch	armv7-a
181 182 183 184 185 186
.fpu	neon

.type	bn_mul8x_mont_neon,%function
.align	5
bn_mul8x_mont_neon:
	mov	ip,sp
187 188 189 190 191 192 193 194 195 196 197 198 199 200
	stmdb	sp!,{r4,r5,r6,r7,r8,r9,r10,r11}
	vstmdb	sp!,{d8,d9,d10,d11,d12,d13,d14,d15}		@ ABI specification says so
	ldmia	ip,{r4,r5}		@ load rest of parameter block

	sub	r7,sp,#16
	vld1.32	{d28[0]}, [r2,:32]!
	sub	r7,r7,r5,lsl#4
	vld1.32	{d0,d1,d2,d3},  [r1]!		@ can't specify :32 :-(
	and	r7,r7,#-64
	vld1.32	{d30[0]}, [r4,:32]
	mov	sp,r7			@ alloca
	veor	d8,d8,d8
	subs	r8,r5,#8
	vzip.16	d28,d8
201 202 203 204 205 206 207 208

	vmull.u32	q6,d28,d0[0]
	vmull.u32	q7,d28,d0[1]
	vmull.u32	q8,d28,d1[0]
	vshl.i64	d10,d13,#16
	vmull.u32	q9,d28,d1[1]

	vadd.u64	d10,d10,d12
209
	veor	d8,d8,d8
210 211 212
	vmul.u32	d29,d10,d30

	vmull.u32	q10,d28,d2[0]
213
	vld1.32	{d4,d5,d6,d7}, [r3]!
214 215
	vmull.u32	q11,d28,d2[1]
	vmull.u32	q12,d28,d3[0]
216
	vzip.16	d29,d8
217 218 219 220 221 222 223
	vmull.u32	q13,d28,d3[1]

	bne	.LNEON_1st

	@ special case for num=8, everything is in register bank...

	vmlal.u32	q6,d29,d4[0]
224
	sub	r9,r5,#1
225 226 227 228 229
	vmlal.u32	q7,d29,d4[1]
	vmlal.u32	q8,d29,d5[0]
	vmlal.u32	q9,d29,d5[1]

	vmlal.u32	q10,d29,d6[0]
230
	vmov	q5,q6
231
	vmlal.u32	q11,d29,d6[1]
232
	vmov	q6,q7
233
	vmlal.u32	q12,d29,d7[0]
234
	vmov	q7,q8
235
	vmlal.u32	q13,d29,d7[1]
236 237
	vmov	q8,q9
	vmov	q9,q10
238
	vshr.u64	d10,d10,#16
239 240
	vmov	q10,q11
	vmov	q11,q12
241
	vadd.u64	d10,d10,d11
242 243
	vmov	q12,q13
	veor	q13,q13
244 245 246 247 248 249
	vshr.u64	d10,d10,#16

	b	.LNEON_outer8

.align	4
.LNEON_outer8:
250 251 252
	vld1.32	{d28[0]}, [r2,:32]!
	veor	d8,d8,d8
	vzip.16	d28,d8
253 254 255 256 257 258 259 260 261
	vadd.u64	d12,d12,d10

	vmlal.u32	q6,d28,d0[0]
	vmlal.u32	q7,d28,d0[1]
	vmlal.u32	q8,d28,d1[0]
	vshl.i64	d10,d13,#16
	vmlal.u32	q9,d28,d1[1]

	vadd.u64	d10,d10,d12
262 263
	veor	d8,d8,d8
	subs	r9,r9,#1
264 265 266 267 268
	vmul.u32	d29,d10,d30

	vmlal.u32	q10,d28,d2[0]
	vmlal.u32	q11,d28,d2[1]
	vmlal.u32	q12,d28,d3[0]
269
	vzip.16	d29,d8
270 271 272 273 274 275 276 277
	vmlal.u32	q13,d28,d3[1]

	vmlal.u32	q6,d29,d4[0]
	vmlal.u32	q7,d29,d4[1]
	vmlal.u32	q8,d29,d5[0]
	vmlal.u32	q9,d29,d5[1]

	vmlal.u32	q10,d29,d6[0]
278
	vmov	q5,q6
279
	vmlal.u32	q11,d29,d6[1]
280
	vmov	q6,q7
281
	vmlal.u32	q12,d29,d7[0]
282
	vmov	q7,q8
283
	vmlal.u32	q13,d29,d7[1]
284 285
	vmov	q8,q9
	vmov	q9,q10
286
	vshr.u64	d10,d10,#16
287 288
	vmov	q10,q11
	vmov	q11,q12
289
	vadd.u64	d10,d10,d11
290 291
	vmov	q12,q13
	veor	q13,q13
292 293 294 295 296
	vshr.u64	d10,d10,#16

	bne	.LNEON_outer8

	vadd.u64	d12,d12,d10
297
	mov	r7,sp
298
	vshr.u64	d10,d12,#16
299
	mov	r8,r5
300
	vadd.u64	d13,d13,d10
301
	add	r6,sp,#16
302
	vshr.u64	d10,d13,#16
303
	vzip.16	d12,d13
304 305 306 307 308 309

	b	.LNEON_tail2

.align	4
.LNEON_1st:
	vmlal.u32	q6,d29,d4[0]
310
	vld1.32	{d0,d1,d2,d3}, [r1]!
311
	vmlal.u32	q7,d29,d4[1]
312
	subs	r8,r8,#8
313 314 315 316
	vmlal.u32	q8,d29,d5[0]
	vmlal.u32	q9,d29,d5[1]

	vmlal.u32	q10,d29,d6[0]
317
	vld1.32	{d4,d5}, [r3]!
318
	vmlal.u32	q11,d29,d6[1]
319
	vst1.64	{q6,q7}, [r7,:256]!
320 321
	vmlal.u32	q12,d29,d7[0]
	vmlal.u32	q13,d29,d7[1]
322
	vst1.64	{q8,q9}, [r7,:256]!
323 324

	vmull.u32	q6,d28,d0[0]
325
	vld1.32	{d6,d7}, [r3]!
326
	vmull.u32	q7,d28,d0[1]
327
	vst1.64	{q10,q11}, [r7,:256]!
328 329
	vmull.u32	q8,d28,d1[0]
	vmull.u32	q9,d28,d1[1]
330
	vst1.64	{q12,q13}, [r7,:256]!
331 332 333 334 335 336 337 338 339

	vmull.u32	q10,d28,d2[0]
	vmull.u32	q11,d28,d2[1]
	vmull.u32	q12,d28,d3[0]
	vmull.u32	q13,d28,d3[1]

	bne	.LNEON_1st

	vmlal.u32	q6,d29,d4[0]
340
	add	r6,sp,#16
341
	vmlal.u32	q7,d29,d4[1]
342
	sub	r1,r1,r5,lsl#2		@ rewind r1
343
	vmlal.u32	q8,d29,d5[0]
344
	vld1.64	{q5}, [sp,:128]
345
	vmlal.u32	q9,d29,d5[1]
346
	sub	r9,r5,#1
347 348

	vmlal.u32	q10,d29,d6[0]
349
	vst1.64	{q6,q7}, [r7,:256]!
350 351
	vmlal.u32	q11,d29,d6[1]
	vshr.u64	d10,d10,#16
352
	vld1.64	{q6},       [r6, :128]!
353
	vmlal.u32	q12,d29,d7[0]
354
	vst1.64	{q8,q9}, [r7,:256]!
355 356
	vmlal.u32	q13,d29,d7[1]

357
	vst1.64	{q10,q11}, [r7,:256]!
358
	vadd.u64	d10,d10,d11
359 360 361 362
	veor	q4,q4,q4
	vst1.64	{q12,q13}, [r7,:256]!
	vld1.64	{q7,q8}, [r6, :256]!
	vst1.64	{q4},          [r7,:128]
363 364
	vshr.u64	d10,d10,#16

365
	b	.LNEON_outer
366 367 368

.align	4
.LNEON_outer:
369 370 371 372 373 374 375
	vld1.32	{d28[0]}, [r2,:32]!
	sub	r3,r3,r5,lsl#2		@ rewind r3
	vld1.32	{d0,d1,d2,d3},  [r1]!
	veor	d8,d8,d8
	mov	r7,sp
	vzip.16	d28,d8
	sub	r8,r5,#8
376 377 378
	vadd.u64	d12,d12,d10

	vmlal.u32	q6,d28,d0[0]
379
	vld1.64	{q9,q10},[r6,:256]!
380 381
	vmlal.u32	q7,d28,d0[1]
	vmlal.u32	q8,d28,d1[0]
382
	vld1.64	{q11,q12},[r6,:256]!
383 384 385
	vmlal.u32	q9,d28,d1[1]

	vshl.i64	d10,d13,#16
386
	veor	d8,d8,d8
387
	vadd.u64	d10,d10,d12
388
	vld1.64	{q13},[r6,:128]!
389 390 391
	vmul.u32	d29,d10,d30

	vmlal.u32	q10,d28,d2[0]
392
	vld1.32	{d4,d5,d6,d7}, [r3]!
393 394
	vmlal.u32	q11,d28,d2[1]
	vmlal.u32	q12,d28,d3[0]
395
	vzip.16	d29,d8
396 397 398 399
	vmlal.u32	q13,d28,d3[1]

.LNEON_inner:
	vmlal.u32	q6,d29,d4[0]
400
	vld1.32	{d0,d1,d2,d3}, [r1]!
401
	vmlal.u32	q7,d29,d4[1]
402
	subs	r8,r8,#8
403 404
	vmlal.u32	q8,d29,d5[0]
	vmlal.u32	q9,d29,d5[1]
405
	vst1.64	{q6,q7}, [r7,:256]!
406 407

	vmlal.u32	q10,d29,d6[0]
408
	vld1.64	{q6},       [r6, :128]!
409
	vmlal.u32	q11,d29,d6[1]
410
	vst1.64	{q8,q9}, [r7,:256]!
411
	vmlal.u32	q12,d29,d7[0]
412
	vld1.64	{q7,q8}, [r6, :256]!
413
	vmlal.u32	q13,d29,d7[1]
414
	vst1.64	{q10,q11}, [r7,:256]!
415 416

	vmlal.u32	q6,d28,d0[0]
417
	vld1.64	{q9,q10}, [r6, :256]!
418
	vmlal.u32	q7,d28,d0[1]
419
	vst1.64	{q12,q13}, [r7,:256]!
420
	vmlal.u32	q8,d28,d1[0]
421
	vld1.64	{q11,q12}, [r6, :256]!
422
	vmlal.u32	q9,d28,d1[1]
423
	vld1.32	{d4,d5,d6,d7}, [r3]!
424 425

	vmlal.u32	q10,d28,d2[0]
426
	vld1.64	{q13},       [r6, :128]!
427 428 429 430 431 432 433
	vmlal.u32	q11,d28,d2[1]
	vmlal.u32	q12,d28,d3[0]
	vmlal.u32	q13,d28,d3[1]

	bne	.LNEON_inner

	vmlal.u32	q6,d29,d4[0]
434
	add	r6,sp,#16
435
	vmlal.u32	q7,d29,d4[1]
436
	sub	r1,r1,r5,lsl#2		@ rewind r1
437
	vmlal.u32	q8,d29,d5[0]
438
	vld1.64	{q5}, [sp,:128]
439
	vmlal.u32	q9,d29,d5[1]
440
	subs	r9,r9,#1
441 442

	vmlal.u32	q10,d29,d6[0]
443
	vst1.64	{q6,q7}, [r7,:256]!
444
	vmlal.u32	q11,d29,d6[1]
445
	vld1.64	{q6},       [r6, :128]!
446
	vshr.u64	d10,d10,#16
447
	vst1.64	{q8,q9}, [r7,:256]!
448
	vmlal.u32	q12,d29,d7[0]
449
	vld1.64	{q7,q8}, [r6, :256]!
450 451
	vmlal.u32	q13,d29,d7[1]

452
	vst1.64	{q10,q11}, [r7,:256]!
453
	vadd.u64	d10,d10,d11
454
	vst1.64	{q12,q13}, [r7,:256]!
455 456 457 458
	vshr.u64	d10,d10,#16

	bne	.LNEON_outer

459 460
	mov	r7,sp
	mov	r8,r5
461 462 463

.LNEON_tail:
	vadd.u64	d12,d12,d10
464
	vld1.64	{q9,q10}, [r6, :256]!
465 466
	vshr.u64	d10,d12,#16
	vadd.u64	d13,d13,d10
467
	vld1.64	{q11,q12}, [r6, :256]!
468
	vshr.u64	d10,d13,#16
469 470
	vld1.64	{q13},       [r6, :128]!
	vzip.16	d12,d13
471 472 473

.LNEON_tail2:
	vadd.u64	d14,d14,d10
474
	vst1.32	{d12[0]}, [r7, :32]!
475 476 477
	vshr.u64	d10,d14,#16
	vadd.u64	d15,d15,d10
	vshr.u64	d10,d15,#16
478
	vzip.16	d14,d15
479 480

	vadd.u64	d16,d16,d10
481
	vst1.32	{d14[0]}, [r7, :32]!
482 483 484
	vshr.u64	d10,d16,#16
	vadd.u64	d17,d17,d10
	vshr.u64	d10,d17,#16
485
	vzip.16	d16,d17
486 487

	vadd.u64	d18,d18,d10
488
	vst1.32	{d16[0]}, [r7, :32]!
489 490 491
	vshr.u64	d10,d18,#16
	vadd.u64	d19,d19,d10
	vshr.u64	d10,d19,#16
492
	vzip.16	d18,d19
493 494

	vadd.u64	d20,d20,d10
495
	vst1.32	{d18[0]}, [r7, :32]!
496 497 498
	vshr.u64	d10,d20,#16
	vadd.u64	d21,d21,d10
	vshr.u64	d10,d21,#16
499
	vzip.16	d20,d21
500 501

	vadd.u64	d22,d22,d10
502
	vst1.32	{d20[0]}, [r7, :32]!
503 504 505
	vshr.u64	d10,d22,#16
	vadd.u64	d23,d23,d10
	vshr.u64	d10,d23,#16
506
	vzip.16	d22,d23
507 508

	vadd.u64	d24,d24,d10
509
	vst1.32	{d22[0]}, [r7, :32]!
510 511
	vshr.u64	d10,d24,#16
	vadd.u64	d25,d25,d10
512
	vld1.64	{q6}, [r6, :128]!
513
	vshr.u64	d10,d25,#16
514
	vzip.16	d24,d25
515 516

	vadd.u64	d26,d26,d10
517
	vst1.32	{d24[0]}, [r7, :32]!
518 519
	vshr.u64	d10,d26,#16
	vadd.u64	d27,d27,d10
520
	vld1.64	{q7,q8},	[r6, :256]!
521
	vshr.u64	d10,d27,#16
522 523 524
	vzip.16	d26,d27
	subs	r8,r8,#8
	vst1.32	{d26[0]}, [r7, :32]!
525 526 527 528 529 530 531 532 533

	bne	.LNEON_tail

	vst1.32	{d10[0]}, [r7, :32]		@ top-most bit
	sub	r3,r3,r5,lsl#2			@ rewind r3
	subs	r1,sp,#0				@ clear carry flag
	add	r2,sp,r5,lsl#2

.LNEON_sub:
534 535
	ldmia	r1!, {r4,r5,r6,r7}
	ldmia	r3!, {r8,r9,r10,r11}
536 537 538 539 540
	sbcs	r8, r4,r8
	sbcs	r9, r5,r9
	sbcs	r10,r6,r10
	sbcs	r11,r7,r11
	teq	r1,r2				@ preserves carry
541
	stmia	r0!, {r8,r9,r10,r11}
542 543 544 545 546 547 548 549 550 551 552 553
	bne	.LNEON_sub

	ldr	r10, [r1]				@ load top-most bit
	veor	q0,q0,q0
	sub	r11,r2,sp				@ this is num*4
	veor	q1,q1,q1
	mov	r1,sp
	sub	r0,r0,r11				@ rewind r0
	mov	r3,r2				@ second 3/4th of frame
	sbcs	r10,r10,#0				@ result is carry flag

.LNEON_copy_n_zap:
554 555
	ldmia	r1!, {r4,r5,r6,r7}
	ldmia	r0,  {r8,r9,r10,r11}
556
	movcc	r8, r4
557
	vst1.64	{q0,q1}, [r3,:256]!			@ wipe
558 559
	movcc	r9, r5
	movcc	r10,r6
560
	vst1.64	{q0,q1}, [r3,:256]!			@ wipe
561
	movcc	r11,r7
562 563
	ldmia	r1, {r4,r5,r6,r7}
	stmia	r0!, {r8,r9,r10,r11}
564
	sub	r1,r1,#16
565
	ldmia	r0, {r8,r9,r10,r11}
566
	movcc	r8, r4
567
	vst1.64	{q0,q1}, [r1,:256]!			@ wipe
568 569
	movcc	r9, r5
	movcc	r10,r6
570
	vst1.64	{q0,q1}, [r3,:256]!			@ wipe
571 572
	movcc	r11,r7
	teq	r1,r2				@ preserves carry
573
	stmia	r0!, {r8,r9,r10,r11}
574 575 576
	bne	.LNEON_copy_n_zap

	sub	sp,ip,#96
577 578 579
	vldmia	sp!,{d8,d9,d10,d11,d12,d13,d14,d15}
	ldmia	sp!,{r4,r5,r6,r7,r8,r9,r10,r11}
	bx	lr						@ .word	0xe12fff1e
580 581
.size	bn_mul8x_mont_neon,.-bn_mul8x_mont_neon
#endif
582 583
.byte	77,111,110,116,103,111,109,101,114,121,32,109,117,108,116,105,112,108,105,99,97,116,105,111,110,32,102,111,114,32,65,82,77,118,52,47,78,69,79,78,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121,32,60,97,112,112,114,111,64,111,112,101,110,115,115,108,46,111,114,103,62,0
.align	2
584
.align	2
585
#if __ARM_MAX_ARCH__>=7
586
.comm	OPENSSL_armcap_P,4,4
587
.hidden	OPENSSL_armcap_P
588
#endif
589
#endif