1 .ident "sparcv8plus.s, Version 1.4"
2 .ident "SPARC v9 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
5 * ====================================================================
6 * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
9 * Rights for redistribution and usage in source and binary forms are
10 * granted according to the OpenSSL license. Warranty of any kind is
12 * ====================================================================
16 * This is my modest contributon to OpenSSL project (see
17 * http://www.openssl.org/ for more information about it) and is
18 * a drop-in UltraSPARC ISA replacement for crypto/bn/bn_asm.c
19 * module. For updates see http://fy.chalmers.se/~appro/hpe/.
21 * Questions-n-answers.
24 * A. With SC4.x/SC5.x:
26 * cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
30 * gcc -mcpu=ultrasparc -c bn_asm.sparc.v8plus.S -o bn_asm.o
32 * or if above fails (it does if you have gas installed):
34 * gcc -E bn_asm.sparc.v8plus.S | as -xarch=v8plus /dev/fd/0 -o bn_asm.o
36 * Quick-n-dirty way to fuse the module into the library.
37 * Provided that the library is already configured and built
38 * (in 0.9.2 case with no-asm option):
41 * # cp /some/place/bn_asm.sparc.v8plus.S .
42 * # cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
47 * Quick-n-dirty way to get rid of it:
55 * Q. V8plus achitecture? What kind of beast is that?
56 * A. Well, it's rather a programming model than an architecture...
57 * It's actually v9-compliant, i.e. *any* UltraSPARC, CPU under
58 * special conditions, namely when kernel doesn't preserve upper
59 * 32 bits of otherwise 64-bit registers during a context switch.
61 * Q. Why just UltraSPARC? What about SuperSPARC?
62 * A. Original release did target UltraSPARC only. Now SuperSPARC
63 * version is provided along. Both version share bn_*comba[48]
64 * implementations (see comment later in code for explanation).
65 * But what's so special about this UltraSPARC implementation?
66 * Why didn't I let compiler do the job? Trouble is that most of
67 * available compilers (well, SC5.0 is the only exception) don't
68 * attempt to take advantage of UltraSPARC's 64-bitness under
69 * 32-bit kernels even though it's perfectly possible (see next
72 * Q. 64-bit registers under 32-bit kernels? Didn't you just say it
74 * A. You can't adress *all* registers as 64-bit wide:-( The catch is
75 * that you actually may rely upon %o0-%o5 and %g1-%g4 being fully
76 * preserved if you're in a leaf function, i.e. such never calling
77 * any other functions. All functions in this module are leaf and
78 * 10 registers is a handful. And as a matter of fact none-"comba"
79 * routines don't require even that much and I could even afford to
80 * not allocate own stack frame for 'em:-)
82 * Q. What about 64-bit kernels?
83 * A. What about 'em? Just kidding:-) Pure 64-bit version is currently
84 * under evaluation and development...
86 * Q. What about shared libraries?
87 * A. What about 'em? Kidding again:-) Code does *not* contain any
88 * code position dependencies and it's safe to include it into
89 * shared library as is.
91 * Q. How much faster does it go?
92 * A. Do you have a good benchmark? In either case below is what I
93 * experience with crypto/bn/expspeed.c test program:
95 * v8plus module on U10/300MHz against bn_asm.c compiled with:
97 * cc-5.0 -xarch=v8plus -xO5 -xdepend +7-12%
98 * cc-4.2 -xarch=v8plus -xO5 -xdepend +25-35%
99 * egcs-1.1.2 -mcpu=ultrasparc -O3 +35-45%
101 * v8 module on SS10/60MHz against bn_asm.c compiled with:
103 * cc-5.0 -xarch=v8 -xO5 -xdepend +7-10%
104 * cc-4.2 -xarch=v8 -xO5 -xdepend +10%
105 * egcs-1.1.2 -mv8 -O3 +35-45%
107 * As you can see it's damn hard to beat the new Sun C compiler
108 * and it's in first place GNU C users who will appreciate this
109 * assembler implementation:-)
115 * 1.0 - initial release;
116 * 1.1 - new loop unrolling model(*);
117 * - some more fine tuning;
118 * 1.2 - made gas friendly;
119 * - updates to documentation concerning v9;
120 * - new performance comparison matrix;
121 * 1.3 - fixed problem with /usr/ccs/lib/cpp;
122 * 1.4 - native V9 bn_*_comba[48] implementation (15% more efficient)
123 * resulting in slight overall performance kick;
125 * - support for GNU as added;
127 * (*) Originally unrolled loop looked like this:
129 * op(p+0); if (--n==0) break;
130 * op(p+1); if (--n==0) break;
131 * op(p+2); if (--n==0) break;
132 * op(p+3); if (--n==0) break;
135 * I unroll according to following:
137 * op(p+0); op(p+1); op(p+2); op(p+3);
141 * op(p+0); if (--n==0) return;
142 * op(p+2); if (--n==0) return;
147 #ifdef OPENSSL_FIPSCANISTER
148 #include <openssl/fipssyms.h>
151 #if defined(__SUNPRO_C) && defined(__sparcv9)
152 /* They've said -xarch=v9 at command line */
153 .register %g2,#scratch
154 .register %g3,#scratch
155 # define FRAME_SIZE -192
156 #elif defined(__GNUC__) && defined(__arch64__)
157 /* They've said -m64 at command line */
158 .register %g2,#scratch
159 .register %g3,#scratch
160 # define FRAME_SIZE -192
162 # define FRAME_SIZE -96
165 * GNU assembler can't stand stuw:-(
169 .section ".text",#alloc,#execinstr
170 .file "bn_asm.sparc.v8plus.S"
174 .global bn_mul_add_words
176 * BN_ULONG bn_mul_add_words(rp,ap,num,w)
182 sra %o2,%g0,%o2 ! signx %o2
183 brgz,a %o2,.L_bn_mul_add_words_proceed
191 .L_bn_mul_add_words_proceed:
192 srl %o3,%g0,%o3 ! clruw %o3
194 bz,pn %icc,.L_bn_mul_add_words_tail
197 .L_bn_mul_add_words_loop: ! wow! 32 aligned!
233 bnz,a,pt %icc,.L_bn_mul_add_words_loop
236 brnz,a,pn %o2,.L_bn_mul_add_words_tail
238 .L_bn_mul_add_words_return:
242 .L_bn_mul_add_words_tail:
249 brz,pt %o2,.L_bn_mul_add_words_return
259 brz,pt %o2,.L_bn_mul_add_words_return
271 .type bn_mul_add_words,#function
272 .size bn_mul_add_words,(.-bn_mul_add_words)
278 * BN_ULONG bn_mul_words(rp,ap,num,w)
284 sra %o2,%g0,%o2 ! signx %o2
285 brgz,a %o2,.L_bn_mul_words_proceeed
293 .L_bn_mul_words_proceeed:
294 srl %o3,%g0,%o3 ! clruw %o3
296 bz,pn %icc,.L_bn_mul_words_tail
299 .L_bn_mul_words_loop: ! wow! 32 aligned!
327 bnz,a,pt %icc,.L_bn_mul_words_loop
332 brnz,a,pn %o2,.L_bn_mul_words_tail
334 .L_bn_mul_words_return:
338 .L_bn_mul_words_tail:
343 brz,pt %o2,.L_bn_mul_words_return
351 brz,pt %o2,.L_bn_mul_words_return
361 .type bn_mul_words,#function
362 .size bn_mul_words,(.-bn_mul_words)
367 * void bn_sqr_words(r,a,n)
372 sra %o2,%g0,%o2 ! signx %o2
373 brgz,a %o2,.L_bn_sqr_words_proceeed
381 .L_bn_sqr_words_proceeed:
384 bz,pn %icc,.L_bn_sqr_words_tail
387 .L_bn_sqr_words_loop: ! wow! 32 aligned!
415 bnz,a,pt %icc,.L_bn_sqr_words_loop
419 brnz,a,pn %o2,.L_bn_sqr_words_tail
421 .L_bn_sqr_words_return:
425 .L_bn_sqr_words_tail:
430 brz,pt %o2,.L_bn_sqr_words_return
438 brz,pt %o2,.L_bn_sqr_words_return
449 .type bn_sqr_words,#function
450 .size bn_sqr_words,(.-bn_sqr_words)
455 * BN_ULONG bn_div_words(h,l,d)
463 srl %o0,%g0,%o0 ! clruw %o0
465 .type bn_div_words,#function
466 .size bn_div_words,(.-bn_div_words)
472 * BN_ULONG bn_add_words(rp,ap,bp,n)
473 * BN_ULONG *rp,*ap,*bp;
477 sra %o3,%g0,%o3 ! signx %o3
478 brgz,a %o3,.L_bn_add_words_proceed
483 .L_bn_add_words_proceed:
485 bz,pn %icc,.L_bn_add_words_tail
486 addcc %g0,0,%g0 ! clear carry flag
488 .L_bn_add_words_loop: ! wow! 32 aligned!
512 brnz,a,pt %g1,.L_bn_add_words_loop
515 brnz,a,pn %o3,.L_bn_add_words_tail
517 .L_bn_add_words_return:
523 .L_bn_add_words_tail:
527 brz,pt %o3,.L_bn_add_words_return
534 brz,pt %o3,.L_bn_add_words_return
545 .type bn_add_words,#function
546 .size bn_add_words,(.-bn_add_words)
550 * BN_ULONG bn_sub_words(rp,ap,bp,n)
551 * BN_ULONG *rp,*ap,*bp;
555 sra %o3,%g0,%o3 ! signx %o3
556 brgz,a %o3,.L_bn_sub_words_proceed
561 .L_bn_sub_words_proceed:
563 bz,pn %icc,.L_bn_sub_words_tail
564 addcc %g0,0,%g0 ! clear carry flag
566 .L_bn_sub_words_loop: ! wow! 32 aligned!
590 brnz,a,pt %g1,.L_bn_sub_words_loop
593 brnz,a,pn %o3,.L_bn_sub_words_tail
595 .L_bn_sub_words_return:
601 .L_bn_sub_words_tail: ! wow! 32 aligned!
605 brz,pt %o3,.L_bn_sub_words_return
612 brz,pt %o3,.L_bn_sub_words_return
623 .type bn_sub_words,#function
624 .size bn_sub_words,(.-bn_sub_words)
627 * Code below depends on the fact that upper parts of the %l0-%l7
628 * and %i0-%i7 are zeroed by kernel after context switch. In
629 * previous versions this comment stated that "the trouble is that
630 * it's not feasible to implement the mumbo-jumbo in less V9
631 * instructions:-(" which apparently isn't true thanks to
632 * 'bcs,a %xcc,.+8; inc %rd' pair. But the performance improvement
633 * results not from the shorter code, but from elimination of
634 * multicycle none-pairable 'rd %y,%rd' instructions.
640 * Here is register usage map for *all* routines below.
647 #define ap(I) [%i1+4*I]
648 #define bp(I) [%i2+4*I]
649 #define rp(I) [%i0+4*I]
670 .global bn_mul_comba8
672 * void bn_mul_comba8(r,a,b)
676 save %sp,FRAME_SIZE,%sp
682 mulx a_0,b_0,t_1 !mul_add_c(a[0],b[0],c1,c2,c3);
684 stuw t_1,rp(0) !=!r[0]=c1;
687 mulx a_0,b_1,t_1 !mul_add_c(a[0],b[1],c2,c3,c1);
693 mulx a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1);
698 stuw t_1,rp(1) !r[1]=c2;
701 mulx a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2);
702 addcc c_12,t_1,c_12 !=
707 mulx a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2);
712 mulx a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2);
717 stuw t_1,rp(2) !r[2]=c3;
720 mulx a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3);
725 mulx a_1,b_2,t_1 !=!mul_add_c(a[1],b[2],c1,c2,c3);
730 mulx a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3);
731 addcc c_12,t_1,c_12 !=
735 mulx a_3,b_0,t_1 !=!mul_add_c(a[3],b[0],c1,c2,c3);!=
740 stuw t_1,rp(3) !r[3]=c1;
743 mulx a_4,b_0,t_1 !mul_add_c(a[4],b[0],c2,c3,c1);
744 addcc c_12,t_1,c_12 !=
748 mulx a_3,b_1,t_1 !=!mul_add_c(a[3],b[1],c2,c3,c1);
752 mulx a_2,b_2,t_1 !=!mul_add_c(a[2],b[2],c2,c3,c1);
757 mulx a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1);
762 mulx a_0,b_4,t_1 !mul_add_c(a[0],b[4],c2,c3,c1);
767 stuw t_1,rp(4) !r[4]=c2;
770 mulx a_0,b_5,t_1 !mul_add_c(a[0],b[5],c3,c1,c2);
775 mulx a_1,b_4,t_1 !mul_add_c(a[1],b[4],c3,c1,c2);
779 mulx a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2);
783 mulx a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2);
788 mulx a_4,b_1,t_1 !mul_add_c(a[4],b[1],c3,c1,c2);
789 addcc c_12,t_1,c_12 !=
793 mulx a_5,b_0,t_1 !=!mul_add_c(a[5],b[0],c3,c1,c2);
798 stuw t_1,rp(5) !r[5]=c3;
801 mulx a_6,b_0,t_1 !mul_add_c(a[6],b[0],c1,c2,c3);
802 addcc c_12,t_1,c_12 !=
806 mulx a_5,b_1,t_1 !=!mul_add_c(a[5],b[1],c1,c2,c3);
810 mulx a_4,b_2,t_1 !=!mul_add_c(a[4],b[2],c1,c2,c3);
814 mulx a_3,b_3,t_1 !=!mul_add_c(a[3],b[3],c1,c2,c3);
818 mulx a_2,b_4,t_1 !=!mul_add_c(a[2],b[4],c1,c2,c3);
823 mulx a_1,b_5,t_1 !mul_add_c(a[1],b[5],c1,c2,c3);
828 mulx a_0,b_6,t_1 !mul_add_c(a[0],b[6],c1,c2,c3);
833 stuw t_1,rp(6) !r[6]=c1;
836 mulx a_0,b_7,t_1 !mul_add_c(a[0],b[7],c2,c3,c1);
841 mulx a_1,b_6,t_1 !mul_add_c(a[1],b[6],c2,c3,c1);
845 mulx a_2,b_5,t_1 !mul_add_c(a[2],b[5],c2,c3,c1);
849 mulx a_3,b_4,t_1 !mul_add_c(a[3],b[4],c2,c3,c1);
853 mulx a_4,b_3,t_1 !mul_add_c(a[4],b[3],c2,c3,c1);
857 mulx a_5,b_2,t_1 !mul_add_c(a[5],b[2],c2,c3,c1);
862 mulx a_6,b_1,t_1 !=!mul_add_c(a[6],b[1],c2,c3,c1);
866 mulx a_7,b_0,t_1 !=!mul_add_c(a[7],b[0],c2,c3,c1);
871 stuw t_1,rp(7) !r[7]=c2;
874 mulx a_7,b_1,t_1 !=!mul_add_c(a[7],b[1],c3,c1,c2);
879 mulx a_6,b_2,t_1 !mul_add_c(a[6],b[2],c3,c1,c2);
883 mulx a_5,b_3,t_1 !mul_add_c(a[5],b[3],c3,c1,c2);
887 mulx a_4,b_4,t_1 !mul_add_c(a[4],b[4],c3,c1,c2);
891 mulx a_3,b_5,t_1 !mul_add_c(a[3],b[5],c3,c1,c2);
895 mulx a_2,b_6,t_1 !mul_add_c(a[2],b[6],c3,c1,c2);
899 mulx a_1,b_7,t_1 !mul_add_c(a[1],b[7],c3,c1,c2);
904 stuw t_1,rp(8) !r[8]=c3;
907 mulx a_2,b_7,t_1 !=!mul_add_c(a[2],b[7],c1,c2,c3);
912 mulx a_3,b_6,t_1 !mul_add_c(a[3],b[6],c1,c2,c3);
916 mulx a_4,b_5,t_1 !mul_add_c(a[4],b[5],c1,c2,c3);
920 mulx a_5,b_4,t_1 !mul_add_c(a[5],b[4],c1,c2,c3);
924 mulx a_6,b_3,t_1 !mul_add_c(a[6],b[3],c1,c2,c3);
928 mulx a_7,b_2,t_1 !mul_add_c(a[7],b[2],c1,c2,c3);
933 stuw t_1,rp(9) !r[9]=c1;
936 mulx a_7,b_3,t_1 !mul_add_c(a[7],b[3],c2,c3,c1);
941 mulx a_6,b_4,t_1 !mul_add_c(a[6],b[4],c2,c3,c1);
945 mulx a_5,b_5,t_1 !mul_add_c(a[5],b[5],c2,c3,c1);
949 mulx a_4,b_6,t_1 !mul_add_c(a[4],b[6],c2,c3,c1);
953 mulx a_3,b_7,t_1 !mul_add_c(a[3],b[7],c2,c3,c1);
958 stuw t_1,rp(10) !r[10]=c2;
961 mulx a_4,b_7,t_1 !mul_add_c(a[4],b[7],c3,c1,c2);
966 mulx a_5,b_6,t_1 !mul_add_c(a[5],b[6],c3,c1,c2);
970 mulx a_6,b_5,t_1 !mul_add_c(a[6],b[5],c3,c1,c2);
974 mulx a_7,b_4,t_1 !mul_add_c(a[7],b[4],c3,c1,c2);
979 stuw t_1,rp(11) !r[11]=c3;
982 mulx a_7,b_5,t_1 !mul_add_c(a[7],b[5],c1,c2,c3);
987 mulx a_6,b_6,t_1 !mul_add_c(a[6],b[6],c1,c2,c3);
991 mulx a_5,b_7,t_1 !mul_add_c(a[5],b[7],c1,c2,c3);
996 stuw t_1,rp(12) !r[12]=c1;
999 mulx a_6,b_7,t_1 !mul_add_c(a[6],b[7],c2,c3,c1);
1004 mulx a_7,b_6,t_1 !mul_add_c(a[7],b[6],c2,c3,c1);
1009 st t_1,rp(13) !r[13]=c2;
1012 mulx a_7,b_7,t_1 !mul_add_c(a[7],b[7],c3,c1,c2);
1015 stuw t_1,rp(14) !r[14]=c3;
1016 stuw c_12,rp(15) !r[15]=c1;
1019 restore %g0,%g0,%o0 !=
1021 .type bn_mul_comba8,#function
1022 .size bn_mul_comba8,(.-bn_mul_comba8)
1026 .global bn_mul_comba4
1028 * void bn_mul_comba4(r,a,b)
1029 * BN_ULONG *r,*a,*b;
1032 save %sp,FRAME_SIZE,%sp
1038 mulx a_0,b_0,t_1 !mul_add_c(a[0],b[0],c1,c2,c3);
1040 stuw t_1,rp(0) !=!r[0]=c1;
1043 mulx a_0,b_1,t_1 !mul_add_c(a[0],b[1],c2,c3,c1);
1049 mulx a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1);
1054 stuw t_1,rp(1) !r[1]=c2;
1057 mulx a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2);
1058 addcc c_12,t_1,c_12 !=
1063 mulx a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2);
1068 mulx a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2);
1073 stuw t_1,rp(2) !r[2]=c3;
1076 mulx a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3);
1081 mulx a_1,b_2,t_1 !mul_add_c(a[1],b[2],c1,c2,c3);
1086 mulx a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3);
1087 addcc c_12,t_1,c_12 !=
1090 mulx a_3,b_0,t_1 !mul_add_c(a[3],b[0],c1,c2,c3);!=
1091 addcc c_12,t_1,t_1 !=
1095 stuw t_1,rp(3) !=!r[3]=c1;
1098 mulx a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1);
1103 mulx a_2,b_2,t_1 !mul_add_c(a[2],b[2],c2,c3,c1);
1104 addcc c_12,t_1,c_12 !=
1107 mulx a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1);
1108 addcc c_12,t_1,t_1 !=
1112 stuw t_1,rp(4) !=!r[4]=c2;
1115 mulx a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2);
1120 mulx a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2);
1121 addcc c_12,t_1,t_1 !=
1125 stuw t_1,rp(5) !=!r[5]=c3;
1128 mulx a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3);
1131 stuw t_1,rp(6) !r[6]=c1;
1132 stuw c_12,rp(7) !r[7]=c2;
1137 .type bn_mul_comba4,#function
1138 .size bn_mul_comba4,(.-bn_mul_comba4)
1142 .global bn_sqr_comba8
1144 save %sp,FRAME_SIZE,%sp
1149 mulx a_0,a_0,t_1 !sqr_add_c(a,0,c1,c2,c3);
1151 stuw t_1,rp(0) !r[0]=c1;
1154 mulx a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1);
1163 stuw t_1,rp(1) !r[1]=c2;
1166 mulx a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2);
1175 mulx a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2);
1180 stuw t_1,rp(2) !r[2]=c3;
1183 mulx a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3);
1192 mulx a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3);
1200 st t_1,rp(3) !r[3]=c1;
1203 mulx a_4,a_0,t_1 !sqr_add_c2(a,4,0,c2,c3,c1);
1211 mulx a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1);
1219 mulx a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1);
1224 stuw t_1,rp(4) !r[4]=c2;
1227 mulx a_0,a_5,t_1 !sqr_add_c2(a,5,0,c3,c1,c2);
1235 mulx a_1,a_4,t_1 !sqr_add_c2(a,4,1,c3,c1,c2);
1243 mulx a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2);
1251 stuw t_1,rp(5) !r[5]=c3;
1254 mulx a_6,a_0,t_1 !sqr_add_c2(a,6,0,c1,c2,c3);
1262 mulx a_5,a_1,t_1 !sqr_add_c2(a,5,1,c1,c2,c3);
1269 mulx a_4,a_2,t_1 !sqr_add_c2(a,4,2,c1,c2,c3);
1277 mulx a_3,a_3,t_1 !=!sqr_add_c(a,3,c1,c2,c3);
1282 stuw t_1,rp(6) !r[6]=c1;
1285 mulx a_0,a_7,t_1 !sqr_add_c2(a,7,0,c2,c3,c1);
1293 mulx a_1,a_6,t_1 !sqr_add_c2(a,6,1,c2,c3,c1);
1300 mulx a_2,a_5,t_1 !sqr_add_c2(a,5,2,c2,c3,c1);
1307 mulx a_3,a_4,t_1 !sqr_add_c2(a,4,3,c2,c3,c1);
1315 stuw t_1,rp(7) !r[7]=c2;
1318 mulx a_7,a_1,t_1 !sqr_add_c2(a,7,1,c3,c1,c2);
1326 mulx a_6,a_2,t_1 !sqr_add_c2(a,6,2,c3,c1,c2);
1333 mulx a_5,a_3,t_1 !sqr_add_c2(a,5,3,c3,c1,c2);
1340 mulx a_4,a_4,t_1 !sqr_add_c(a,4,c3,c1,c2);
1345 stuw t_1,rp(8) !r[8]=c3;
1348 mulx a_2,a_7,t_1 !sqr_add_c2(a,7,2,c1,c2,c3);
1356 mulx a_3,a_6,t_1 !sqr_add_c2(a,6,3,c1,c2,c3);
1363 mulx a_4,a_5,t_1 !sqr_add_c2(a,5,4,c1,c2,c3);
1371 stuw t_1,rp(9) !r[9]=c1;
1374 mulx a_7,a_3,t_1 !sqr_add_c2(a,7,3,c2,c3,c1);
1382 mulx a_6,a_4,t_1 !sqr_add_c2(a,6,4,c2,c3,c1);
1389 mulx a_5,a_5,t_1 !sqr_add_c(a,5,c2,c3,c1);
1394 stuw t_1,rp(10) !r[10]=c2;
1397 mulx a_4,a_7,t_1 !sqr_add_c2(a,7,4,c3,c1,c2);
1405 mulx a_5,a_6,t_1 !sqr_add_c2(a,6,5,c3,c1,c2);
1413 stuw t_1,rp(11) !r[11]=c3;
1416 mulx a_7,a_5,t_1 !sqr_add_c2(a,7,5,c1,c2,c3);
1424 mulx a_6,a_6,t_1 !sqr_add_c(a,6,c1,c2,c3);
1429 stuw t_1,rp(12) !r[12]=c1;
1432 mulx a_6,a_7,t_1 !sqr_add_c2(a,7,6,c2,c3,c1);
1441 stuw t_1,rp(13) !r[13]=c2;
1444 mulx a_7,a_7,t_1 !sqr_add_c(a,7,c3,c1,c2);
1447 stuw t_1,rp(14) !r[14]=c3;
1448 stuw c_12,rp(15) !r[15]=c1;
1453 .type bn_sqr_comba8,#function
1454 .size bn_sqr_comba8,(.-bn_sqr_comba8)
1458 .global bn_sqr_comba4
1460 * void bn_sqr_comba4(r,a)
1464 save %sp,FRAME_SIZE,%sp
1469 mulx a_0,a_0,t_1 !sqr_add_c(a,0,c1,c2,c3);
1471 stuw t_1,rp(0) !r[0]=c1;
1474 mulx a_0,a_1,t_1 !sqr_add_c2(a,1,0,c2,c3,c1);
1483 stuw t_1,rp(1) !r[1]=c2;
1486 mulx a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2);
1495 mulx a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2);
1500 stuw t_1,rp(2) !r[2]=c3;
1503 mulx a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3);
1511 mulx a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3);
1519 stuw t_1,rp(3) !r[3]=c1;
1522 mulx a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1);
1530 mulx a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1);
1535 stuw t_1,rp(4) !r[4]=c2;
1538 mulx a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2);
1547 stuw t_1,rp(5) !r[5]=c3;
1550 mulx a_3,a_3,t_1 !sqr_add_c(a,3,c1,c2,c3);
1553 stuw t_1,rp(6) !r[6]=c1;
1554 stuw c_12,rp(7) !r[7]=c2;
1559 .type bn_sqr_comba4,#function
1560 .size bn_sqr_comba4,(.-bn_sqr_comba4)