summaryrefslogtreecommitdiff
path: root/src/lib/libssl/src/crypto/bn/asm/ia64.S
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libssl/src/crypto/bn/asm/ia64.S')
-rw-r--r--src/lib/libssl/src/crypto/bn/asm/ia64.S235
1 files changed, 171 insertions, 64 deletions
diff --git a/src/lib/libssl/src/crypto/bn/asm/ia64.S b/src/lib/libssl/src/crypto/bn/asm/ia64.S
index ae56066310..7dfda85566 100644
--- a/src/lib/libssl/src/crypto/bn/asm/ia64.S
+++ b/src/lib/libssl/src/crypto/bn/asm/ia64.S
@@ -1,6 +1,6 @@
1.explicit 1.explicit
2.text 2.text
3.ident "ia64.S, Version 1.1" 3.ident "ia64.S, Version 2.0"
4.ident "IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>" 4.ident "IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
5 5
6// 6//
@@ -13,6 +13,35 @@
13// disclaimed. 13// disclaimed.
14// ==================================================================== 14// ====================================================================
15// 15//
16// Version 2.x is Itanium2 re-tune. Few words about how Itanum2 is
17// different from Itanium to this module viewpoint. Most notably, is it
18// "wider" than Itanium? Can you experience loop scalability as
19// discussed in commentary sections? Not really:-( Itanium2 has 6
20// integer ALU ports, i.e. it's 2 ports wider, but it's not enough to
21// spin twice as fast, as I need 8 IALU ports. Amount of floating point
22// ports is the same, i.e. 2, while I need 4. In other words, to this
23// module Itanium2 remains effectively as "wide" as Itanium. Yet it's
24// essentially different in respect to this module, and a re-tune was
25// required. Well, because some intruction latencies has changed. Most
26// noticeably those intensively used:
27//
28// Itanium Itanium2
29// ldf8 9 6 L2 hit
30// ld8 2 1 L1 hit
31// getf 2 5
32// xma[->getf] 7[+1] 4[+0]
33// add[->st8] 1[+1] 1[+0]
34//
35// What does it mean? You might ratiocinate that the original code
36// should run just faster... Because sum of latencies is smaller...
37// Wrong! Note that getf latency increased. This means that if a loop is
38// scheduled for lower latency (and they are), then it will suffer from
39// stall condition and the code will therefore turn anti-scalable, e.g.
40// original bn_mul_words spun at 5*n or 2.5 times slower than expected
41// on Itanium2! What to do? Reschedule loops for Itanium2? But then
42// Itanium would exhibit anti-scalability. So I've chosen to reschedule
43// for worst latency for every instruction aiming for best *all-round*
44// performance.
16 45
17// Q. How much faster does it get? 46// Q. How much faster does it get?
18// A. Here is the output from 'openssl speed rsa dsa' for vanilla 47// A. Here is the output from 'openssl speed rsa dsa' for vanilla
@@ -149,12 +178,27 @@ bn_add_words:
149 brp.loop.imp .L_bn_add_words_ctop,.L_bn_add_words_cend-16 178 brp.loop.imp .L_bn_add_words_ctop,.L_bn_add_words_cend-16
150 } 179 }
151 .body 180 .body
152{ .mib; mov r14=r32 // rp 181{ .mib;
182#if defined(_HPUX_SOURCE) && defined(_ILP32)
183 addp4 r14=0,r32 // rp
184#else
185 mov r14=r32 // rp
186#endif
153 mov r9=pr };; 187 mov r9=pr };;
154{ .mii; mov r15=r33 // ap 188{ .mii;
189#if defined(_HPUX_SOURCE) && defined(_ILP32)
190 addp4 r15=0,r33 // ap
191#else
192 mov r15=r33 // ap
193#endif
155 mov ar.lc=r10 194 mov ar.lc=r10
156 mov ar.ec=6 } 195 mov ar.ec=6 }
157{ .mib; mov r16=r34 // bp 196{ .mib;
197#if defined(_HPUX_SOURCE) && defined(_ILP32)
198 addp4 r16=0,r34 // bp
199#else
200 mov r16=r34 // bp
201#endif
158 mov pr.rot=1<<16 };; 202 mov pr.rot=1<<16 };;
159 203
160.L_bn_add_words_ctop: 204.L_bn_add_words_ctop:
@@ -174,7 +218,7 @@ bn_add_words:
174 218
175{ .mii; 219{ .mii;
176(p59) add r8=1,r8 // return value 220(p59) add r8=1,r8 // return value
177 mov pr=r9,-1 221 mov pr=r9,0x1ffff
178 mov ar.lc=r3 } 222 mov ar.lc=r3 }
179{ .mbb; nop.b 0x0 223{ .mbb; nop.b 0x0
180 br.ret.sptk.many b0 };; 224 br.ret.sptk.many b0 };;
@@ -202,12 +246,27 @@ bn_sub_words:
202 brp.loop.imp .L_bn_sub_words_ctop,.L_bn_sub_words_cend-16 246 brp.loop.imp .L_bn_sub_words_ctop,.L_bn_sub_words_cend-16
203 } 247 }
204 .body 248 .body
205{ .mib; mov r14=r32 // rp 249{ .mib;
250#if defined(_HPUX_SOURCE) && defined(_ILP32)
251 addp4 r14=0,r32 // rp
252#else
253 mov r14=r32 // rp
254#endif
206 mov r9=pr };; 255 mov r9=pr };;
207{ .mii; mov r15=r33 // ap 256{ .mii;
257#if defined(_HPUX_SOURCE) && defined(_ILP32)
258 addp4 r15=0,r33 // ap
259#else
260 mov r15=r33 // ap
261#endif
208 mov ar.lc=r10 262 mov ar.lc=r10
209 mov ar.ec=6 } 263 mov ar.ec=6 }
210{ .mib; mov r16=r34 // bp 264{ .mib;
265#if defined(_HPUX_SOURCE) && defined(_ILP32)
266 addp4 r16=0,r34 // bp
267#else
268 mov r16=r34 // bp
269#endif
211 mov pr.rot=1<<16 };; 270 mov pr.rot=1<<16 };;
212 271
213.L_bn_sub_words_ctop: 272.L_bn_sub_words_ctop:
@@ -227,7 +286,7 @@ bn_sub_words:
227 286
228{ .mii; 287{ .mii;
229(p59) add r8=1,r8 // return value 288(p59) add r8=1,r8 // return value
230 mov pr=r9,-1 289 mov pr=r9,0x1ffff
231 mov ar.lc=r3 } 290 mov ar.lc=r3 }
232{ .mbb; nop.b 0x0 291{ .mbb; nop.b 0x0
233 br.ret.sptk.many b0 };; 292 br.ret.sptk.many b0 };;
@@ -253,7 +312,7 @@ bn_mul_words:
253#ifdef XMA_TEMPTATION 312#ifdef XMA_TEMPTATION
254{ .mfi; alloc r2=ar.pfs,4,0,0,0 };; 313{ .mfi; alloc r2=ar.pfs,4,0,0,0 };;
255#else 314#else
256{ .mfi; alloc r2=ar.pfs,4,4,0,8 };; 315{ .mfi; alloc r2=ar.pfs,4,12,0,16 };;
257#endif 316#endif
258{ .mib; mov r8=r0 // return value 317{ .mib; mov r8=r0 // return value
259 cmp4.le p6,p0=r34,r0 318 cmp4.le p6,p0=r34,r0
@@ -266,24 +325,30 @@ bn_mul_words:
266 325
267 .body 326 .body
268{ .mib; setf.sig f8=r35 // w 327{ .mib; setf.sig f8=r35 // w
269 mov pr.rot=0x400001<<16 328 mov pr.rot=0x800001<<16
270 // ------^----- serves as (p48) at first (p26) 329 // ------^----- serves as (p50) at first (p27)
271 brp.loop.imp .L_bn_mul_words_ctop,.L_bn_mul_words_cend-16 330 brp.loop.imp .L_bn_mul_words_ctop,.L_bn_mul_words_cend-16
272 } 331 }
273 332
274#ifndef XMA_TEMPTATION 333#ifndef XMA_TEMPTATION
275 334
276{ .mii; mov r14=r32 // rp 335{ .mii;
277 mov r15=r33 // ap 336#if defined(_HPUX_SOURCE) && defined(_ILP32)
337 addp4 r14=0,r32 // rp
338 addp4 r15=0,r33 // ap
339#else
340 mov r14=r32 // rp
341 mov r15=r33 // ap
342#endif
278 mov ar.lc=r10 } 343 mov ar.lc=r10 }
279{ .mii; mov r39=0 // serves as r33 at first (p26) 344{ .mii; mov r40=0 // serves as r35 at first (p27)
280 mov ar.ec=12 };; 345 mov ar.ec=13 };;
281 346
282// This loop spins in 2*(n+11) ticks. It's scheduled for data in L2 347// This loop spins in 2*(n+12) ticks. It's scheduled for data in Itanium
283// cache (i.e. 9 ticks away) as floating point load/store instructions 348// L2 cache (i.e. 9 ticks away) as floating point load/store instructions
284// bypass L1 cache and L2 latency is actually best-case scenario for 349// bypass L1 cache and L2 latency is actually best-case scenario for
285// ldf8. The loop is not scalable and shall run in 2*(n+11) even on 350// ldf8. The loop is not scalable and shall run in 2*(n+12) even on
286// "wider" IA-64 implementations. It's a trade-off here. n+22 loop 351// "wider" IA-64 implementations. It's a trade-off here. n+24 loop
287// would give us ~5% in *overall* performance improvement on "wider" 352// would give us ~5% in *overall* performance improvement on "wider"
288// IA-64, but would hurt Itanium for about same because of longer 353// IA-64, but would hurt Itanium for about same because of longer
289// epilogue. As it's a matter of few percents in either case I've 354// epilogue. As it's a matter of few percents in either case I've
@@ -291,25 +356,25 @@ bn_mul_words:
291// this very instruction sequence in bn_mul_add_words loop which in 356// this very instruction sequence in bn_mul_add_words loop which in
292// turn is scalable). 357// turn is scalable).
293.L_bn_mul_words_ctop: 358.L_bn_mul_words_ctop:
294{ .mfi; (p25) getf.sig r36=f49 // low 359{ .mfi; (p25) getf.sig r36=f52 // low
295 (p21) xmpy.lu f45=f37,f8 360 (p21) xmpy.lu f48=f37,f8
296 (p27) cmp.ltu p52,p48=r39,r38 } 361 (p28) cmp.ltu p54,p50=r41,r39 }
297{ .mfi; (p16) ldf8 f32=[r15],8 362{ .mfi; (p16) ldf8 f32=[r15],8
298 (p21) xmpy.hu f38=f37,f8 363 (p21) xmpy.hu f40=f37,f8
299 (p0) nop.i 0x0 };; 364 (p0) nop.i 0x0 };;
300{ .mii; (p26) getf.sig r32=f43 // high 365{ .mii; (p25) getf.sig r32=f44 // high
301 .pred.rel "mutex",p48,p52 366 .pred.rel "mutex",p50,p54
302 (p48) add r38=r37,r33 // (p26) 367 (p50) add r40=r38,r35 // (p27)
303 (p52) add r38=r37,r33,1 } // (p26) 368 (p54) add r40=r38,r35,1 } // (p27)
304{ .mfb; (p27) st8 [r14]=r39,8 369{ .mfb; (p28) st8 [r14]=r41,8
305 (p0) nop.f 0x0 370 (p0) nop.f 0x0
306 br.ctop.sptk .L_bn_mul_words_ctop };; 371 br.ctop.sptk .L_bn_mul_words_ctop };;
307.L_bn_mul_words_cend: 372.L_bn_mul_words_cend:
308 373
309{ .mii; nop.m 0x0 374{ .mii; nop.m 0x0
310.pred.rel "mutex",p49,p53 375.pred.rel "mutex",p51,p55
311(p49) add r8=r34,r0 376(p51) add r8=r36,r0
312(p53) add r8=r34,r0,1 } 377(p55) add r8=r36,r0,1 }
313{ .mfb; nop.m 0x0 378{ .mfb; nop.m 0x0
314 nop.f 0x0 379 nop.f 0x0
315 nop.b 0x0 } 380 nop.b 0x0 }
@@ -344,7 +409,7 @@ bn_mul_words:
344#endif // XMA_TEMPTATION 409#endif // XMA_TEMPTATION
345 410
346{ .mii; nop.m 0x0 411{ .mii; nop.m 0x0
347 mov pr=r9,-1 412 mov pr=r9,0x1ffff
348 mov ar.lc=r3 } 413 mov ar.lc=r3 }
349{ .mfb; rum 1<<5 // clear um.mfh 414{ .mfb; rum 1<<5 // clear um.mfh
350 nop.f 0x0 415 nop.f 0x0
@@ -376,59 +441,69 @@ bn_mul_add_words:
376 441
377 .body 442 .body
378{ .mib; setf.sig f8=r35 // w 443{ .mib; setf.sig f8=r35 // w
379 mov pr.rot=0x400001<<16 444 mov pr.rot=0x800001<<16
380 // ------^----- serves as (p48) at first (p26) 445 // ------^----- serves as (p50) at first (p27)
381 brp.loop.imp .L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16 446 brp.loop.imp .L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16
382 } 447 }
383{ .mii; mov r14=r32 // rp 448{ .mii;
384 mov r15=r33 // ap 449#if defined(_HPUX_SOURCE) && defined(_ILP32)
450 addp4 r14=0,r32 // rp
451 addp4 r15=0,r33 // ap
452#else
453 mov r14=r32 // rp
454 mov r15=r33 // ap
455#endif
385 mov ar.lc=r10 } 456 mov ar.lc=r10 }
386{ .mii; mov r39=0 // serves as r33 at first (p26) 457{ .mii; mov r40=0 // serves as r35 at first (p27)
387 mov r18=r32 // rp copy 458#if defined(_HPUX_SOURCE) && defined(_ILP32)
388 mov ar.ec=14 };; 459 addp4 r18=0,r32 // rp copy
460#else
461 mov r18=r32 // rp copy
462#endif
463 mov ar.ec=15 };;
389 464
390// This loop spins in 3*(n+13) ticks on Itanium and should spin in 465// This loop spins in 3*(n+14) ticks on Itanium and should spin in
391// 2*(n+13) on "wider" IA-64 implementations (to be verified with new 466// 2*(n+14) on "wider" IA-64 implementations (to be verified with new
392// µ-architecture manuals as they become available). As usual it's 467// µ-architecture manuals as they become available). As usual it's
393// possible to compress the epilogue, down to 10 in this case, at the 468// possible to compress the epilogue, down to 10 in this case, at the
394// cost of scalability. Compressed (and therefore non-scalable) loop 469// cost of scalability. Compressed (and therefore non-scalable) loop
395// running at 3*(n+10) would buy you ~10% on Itanium but take ~35% 470// running at 3*(n+11) would buy you ~10% on Itanium but take ~35%
396// from "wider" IA-64 so let it be scalable! Special attention was 471// from "wider" IA-64 so let it be scalable! Special attention was
397// paid for having the loop body split at 64-byte boundary. ld8 is 472// paid for having the loop body split at 64-byte boundary. ld8 is
398// scheduled for L1 cache as the data is more than likely there. 473// scheduled for L1 cache as the data is more than likely there.
399// Indeed, bn_mul_words has put it there a moment ago:-) 474// Indeed, bn_mul_words has put it there a moment ago:-)
400.L_bn_mul_add_words_ctop: 475.L_bn_mul_add_words_ctop:
401{ .mfi; (p25) getf.sig r36=f49 // low 476{ .mfi; (p25) getf.sig r36=f52 // low
402 (p21) xmpy.lu f45=f37,f8 477 (p21) xmpy.lu f48=f37,f8
403 (p27) cmp.ltu p52,p48=r39,r38 } 478 (p28) cmp.ltu p54,p50=r41,r39 }
404{ .mfi; (p16) ldf8 f32=[r15],8 479{ .mfi; (p16) ldf8 f32=[r15],8
405 (p21) xmpy.hu f38=f37,f8 480 (p21) xmpy.hu f40=f37,f8
406 (p27) add r43=r43,r39 };; 481 (p28) add r45=r45,r41 };;
407{ .mii; (p26) getf.sig r32=f43 // high 482{ .mii; (p25) getf.sig r32=f44 // high
408 .pred.rel "mutex",p48,p52 483 .pred.rel "mutex",p50,p54
409 (p48) add r38=r37,r33 // (p26) 484 (p50) add r40=r38,r35 // (p27)
410 (p52) add r38=r37,r33,1 } // (p26) 485 (p54) add r40=r38,r35,1 } // (p27)
411{ .mfb; (p27) cmp.ltu.unc p56,p0=r43,r39 486{ .mfb; (p28) cmp.ltu.unc p60,p0=r45,r41
412 (p0) nop.f 0x0 487 (p0) nop.f 0x0
413 (p0) nop.b 0x0 } 488 (p0) nop.b 0x0 }
414{ .mii; (p26) ld8 r42=[r18],8 489{ .mii; (p27) ld8 r44=[r18],8
415 (p58) cmp.eq.or p57,p0=-1,r44 490 (p62) cmp.eq.or p61,p0=-1,r46
416 (p58) add r44=1,r44 } 491 (p62) add r46=1,r46 }
417{ .mfb; (p29) st8 [r14]=r45,8 492{ .mfb; (p30) st8 [r14]=r47,8
418 (p0) nop.f 0x0 493 (p0) nop.f 0x0
419 br.ctop.sptk .L_bn_mul_add_words_ctop};; 494 br.ctop.sptk .L_bn_mul_add_words_ctop};;
420.L_bn_mul_add_words_cend: 495.L_bn_mul_add_words_cend:
421 496
422{ .mii; nop.m 0x0 497{ .mii; nop.m 0x0
423.pred.rel "mutex",p51,p55 498.pred.rel "mutex",p53,p57
424(p51) add r8=r36,r0 499(p53) add r8=r38,r0
425(p55) add r8=r36,r0,1 } 500(p57) add r8=r38,r0,1 }
426{ .mfb; nop.m 0x0 501{ .mfb; nop.m 0x0
427 nop.f 0x0 502 nop.f 0x0
428 nop.b 0x0 };; 503 nop.b 0x0 };;
429{ .mii; 504{ .mii;
430(p59) add r8=1,r8 505(p63) add r8=1,r8
431 mov pr=r9,-1 506 mov pr=r9,0x1ffff
432 mov ar.lc=r3 } 507 mov ar.lc=r3 }
433{ .mfb; rum 1<<5 // clear um.mfh 508{ .mfb; rum 1<<5 // clear um.mfh
434 nop.f 0x0 509 nop.f 0x0
@@ -461,6 +536,10 @@ bn_sqr_words:
461 mov r9=pr };; 536 mov r9=pr };;
462 537
463 .body 538 .body
539#if defined(_HPUX_SOURCE) && defined(_ILP32)
540{ .mii; addp4 r32=0,r32
541 addp4 r33=0,r33 };;
542#endif
464{ .mib; 543{ .mib;
465 mov pr.rot=1<<16 544 mov pr.rot=1<<16
466 brp.loop.imp .L_bn_sqr_words_ctop,.L_bn_sqr_words_cend-16 545 brp.loop.imp .L_bn_sqr_words_ctop,.L_bn_sqr_words_cend-16
@@ -492,7 +571,7 @@ bn_sqr_words:
492.L_bn_sqr_words_cend: 571.L_bn_sqr_words_cend:
493 572
494{ .mii; nop.m 0x0 573{ .mii; nop.m 0x0
495 mov pr=r9,-1 574 mov pr=r9,0x1ffff
496 mov ar.lc=r3 } 575 mov ar.lc=r3 }
497{ .mfb; rum 1<<5 // clear um.mfh 576{ .mfb; rum 1<<5 // clear um.mfh
498 nop.f 0x0 577 nop.f 0x0
@@ -526,7 +605,14 @@ bn_sqr_comba8:
526 .prologue 605 .prologue
527 .fframe 0 606 .fframe 0
528 .save ar.pfs,r2 607 .save ar.pfs,r2
608#if defined(_HPUX_SOURCE) && defined(_ILP32)
529{ .mii; alloc r2=ar.pfs,2,1,0,0 609{ .mii; alloc r2=ar.pfs,2,1,0,0
610 addp4 r33=0,r33
611 addp4 r32=0,r32 };;
612{ .mii;
613#else
614{ .mii; alloc r2=ar.pfs,2,1,0,0
615#endif
530 mov r34=r33 616 mov r34=r33
531 add r14=8,r33 };; 617 add r14=8,r33 };;
532 .body 618 .body
@@ -587,7 +673,14 @@ bn_mul_comba8:
587 .prologue 673 .prologue
588 .fframe 0 674 .fframe 0
589 .save ar.pfs,r2 675 .save ar.pfs,r2
676#if defined(_HPUX_SOURCE) && defined(_ILP32)
590{ .mii; alloc r2=ar.pfs,3,0,0,0 677{ .mii; alloc r2=ar.pfs,3,0,0,0
678 addp4 r33=0,r33
679 addp4 r34=0,r34 };;
680{ .mii; addp4 r32=0,r32
681#else
682{ .mii; alloc r2=ar.pfs,3,0,0,0
683#endif
591 add r14=8,r33 684 add r14=8,r33
592 add r17=8,r34 } 685 add r17=8,r34 }
593 .body 686 .body
@@ -1138,7 +1231,14 @@ bn_sqr_comba4:
1138 .prologue 1231 .prologue
1139 .fframe 0 1232 .fframe 0
1140 .save ar.pfs,r2 1233 .save ar.pfs,r2
1234#if defined(_HPUX_SOURCE) && defined(_ILP32)
1235{ .mii; alloc r2=ar.pfs,2,1,0,0
1236 addp4 r32=0,r32
1237 addp4 r33=0,r33 };;
1238{ .mii;
1239#else
1141{ .mii; alloc r2=ar.pfs,2,1,0,0 1240{ .mii; alloc r2=ar.pfs,2,1,0,0
1241#endif
1142 mov r34=r33 1242 mov r34=r33
1143 add r14=8,r33 };; 1243 add r14=8,r33 };;
1144 .body 1244 .body
@@ -1164,7 +1264,14 @@ bn_mul_comba4:
1164 .prologue 1264 .prologue
1165 .fframe 0 1265 .fframe 0
1166 .save ar.pfs,r2 1266 .save ar.pfs,r2
1267#if defined(_HPUX_SOURCE) && defined(_ILP32)
1268{ .mii; alloc r2=ar.pfs,3,0,0,0
1269 addp4 r33=0,r33
1270 addp4 r34=0,r34 };;
1271{ .mii; addp4 r32=0,r32
1272#else
1167{ .mii; alloc r2=ar.pfs,3,0,0,0 1273{ .mii; alloc r2=ar.pfs,3,0,0,0
1274#endif
1168 add r14=8,r33 1275 add r14=8,r33
1169 add r17=8,r34 } 1276 add r17=8,r34 }
1170 .body 1277 .body
@@ -1464,7 +1571,7 @@ bn_div_words:
1464 or r8=r8,r33 1571 or r8=r8,r33
1465 mov ar.pfs=r2 };; 1572 mov ar.pfs=r2 };;
1466{ .mii; shr.u r9=H,I // remainder if anybody wants it 1573{ .mii; shr.u r9=H,I // remainder if anybody wants it
1467 mov pr=r10,-1 } 1574 mov pr=r10,0x1ffff }
1468{ .mfb; br.ret.sptk.many b0 };; 1575{ .mfb; br.ret.sptk.many b0 };;
1469 1576
1470// Unsigned 64 by 32 (well, by 64 for the moment) bit integer division 1577// Unsigned 64 by 32 (well, by 64 for the moment) bit integer division