blob: 1d516ef9ba53b61d09b35b521fe627555e876cf0 [file] [log] [blame]
Robert Sloan8ff03552017-06-14 12:40:58 -07001#include <openssl/arm_arch.h>
2
3.text
4#if defined(__thumb2__)
5.syntax unified
6.thumb
7#else
8.code 32
9#endif
10
11#if __ARM_MAX_ARCH__>=7
12.align 5
13LOPENSSL_armcap:
14.word OPENSSL_armcap_P-Lbn_mul_mont
15#endif
16
17.globl _bn_mul_mont
18.private_extern _bn_mul_mont
19#ifdef __thumb2__
20.thumb_func _bn_mul_mont
21#endif
22
23.align 5
24_bn_mul_mont:
25Lbn_mul_mont:
26 ldr ip,[sp,#4] @ load num
27 stmdb sp!,{r0,r2} @ sp points at argument block
28#if __ARM_MAX_ARCH__>=7
29 tst ip,#7
30 bne Lialu
31 adr r0,Lbn_mul_mont
32 ldr r2,LOPENSSL_armcap
33 ldr r0,[r0,r2]
34#ifdef __APPLE__
35 ldr r0,[r0]
36#endif
37 tst r0,#ARMV7_NEON @ NEON available?
38 ldmia sp, {r0,r2}
39 beq Lialu
40 add sp,sp,#8
41 b bn_mul8x_mont_neon
42.align 4
43Lialu:
44#endif
45 cmp ip,#2
46 mov r0,ip @ load num
47#ifdef __thumb2__
48 ittt lt
49#endif
50 movlt r0,#0
51 addlt sp,sp,#2*4
52 blt Labrt
53
54 stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} @ save 10 registers
55
56 mov r0,r0,lsl#2 @ rescale r0 for byte count
57 sub sp,sp,r0 @ alloca(4*num)
58 sub sp,sp,#4 @ +extra dword
59 sub r0,r0,#4 @ "num=num-1"
60 add r4,r2,r0 @ &bp[num-1]
61
62 add r0,sp,r0 @ r0 to point at &tp[num-1]
63 ldr r8,[r0,#14*4] @ &n0
64 ldr r2,[r2] @ bp[0]
65 ldr r5,[r1],#4 @ ap[0],ap++
66 ldr r6,[r3],#4 @ np[0],np++
67 ldr r8,[r8] @ *n0
68 str r4,[r0,#15*4] @ save &bp[num]
69
70 umull r10,r11,r5,r2 @ ap[0]*bp[0]
71 str r8,[r0,#14*4] @ save n0 value
72 mul r8,r10,r8 @ "tp[0]"*n0
73 mov r12,#0
74 umlal r10,r12,r6,r8 @ np[0]*n0+"t[0]"
75 mov r4,sp
76
77L1st:
78 ldr r5,[r1],#4 @ ap[j],ap++
79 mov r10,r11
80 ldr r6,[r3],#4 @ np[j],np++
81 mov r11,#0
82 umlal r10,r11,r5,r2 @ ap[j]*bp[0]
83 mov r14,#0
84 umlal r12,r14,r6,r8 @ np[j]*n0
85 adds r12,r12,r10
86 str r12,[r4],#4 @ tp[j-1]=,tp++
87 adc r12,r14,#0
88 cmp r4,r0
89 bne L1st
90
91 adds r12,r12,r11
92 ldr r4,[r0,#13*4] @ restore bp
93 mov r14,#0
94 ldr r8,[r0,#14*4] @ restore n0
95 adc r14,r14,#0
96 str r12,[r0] @ tp[num-1]=
97 mov r7,sp
98 str r14,[r0,#4] @ tp[num]=
99
100Louter:
101 sub r7,r0,r7 @ "original" r0-1 value
102 sub r1,r1,r7 @ "rewind" ap to &ap[1]
103 ldr r2,[r4,#4]! @ *(++bp)
104 sub r3,r3,r7 @ "rewind" np to &np[1]
105 ldr r5,[r1,#-4] @ ap[0]
106 ldr r10,[sp] @ tp[0]
107 ldr r6,[r3,#-4] @ np[0]
108 ldr r7,[sp,#4] @ tp[1]
109
110 mov r11,#0
111 umlal r10,r11,r5,r2 @ ap[0]*bp[i]+tp[0]
112 str r4,[r0,#13*4] @ save bp
113 mul r8,r10,r8
114 mov r12,#0
115 umlal r10,r12,r6,r8 @ np[0]*n0+"tp[0]"
116 mov r4,sp
117
118Linner:
119 ldr r5,[r1],#4 @ ap[j],ap++
120 adds r10,r11,r7 @ +=tp[j]
121 ldr r6,[r3],#4 @ np[j],np++
122 mov r11,#0
123 umlal r10,r11,r5,r2 @ ap[j]*bp[i]
124 mov r14,#0
125 umlal r12,r14,r6,r8 @ np[j]*n0
126 adc r11,r11,#0
127 ldr r7,[r4,#8] @ tp[j+1]
128 adds r12,r12,r10
129 str r12,[r4],#4 @ tp[j-1]=,tp++
130 adc r12,r14,#0
131 cmp r4,r0
132 bne Linner
133
134 adds r12,r12,r11
135 mov r14,#0
136 ldr r4,[r0,#13*4] @ restore bp
137 adc r14,r14,#0
138 ldr r8,[r0,#14*4] @ restore n0
139 adds r12,r12,r7
140 ldr r7,[r0,#15*4] @ restore &bp[num]
141 adc r14,r14,#0
142 str r12,[r0] @ tp[num-1]=
143 str r14,[r0,#4] @ tp[num]=
144
145 cmp r4,r7
146#ifdef __thumb2__
147 itt ne
148#endif
149 movne r7,sp
150 bne Louter
151
152 ldr r2,[r0,#12*4] @ pull rp
153 mov r5,sp
154 add r0,r0,#4 @ r0 to point at &tp[num]
155 sub r5,r0,r5 @ "original" num value
156 mov r4,sp @ "rewind" r4
157 mov r1,r4 @ "borrow" r1
158 sub r3,r3,r5 @ "rewind" r3 to &np[0]
159
160 subs r7,r7,r7 @ "clear" carry flag
161Lsub: ldr r7,[r4],#4
162 ldr r6,[r3],#4
163 sbcs r7,r7,r6 @ tp[j]-np[j]
164 str r7,[r2],#4 @ rp[j]=
165 teq r4,r0 @ preserve carry
166 bne Lsub
167 sbcs r14,r14,#0 @ upmost carry
168 mov r4,sp @ "rewind" r4
169 sub r2,r2,r5 @ "rewind" r2
170
171 and r1,r4,r14
172 bic r3,r2,r14
173 orr r1,r1,r3 @ ap=borrow?tp:rp
174
175Lcopy: ldr r7,[r1],#4 @ copy or in-place refresh
176 str sp,[r4],#4 @ zap tp
177 str r7,[r2],#4
178 cmp r4,r0
179 bne Lcopy
180
181 mov sp,r0
182 add sp,sp,#4 @ skip over tp[num+1]
183 ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11,r12,lr} @ restore registers
184 add sp,sp,#2*4 @ skip over {r0,r2}
185 mov r0,#1
186Labrt:
187#if __ARM_ARCH__>=5
188 bx lr @ bx lr
189#else
190 tst lr,#1
191 moveq pc,lr @ be binary compatible with V4, yet
192.word 0xe12fff1e @ interoperable with Thumb ISA:-)
193#endif
194
195#if __ARM_MAX_ARCH__>=7
196
197
198
199#ifdef __thumb2__
200.thumb_func bn_mul8x_mont_neon
201#endif
202.align 5
203bn_mul8x_mont_neon:
204 mov ip,sp
205 stmdb sp!,{r4,r5,r6,r7,r8,r9,r10,r11}
206 vstmdb sp!,{d8,d9,d10,d11,d12,d13,d14,d15} @ ABI specification says so
207 ldmia ip,{r4,r5} @ load rest of parameter block
208 mov ip,sp
209
210 cmp r5,#8
211 bhi LNEON_8n
212
213 @ special case for r5==8, everything is in register bank...
214
215 vld1.32 {d28[0]}, [r2,:32]!
216 veor d8,d8,d8
217 sub r7,sp,r5,lsl#4
218 vld1.32 {d0,d1,d2,d3}, [r1]! @ can't specify :32 :-(
219 and r7,r7,#-64
220 vld1.32 {d30[0]}, [r4,:32]
221 mov sp,r7 @ alloca
222 vzip.16 d28,d8
223
224 vmull.u32 q6,d28,d0[0]
225 vmull.u32 q7,d28,d0[1]
226 vmull.u32 q8,d28,d1[0]
227 vshl.i64 d29,d13,#16
228 vmull.u32 q9,d28,d1[1]
229
230 vadd.u64 d29,d29,d12
231 veor d8,d8,d8
232 vmul.u32 d29,d29,d30
233
234 vmull.u32 q10,d28,d2[0]
235 vld1.32 {d4,d5,d6,d7}, [r3]!
236 vmull.u32 q11,d28,d2[1]
237 vmull.u32 q12,d28,d3[0]
238 vzip.16 d29,d8
239 vmull.u32 q13,d28,d3[1]
240
241 vmlal.u32 q6,d29,d4[0]
242 sub r9,r5,#1
243 vmlal.u32 q7,d29,d4[1]
244 vmlal.u32 q8,d29,d5[0]
245 vmlal.u32 q9,d29,d5[1]
246
247 vmlal.u32 q10,d29,d6[0]
248 vmov q5,q6
249 vmlal.u32 q11,d29,d6[1]
250 vmov q6,q7
251 vmlal.u32 q12,d29,d7[0]
252 vmov q7,q8
253 vmlal.u32 q13,d29,d7[1]
254 vmov q8,q9
255 vmov q9,q10
256 vshr.u64 d10,d10,#16
257 vmov q10,q11
258 vmov q11,q12
259 vadd.u64 d10,d10,d11
260 vmov q12,q13
261 veor q13,q13
262 vshr.u64 d10,d10,#16
263
264 b LNEON_outer8
265
266.align 4
267LNEON_outer8:
268 vld1.32 {d28[0]}, [r2,:32]!
269 veor d8,d8,d8
270 vzip.16 d28,d8
271 vadd.u64 d12,d12,d10
272
273 vmlal.u32 q6,d28,d0[0]
274 vmlal.u32 q7,d28,d0[1]
275 vmlal.u32 q8,d28,d1[0]
276 vshl.i64 d29,d13,#16
277 vmlal.u32 q9,d28,d1[1]
278
279 vadd.u64 d29,d29,d12
280 veor d8,d8,d8
281 subs r9,r9,#1
282 vmul.u32 d29,d29,d30
283
284 vmlal.u32 q10,d28,d2[0]
285 vmlal.u32 q11,d28,d2[1]
286 vmlal.u32 q12,d28,d3[0]
287 vzip.16 d29,d8
288 vmlal.u32 q13,d28,d3[1]
289
290 vmlal.u32 q6,d29,d4[0]
291 vmlal.u32 q7,d29,d4[1]
292 vmlal.u32 q8,d29,d5[0]
293 vmlal.u32 q9,d29,d5[1]
294
295 vmlal.u32 q10,d29,d6[0]
296 vmov q5,q6
297 vmlal.u32 q11,d29,d6[1]
298 vmov q6,q7
299 vmlal.u32 q12,d29,d7[0]
300 vmov q7,q8
301 vmlal.u32 q13,d29,d7[1]
302 vmov q8,q9
303 vmov q9,q10
304 vshr.u64 d10,d10,#16
305 vmov q10,q11
306 vmov q11,q12
307 vadd.u64 d10,d10,d11
308 vmov q12,q13
309 veor q13,q13
310 vshr.u64 d10,d10,#16
311
312 bne LNEON_outer8
313
314 vadd.u64 d12,d12,d10
315 mov r7,sp
316 vshr.u64 d10,d12,#16
317 mov r8,r5
318 vadd.u64 d13,d13,d10
319 add r6,sp,#96
320 vshr.u64 d10,d13,#16
321 vzip.16 d12,d13
322
323 b LNEON_tail_entry
324
325.align 4
326LNEON_8n:
327 veor q6,q6,q6
328 sub r7,sp,#128
329 veor q7,q7,q7
330 sub r7,r7,r5,lsl#4
331 veor q8,q8,q8
332 and r7,r7,#-64
333 veor q9,q9,q9
334 mov sp,r7 @ alloca
335 veor q10,q10,q10
336 add r7,r7,#256
337 veor q11,q11,q11
338 sub r8,r5,#8
339 veor q12,q12,q12
340 veor q13,q13,q13
341
342LNEON_8n_init:
343 vst1.64 {q6,q7},[r7,:256]!
344 subs r8,r8,#8
345 vst1.64 {q8,q9},[r7,:256]!
346 vst1.64 {q10,q11},[r7,:256]!
347 vst1.64 {q12,q13},[r7,:256]!
348 bne LNEON_8n_init
349
350 add r6,sp,#256
351 vld1.32 {d0,d1,d2,d3},[r1]!
352 add r10,sp,#8
353 vld1.32 {d30[0]},[r4,:32]
354 mov r9,r5
355 b LNEON_8n_outer
356
357.align 4
358LNEON_8n_outer:
359 vld1.32 {d28[0]},[r2,:32]! @ *b++
360 veor d8,d8,d8
361 vzip.16 d28,d8
362 add r7,sp,#128
363 vld1.32 {d4,d5,d6,d7},[r3]!
364
365 vmlal.u32 q6,d28,d0[0]
366 vmlal.u32 q7,d28,d0[1]
367 veor d8,d8,d8
368 vmlal.u32 q8,d28,d1[0]
369 vshl.i64 d29,d13,#16
370 vmlal.u32 q9,d28,d1[1]
371 vadd.u64 d29,d29,d12
372 vmlal.u32 q10,d28,d2[0]
373 vmul.u32 d29,d29,d30
374 vmlal.u32 q11,d28,d2[1]
375 vst1.32 {d28},[sp,:64] @ put aside smashed b[8*i+0]
376 vmlal.u32 q12,d28,d3[0]
377 vzip.16 d29,d8
378 vmlal.u32 q13,d28,d3[1]
379 vld1.32 {d28[0]},[r2,:32]! @ *b++
380 vmlal.u32 q6,d29,d4[0]
381 veor d10,d10,d10
382 vmlal.u32 q7,d29,d4[1]
383 vzip.16 d28,d10
384 vmlal.u32 q8,d29,d5[0]
385 vshr.u64 d12,d12,#16
386 vmlal.u32 q9,d29,d5[1]
387 vmlal.u32 q10,d29,d6[0]
388 vadd.u64 d12,d12,d13
389 vmlal.u32 q11,d29,d6[1]
390 vshr.u64 d12,d12,#16
391 vmlal.u32 q12,d29,d7[0]
392 vmlal.u32 q13,d29,d7[1]
393 vadd.u64 d14,d14,d12
394 vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+0]
395 vmlal.u32 q7,d28,d0[0]
396 vld1.64 {q6},[r6,:128]!
397 vmlal.u32 q8,d28,d0[1]
398 veor d8,d8,d8
399 vmlal.u32 q9,d28,d1[0]
400 vshl.i64 d29,d15,#16
401 vmlal.u32 q10,d28,d1[1]
402 vadd.u64 d29,d29,d14
403 vmlal.u32 q11,d28,d2[0]
404 vmul.u32 d29,d29,d30
405 vmlal.u32 q12,d28,d2[1]
406 vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+1]
407 vmlal.u32 q13,d28,d3[0]
408 vzip.16 d29,d8
409 vmlal.u32 q6,d28,d3[1]
410 vld1.32 {d28[0]},[r2,:32]! @ *b++
411 vmlal.u32 q7,d29,d4[0]
412 veor d10,d10,d10
413 vmlal.u32 q8,d29,d4[1]
414 vzip.16 d28,d10
415 vmlal.u32 q9,d29,d5[0]
416 vshr.u64 d14,d14,#16
417 vmlal.u32 q10,d29,d5[1]
418 vmlal.u32 q11,d29,d6[0]
419 vadd.u64 d14,d14,d15
420 vmlal.u32 q12,d29,d6[1]
421 vshr.u64 d14,d14,#16
422 vmlal.u32 q13,d29,d7[0]
423 vmlal.u32 q6,d29,d7[1]
424 vadd.u64 d16,d16,d14
425 vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+1]
426 vmlal.u32 q8,d28,d0[0]
427 vld1.64 {q7},[r6,:128]!
428 vmlal.u32 q9,d28,d0[1]
429 veor d8,d8,d8
430 vmlal.u32 q10,d28,d1[0]
431 vshl.i64 d29,d17,#16
432 vmlal.u32 q11,d28,d1[1]
433 vadd.u64 d29,d29,d16
434 vmlal.u32 q12,d28,d2[0]
435 vmul.u32 d29,d29,d30
436 vmlal.u32 q13,d28,d2[1]
437 vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+2]
438 vmlal.u32 q6,d28,d3[0]
439 vzip.16 d29,d8
440 vmlal.u32 q7,d28,d3[1]
441 vld1.32 {d28[0]},[r2,:32]! @ *b++
442 vmlal.u32 q8,d29,d4[0]
443 veor d10,d10,d10
444 vmlal.u32 q9,d29,d4[1]
445 vzip.16 d28,d10
446 vmlal.u32 q10,d29,d5[0]
447 vshr.u64 d16,d16,#16
448 vmlal.u32 q11,d29,d5[1]
449 vmlal.u32 q12,d29,d6[0]
450 vadd.u64 d16,d16,d17
451 vmlal.u32 q13,d29,d6[1]
452 vshr.u64 d16,d16,#16
453 vmlal.u32 q6,d29,d7[0]
454 vmlal.u32 q7,d29,d7[1]
455 vadd.u64 d18,d18,d16
456 vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+2]
457 vmlal.u32 q9,d28,d0[0]
458 vld1.64 {q8},[r6,:128]!
459 vmlal.u32 q10,d28,d0[1]
460 veor d8,d8,d8
461 vmlal.u32 q11,d28,d1[0]
462 vshl.i64 d29,d19,#16
463 vmlal.u32 q12,d28,d1[1]
464 vadd.u64 d29,d29,d18
465 vmlal.u32 q13,d28,d2[0]
466 vmul.u32 d29,d29,d30
467 vmlal.u32 q6,d28,d2[1]
468 vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+3]
469 vmlal.u32 q7,d28,d3[0]
470 vzip.16 d29,d8
471 vmlal.u32 q8,d28,d3[1]
472 vld1.32 {d28[0]},[r2,:32]! @ *b++
473 vmlal.u32 q9,d29,d4[0]
474 veor d10,d10,d10
475 vmlal.u32 q10,d29,d4[1]
476 vzip.16 d28,d10
477 vmlal.u32 q11,d29,d5[0]
478 vshr.u64 d18,d18,#16
479 vmlal.u32 q12,d29,d5[1]
480 vmlal.u32 q13,d29,d6[0]
481 vadd.u64 d18,d18,d19
482 vmlal.u32 q6,d29,d6[1]
483 vshr.u64 d18,d18,#16
484 vmlal.u32 q7,d29,d7[0]
485 vmlal.u32 q8,d29,d7[1]
486 vadd.u64 d20,d20,d18
487 vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+3]
488 vmlal.u32 q10,d28,d0[0]
489 vld1.64 {q9},[r6,:128]!
490 vmlal.u32 q11,d28,d0[1]
491 veor d8,d8,d8
492 vmlal.u32 q12,d28,d1[0]
493 vshl.i64 d29,d21,#16
494 vmlal.u32 q13,d28,d1[1]
495 vadd.u64 d29,d29,d20
496 vmlal.u32 q6,d28,d2[0]
497 vmul.u32 d29,d29,d30
498 vmlal.u32 q7,d28,d2[1]
499 vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+4]
500 vmlal.u32 q8,d28,d3[0]
501 vzip.16 d29,d8
502 vmlal.u32 q9,d28,d3[1]
503 vld1.32 {d28[0]},[r2,:32]! @ *b++
504 vmlal.u32 q10,d29,d4[0]
505 veor d10,d10,d10
506 vmlal.u32 q11,d29,d4[1]
507 vzip.16 d28,d10
508 vmlal.u32 q12,d29,d5[0]
509 vshr.u64 d20,d20,#16
510 vmlal.u32 q13,d29,d5[1]
511 vmlal.u32 q6,d29,d6[0]
512 vadd.u64 d20,d20,d21
513 vmlal.u32 q7,d29,d6[1]
514 vshr.u64 d20,d20,#16
515 vmlal.u32 q8,d29,d7[0]
516 vmlal.u32 q9,d29,d7[1]
517 vadd.u64 d22,d22,d20
518 vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+4]
519 vmlal.u32 q11,d28,d0[0]
520 vld1.64 {q10},[r6,:128]!
521 vmlal.u32 q12,d28,d0[1]
522 veor d8,d8,d8
523 vmlal.u32 q13,d28,d1[0]
524 vshl.i64 d29,d23,#16
525 vmlal.u32 q6,d28,d1[1]
526 vadd.u64 d29,d29,d22
527 vmlal.u32 q7,d28,d2[0]
528 vmul.u32 d29,d29,d30
529 vmlal.u32 q8,d28,d2[1]
530 vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+5]
531 vmlal.u32 q9,d28,d3[0]
532 vzip.16 d29,d8
533 vmlal.u32 q10,d28,d3[1]
534 vld1.32 {d28[0]},[r2,:32]! @ *b++
535 vmlal.u32 q11,d29,d4[0]
536 veor d10,d10,d10
537 vmlal.u32 q12,d29,d4[1]
538 vzip.16 d28,d10
539 vmlal.u32 q13,d29,d5[0]
540 vshr.u64 d22,d22,#16
541 vmlal.u32 q6,d29,d5[1]
542 vmlal.u32 q7,d29,d6[0]
543 vadd.u64 d22,d22,d23
544 vmlal.u32 q8,d29,d6[1]
545 vshr.u64 d22,d22,#16
546 vmlal.u32 q9,d29,d7[0]
547 vmlal.u32 q10,d29,d7[1]
548 vadd.u64 d24,d24,d22
549 vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+5]
550 vmlal.u32 q12,d28,d0[0]
551 vld1.64 {q11},[r6,:128]!
552 vmlal.u32 q13,d28,d0[1]
553 veor d8,d8,d8
554 vmlal.u32 q6,d28,d1[0]
555 vshl.i64 d29,d25,#16
556 vmlal.u32 q7,d28,d1[1]
557 vadd.u64 d29,d29,d24
558 vmlal.u32 q8,d28,d2[0]
559 vmul.u32 d29,d29,d30
560 vmlal.u32 q9,d28,d2[1]
561 vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+6]
562 vmlal.u32 q10,d28,d3[0]
563 vzip.16 d29,d8
564 vmlal.u32 q11,d28,d3[1]
565 vld1.32 {d28[0]},[r2,:32]! @ *b++
566 vmlal.u32 q12,d29,d4[0]
567 veor d10,d10,d10
568 vmlal.u32 q13,d29,d4[1]
569 vzip.16 d28,d10
570 vmlal.u32 q6,d29,d5[0]
571 vshr.u64 d24,d24,#16
572 vmlal.u32 q7,d29,d5[1]
573 vmlal.u32 q8,d29,d6[0]
574 vadd.u64 d24,d24,d25
575 vmlal.u32 q9,d29,d6[1]
576 vshr.u64 d24,d24,#16
577 vmlal.u32 q10,d29,d7[0]
578 vmlal.u32 q11,d29,d7[1]
579 vadd.u64 d26,d26,d24
580 vst1.32 {d29},[r10,:64]! @ put aside smashed m[8*i+6]
581 vmlal.u32 q13,d28,d0[0]
582 vld1.64 {q12},[r6,:128]!
583 vmlal.u32 q6,d28,d0[1]
584 veor d8,d8,d8
585 vmlal.u32 q7,d28,d1[0]
586 vshl.i64 d29,d27,#16
587 vmlal.u32 q8,d28,d1[1]
588 vadd.u64 d29,d29,d26
589 vmlal.u32 q9,d28,d2[0]
590 vmul.u32 d29,d29,d30
591 vmlal.u32 q10,d28,d2[1]
592 vst1.32 {d28},[r10,:64]! @ put aside smashed b[8*i+7]
593 vmlal.u32 q11,d28,d3[0]
594 vzip.16 d29,d8
595 vmlal.u32 q12,d28,d3[1]
596 vld1.32 {d28},[sp,:64] @ pull smashed b[8*i+0]
597 vmlal.u32 q13,d29,d4[0]
598 vld1.32 {d0,d1,d2,d3},[r1]!
599 vmlal.u32 q6,d29,d4[1]
600 vmlal.u32 q7,d29,d5[0]
601 vshr.u64 d26,d26,#16
602 vmlal.u32 q8,d29,d5[1]
603 vmlal.u32 q9,d29,d6[0]
604 vadd.u64 d26,d26,d27
605 vmlal.u32 q10,d29,d6[1]
606 vshr.u64 d26,d26,#16
607 vmlal.u32 q11,d29,d7[0]
608 vmlal.u32 q12,d29,d7[1]
609 vadd.u64 d12,d12,d26
610 vst1.32 {d29},[r10,:64] @ put aside smashed m[8*i+7]
611 add r10,sp,#8 @ rewind
612 sub r8,r5,#8
613 b LNEON_8n_inner
614
615.align 4
616LNEON_8n_inner:
617 subs r8,r8,#8
618 vmlal.u32 q6,d28,d0[0]
619 vld1.64 {q13},[r6,:128]
620 vmlal.u32 q7,d28,d0[1]
621 vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+0]
622 vmlal.u32 q8,d28,d1[0]
623 vld1.32 {d4,d5,d6,d7},[r3]!
624 vmlal.u32 q9,d28,d1[1]
625 it ne
626 addne r6,r6,#16 @ don't advance in last iteration
627 vmlal.u32 q10,d28,d2[0]
628 vmlal.u32 q11,d28,d2[1]
629 vmlal.u32 q12,d28,d3[0]
630 vmlal.u32 q13,d28,d3[1]
631 vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+1]
632 vmlal.u32 q6,d29,d4[0]
633 vmlal.u32 q7,d29,d4[1]
634 vmlal.u32 q8,d29,d5[0]
635 vmlal.u32 q9,d29,d5[1]
636 vmlal.u32 q10,d29,d6[0]
637 vmlal.u32 q11,d29,d6[1]
638 vmlal.u32 q12,d29,d7[0]
639 vmlal.u32 q13,d29,d7[1]
640 vst1.64 {q6},[r7,:128]!
641 vmlal.u32 q7,d28,d0[0]
642 vld1.64 {q6},[r6,:128]
643 vmlal.u32 q8,d28,d0[1]
644 vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+1]
645 vmlal.u32 q9,d28,d1[0]
646 it ne
647 addne r6,r6,#16 @ don't advance in last iteration
648 vmlal.u32 q10,d28,d1[1]
649 vmlal.u32 q11,d28,d2[0]
650 vmlal.u32 q12,d28,d2[1]
651 vmlal.u32 q13,d28,d3[0]
652 vmlal.u32 q6,d28,d3[1]
653 vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+2]
654 vmlal.u32 q7,d29,d4[0]
655 vmlal.u32 q8,d29,d4[1]
656 vmlal.u32 q9,d29,d5[0]
657 vmlal.u32 q10,d29,d5[1]
658 vmlal.u32 q11,d29,d6[0]
659 vmlal.u32 q12,d29,d6[1]
660 vmlal.u32 q13,d29,d7[0]
661 vmlal.u32 q6,d29,d7[1]
662 vst1.64 {q7},[r7,:128]!
663 vmlal.u32 q8,d28,d0[0]
664 vld1.64 {q7},[r6,:128]
665 vmlal.u32 q9,d28,d0[1]
666 vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+2]
667 vmlal.u32 q10,d28,d1[0]
668 it ne
669 addne r6,r6,#16 @ don't advance in last iteration
670 vmlal.u32 q11,d28,d1[1]
671 vmlal.u32 q12,d28,d2[0]
672 vmlal.u32 q13,d28,d2[1]
673 vmlal.u32 q6,d28,d3[0]
674 vmlal.u32 q7,d28,d3[1]
675 vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+3]
676 vmlal.u32 q8,d29,d4[0]
677 vmlal.u32 q9,d29,d4[1]
678 vmlal.u32 q10,d29,d5[0]
679 vmlal.u32 q11,d29,d5[1]
680 vmlal.u32 q12,d29,d6[0]
681 vmlal.u32 q13,d29,d6[1]
682 vmlal.u32 q6,d29,d7[0]
683 vmlal.u32 q7,d29,d7[1]
684 vst1.64 {q8},[r7,:128]!
685 vmlal.u32 q9,d28,d0[0]
686 vld1.64 {q8},[r6,:128]
687 vmlal.u32 q10,d28,d0[1]
688 vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+3]
689 vmlal.u32 q11,d28,d1[0]
690 it ne
691 addne r6,r6,#16 @ don't advance in last iteration
692 vmlal.u32 q12,d28,d1[1]
693 vmlal.u32 q13,d28,d2[0]
694 vmlal.u32 q6,d28,d2[1]
695 vmlal.u32 q7,d28,d3[0]
696 vmlal.u32 q8,d28,d3[1]
697 vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+4]
698 vmlal.u32 q9,d29,d4[0]
699 vmlal.u32 q10,d29,d4[1]
700 vmlal.u32 q11,d29,d5[0]
701 vmlal.u32 q12,d29,d5[1]
702 vmlal.u32 q13,d29,d6[0]
703 vmlal.u32 q6,d29,d6[1]
704 vmlal.u32 q7,d29,d7[0]
705 vmlal.u32 q8,d29,d7[1]
706 vst1.64 {q9},[r7,:128]!
707 vmlal.u32 q10,d28,d0[0]
708 vld1.64 {q9},[r6,:128]
709 vmlal.u32 q11,d28,d0[1]
710 vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+4]
711 vmlal.u32 q12,d28,d1[0]
712 it ne
713 addne r6,r6,#16 @ don't advance in last iteration
714 vmlal.u32 q13,d28,d1[1]
715 vmlal.u32 q6,d28,d2[0]
716 vmlal.u32 q7,d28,d2[1]
717 vmlal.u32 q8,d28,d3[0]
718 vmlal.u32 q9,d28,d3[1]
719 vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+5]
720 vmlal.u32 q10,d29,d4[0]
721 vmlal.u32 q11,d29,d4[1]
722 vmlal.u32 q12,d29,d5[0]
723 vmlal.u32 q13,d29,d5[1]
724 vmlal.u32 q6,d29,d6[0]
725 vmlal.u32 q7,d29,d6[1]
726 vmlal.u32 q8,d29,d7[0]
727 vmlal.u32 q9,d29,d7[1]
728 vst1.64 {q10},[r7,:128]!
729 vmlal.u32 q11,d28,d0[0]
730 vld1.64 {q10},[r6,:128]
731 vmlal.u32 q12,d28,d0[1]
732 vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+5]
733 vmlal.u32 q13,d28,d1[0]
734 it ne
735 addne r6,r6,#16 @ don't advance in last iteration
736 vmlal.u32 q6,d28,d1[1]
737 vmlal.u32 q7,d28,d2[0]
738 vmlal.u32 q8,d28,d2[1]
739 vmlal.u32 q9,d28,d3[0]
740 vmlal.u32 q10,d28,d3[1]
741 vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+6]
742 vmlal.u32 q11,d29,d4[0]
743 vmlal.u32 q12,d29,d4[1]
744 vmlal.u32 q13,d29,d5[0]
745 vmlal.u32 q6,d29,d5[1]
746 vmlal.u32 q7,d29,d6[0]
747 vmlal.u32 q8,d29,d6[1]
748 vmlal.u32 q9,d29,d7[0]
749 vmlal.u32 q10,d29,d7[1]
750 vst1.64 {q11},[r7,:128]!
751 vmlal.u32 q12,d28,d0[0]
752 vld1.64 {q11},[r6,:128]
753 vmlal.u32 q13,d28,d0[1]
754 vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+6]
755 vmlal.u32 q6,d28,d1[0]
756 it ne
757 addne r6,r6,#16 @ don't advance in last iteration
758 vmlal.u32 q7,d28,d1[1]
759 vmlal.u32 q8,d28,d2[0]
760 vmlal.u32 q9,d28,d2[1]
761 vmlal.u32 q10,d28,d3[0]
762 vmlal.u32 q11,d28,d3[1]
763 vld1.32 {d28},[r10,:64]! @ pull smashed b[8*i+7]
764 vmlal.u32 q12,d29,d4[0]
765 vmlal.u32 q13,d29,d4[1]
766 vmlal.u32 q6,d29,d5[0]
767 vmlal.u32 q7,d29,d5[1]
768 vmlal.u32 q8,d29,d6[0]
769 vmlal.u32 q9,d29,d6[1]
770 vmlal.u32 q10,d29,d7[0]
771 vmlal.u32 q11,d29,d7[1]
772 vst1.64 {q12},[r7,:128]!
773 vmlal.u32 q13,d28,d0[0]
774 vld1.64 {q12},[r6,:128]
775 vmlal.u32 q6,d28,d0[1]
776 vld1.32 {d29},[r10,:64]! @ pull smashed m[8*i+7]
777 vmlal.u32 q7,d28,d1[0]
778 it ne
779 addne r6,r6,#16 @ don't advance in last iteration
780 vmlal.u32 q8,d28,d1[1]
781 vmlal.u32 q9,d28,d2[0]
782 vmlal.u32 q10,d28,d2[1]
783 vmlal.u32 q11,d28,d3[0]
784 vmlal.u32 q12,d28,d3[1]
785 it eq
786 subeq r1,r1,r5,lsl#2 @ rewind
787 vmlal.u32 q13,d29,d4[0]
788 vld1.32 {d28},[sp,:64] @ pull smashed b[8*i+0]
789 vmlal.u32 q6,d29,d4[1]
790 vld1.32 {d0,d1,d2,d3},[r1]!
791 vmlal.u32 q7,d29,d5[0]
792 add r10,sp,#8 @ rewind
793 vmlal.u32 q8,d29,d5[1]
794 vmlal.u32 q9,d29,d6[0]
795 vmlal.u32 q10,d29,d6[1]
796 vmlal.u32 q11,d29,d7[0]
797 vst1.64 {q13},[r7,:128]!
798 vmlal.u32 q12,d29,d7[1]
799
800 bne LNEON_8n_inner
801 add r6,sp,#128
802 vst1.64 {q6,q7},[r7,:256]!
803 veor q2,q2,q2 @ d4-d5
804 vst1.64 {q8,q9},[r7,:256]!
805 veor q3,q3,q3 @ d6-d7
806 vst1.64 {q10,q11},[r7,:256]!
807 vst1.64 {q12},[r7,:128]
808
809 subs r9,r9,#8
810 vld1.64 {q6,q7},[r6,:256]!
811 vld1.64 {q8,q9},[r6,:256]!
812 vld1.64 {q10,q11},[r6,:256]!
813 vld1.64 {q12,q13},[r6,:256]!
814
815 itt ne
816 subne r3,r3,r5,lsl#2 @ rewind
817 bne LNEON_8n_outer
818
819 add r7,sp,#128
820 vst1.64 {q2,q3}, [sp,:256]! @ start wiping stack frame
821 vshr.u64 d10,d12,#16
822 vst1.64 {q2,q3},[sp,:256]!
823 vadd.u64 d13,d13,d10
824 vst1.64 {q2,q3}, [sp,:256]!
825 vshr.u64 d10,d13,#16
826 vst1.64 {q2,q3}, [sp,:256]!
827 vzip.16 d12,d13
828
829 mov r8,r5
830 b LNEON_tail_entry
831
832.align 4
833LNEON_tail:
834 vadd.u64 d12,d12,d10
835 vshr.u64 d10,d12,#16
836 vld1.64 {q8,q9}, [r6, :256]!
837 vadd.u64 d13,d13,d10
838 vld1.64 {q10,q11}, [r6, :256]!
839 vshr.u64 d10,d13,#16
840 vld1.64 {q12,q13}, [r6, :256]!
841 vzip.16 d12,d13
842
843LNEON_tail_entry:
844 vadd.u64 d14,d14,d10
845 vst1.32 {d12[0]}, [r7, :32]!
846 vshr.u64 d10,d14,#16
847 vadd.u64 d15,d15,d10
848 vshr.u64 d10,d15,#16
849 vzip.16 d14,d15
850 vadd.u64 d16,d16,d10
851 vst1.32 {d14[0]}, [r7, :32]!
852 vshr.u64 d10,d16,#16
853 vadd.u64 d17,d17,d10
854 vshr.u64 d10,d17,#16
855 vzip.16 d16,d17
856 vadd.u64 d18,d18,d10
857 vst1.32 {d16[0]}, [r7, :32]!
858 vshr.u64 d10,d18,#16
859 vadd.u64 d19,d19,d10
860 vshr.u64 d10,d19,#16
861 vzip.16 d18,d19
862 vadd.u64 d20,d20,d10
863 vst1.32 {d18[0]}, [r7, :32]!
864 vshr.u64 d10,d20,#16
865 vadd.u64 d21,d21,d10
866 vshr.u64 d10,d21,#16
867 vzip.16 d20,d21
868 vadd.u64 d22,d22,d10
869 vst1.32 {d20[0]}, [r7, :32]!
870 vshr.u64 d10,d22,#16
871 vadd.u64 d23,d23,d10
872 vshr.u64 d10,d23,#16
873 vzip.16 d22,d23
874 vadd.u64 d24,d24,d10
875 vst1.32 {d22[0]}, [r7, :32]!
876 vshr.u64 d10,d24,#16
877 vadd.u64 d25,d25,d10
878 vshr.u64 d10,d25,#16
879 vzip.16 d24,d25
880 vadd.u64 d26,d26,d10
881 vst1.32 {d24[0]}, [r7, :32]!
882 vshr.u64 d10,d26,#16
883 vadd.u64 d27,d27,d10
884 vshr.u64 d10,d27,#16
885 vzip.16 d26,d27
886 vld1.64 {q6,q7}, [r6, :256]!
887 subs r8,r8,#8
888 vst1.32 {d26[0]}, [r7, :32]!
889 bne LNEON_tail
890
891 vst1.32 {d10[0]}, [r7, :32] @ top-most bit
892 sub r3,r3,r5,lsl#2 @ rewind r3
893 subs r1,sp,#0 @ clear carry flag
894 add r2,sp,r5,lsl#2
895
896LNEON_sub:
897 ldmia r1!, {r4,r5,r6,r7}
898 ldmia r3!, {r8,r9,r10,r11}
899 sbcs r8, r4,r8
900 sbcs r9, r5,r9
901 sbcs r10,r6,r10
902 sbcs r11,r7,r11
903 teq r1,r2 @ preserves carry
904 stmia r0!, {r8,r9,r10,r11}
905 bne LNEON_sub
906
907 ldr r10, [r1] @ load top-most bit
908 mov r11,sp
909 veor q0,q0,q0
910 sub r11,r2,r11 @ this is num*4
911 veor q1,q1,q1
912 mov r1,sp
913 sub r0,r0,r11 @ rewind r0
914 mov r3,r2 @ second 3/4th of frame
915 sbcs r10,r10,#0 @ result is carry flag
916
917LNEON_copy_n_zap:
918 ldmia r1!, {r4,r5,r6,r7}
919 ldmia r0, {r8,r9,r10,r11}
920 it cc
921 movcc r8, r4
922 vst1.64 {q0,q1}, [r3,:256]! @ wipe
923 itt cc
924 movcc r9, r5
925 movcc r10,r6
926 vst1.64 {q0,q1}, [r3,:256]! @ wipe
927 it cc
928 movcc r11,r7
929 ldmia r1, {r4,r5,r6,r7}
930 stmia r0!, {r8,r9,r10,r11}
931 sub r1,r1,#16
932 ldmia r0, {r8,r9,r10,r11}
933 it cc
934 movcc r8, r4
935 vst1.64 {q0,q1}, [r1,:256]! @ wipe
936 itt cc
937 movcc r9, r5
938 movcc r10,r6
939 vst1.64 {q0,q1}, [r3,:256]! @ wipe
940 it cc
941 movcc r11,r7
942 teq r1,r2 @ preserves carry
943 stmia r0!, {r8,r9,r10,r11}
944 bne LNEON_copy_n_zap
945
946 mov sp,ip
947 vldmia sp!,{d8,d9,d10,d11,d12,d13,d14,d15}
948 ldmia sp!,{r4,r5,r6,r7,r8,r9,r10,r11}
949 bx lr @ bx lr
950
951#endif
952.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
953.align 2
954.align 2
955#if __ARM_MAX_ARCH__>=7
956.comm _OPENSSL_armcap_P,4
957.non_lazy_symbol_pointer
958OPENSSL_armcap_P:
959.indirect_symbol _OPENSSL_armcap_P
960.long 0
961.private_extern _OPENSSL_armcap_P
962#endif