-{ .mii mov r39=0 // serves as r33 at first (p26)
- mov r18=r32 // rp copy
- mov ar.ec=14 }
-
-// This loop spins in 3*(n+13) ticks on Itanium and should spin in
-// 2*(n+13) on "wider" IA-64 implementations (to be verified with new
-// µ-architecture manuals as they become available). As usual it's
-// possible to compress the epilogue, down to 10 in this case, at the
-// cost of scalability. Compressed (and therefore non-scalable) loop
-// running at 3*(n+10) would buy you ~10% on Itanium but take ~35%
-// from "wider" IA-64 so let it be scalable! Special attention was
-// paid for having the loop body split at 64-byte boundary. ld8 is
-// scheduled for L1 cache as the data is more than likely there.
-// Indeed, bn_mul_words has put it there a moment ago:-)
-.L_bn_mul_add_words_ctop: ;;
-{ .mfi (p25) getf.sig r36=f49 // low
- (p21) xmpy.lu f45=f37,f8
- (p27) cmp.ltu p52,p48=r39,r38 }
-{ .mfi (p16) ldf8 f32=[r15],8
- (p21) xmpy.hu f38=f37,f8
- (p27) add r43=r43,r39 };;
-{ .mii (p26) getf.sig r32=f43 // high
- (p48) add r38=r37,r33 // (p26)
- (p52) add r38=r37,r33,1 } // (p26)
-{ .mfb (p27) cmp.ltu.unc p56,p0=r43,r39
- (p0) nop.f 0x0
- (p0) nop.b 0x0 }
-{ .mii (p26) ld8 r42=[r18],8
- (p58) cmp.eq.or p57,p0=-1,r44
- (p58) add r44=1,r44 }
-{ .mfb (p29) st8 [r14]=r45,8
- (p0) nop.f 0x0
+{ .mii; ADDP r16=0,r32 // rp copy
+ mov pr.rot=0x2001<<16
+ // ------^----- serves as (p40) at first (p27)
+ mov ar.ec=11 };;
+
+// This loop spins in 3*(n+10) ticks on Itanium and in 2*(n+10) on
+// Itanium 2. Yes, unlike previous versions it scales:-) Previous
+// version was peforming *all* additions in IALU and was starving
+// for those even on Itanium 2. In this version one addition is
+// moved to FPU and is folded with multiplication. This is at cost
+// of propogating the result from previous call to this subroutine
+// to L2 cache... In other words negligible even for shorter keys.
+// *Overall* performance improvement [over previous version] varies
+// from 11 to 22 percent depending on key length.
+.L_bn_mul_add_words_ctop:
+.pred.rel "mutex",p40,p42
+{ .mfi; (p23) getf.sig r36=f45 // low
+ (p20) xma.lu f42=f36,f8,f50 // low
+ (p40) add r39=r39,r35 } // (p27)
+{ .mfi; (p16) ldf8 f32=[r15],8 // *(ap++)
+ (p20) xma.hu f36=f36,f8,f50 // high
+ (p42) add r39=r39,r35,1 };; // (p27)
+{ .mmi; (p24) getf.sig r32=f40 // high
+ (p16) ldf8 f46=[r16],8 // *(rp1++)
+ (p40) cmp.ltu p41,p39=r39,r35 } // (p27)
+{ .mib; (p26) st8 [r14]=r39,8 // *(rp2++)
+ (p42) cmp.leu p41,p39=r39,r35 // (p27)