aboutsummaryrefslogtreecommitdiff
path: root/openssl/trunk/crypto/bn/asm
diff options
context:
space:
mode:
Diffstat (limited to 'openssl/trunk/crypto/bn/asm')
-rw-r--r--openssl/trunk/crypto/bn/asm/README27
-rw-r--r--openssl/trunk/crypto/bn/asm/bn-586.pl675
-rw-r--r--openssl/trunk/crypto/bn/asm/co-586.pl286
-rw-r--r--openssl/trunk/crypto/bn/asm/ia64.S1560
-rw-r--r--openssl/trunk/crypto/bn/asm/mips3.s2201
-rw-r--r--openssl/trunk/crypto/bn/asm/pa-risc2.s1618
-rw-r--r--openssl/trunk/crypto/bn/asm/pa-risc2W.s1605
-rw-r--r--openssl/trunk/crypto/bn/asm/ppc.pl2078
-rw-r--r--openssl/trunk/crypto/bn/asm/sparcv8.S1458
-rw-r--r--openssl/trunk/crypto/bn/asm/sparcv8plus.S1547
-rw-r--r--openssl/trunk/crypto/bn/asm/vms.mar6440
-rw-r--r--openssl/trunk/crypto/bn/asm/x86.pl28
-rw-r--r--openssl/trunk/crypto/bn/asm/x86/add.pl76
-rw-r--r--openssl/trunk/crypto/bn/asm/x86/comba.pl277
-rw-r--r--openssl/trunk/crypto/bn/asm/x86/div.pl15
-rw-r--r--openssl/trunk/crypto/bn/asm/x86/f3
-rw-r--r--openssl/trunk/crypto/bn/asm/x86/mul.pl77
-rw-r--r--openssl/trunk/crypto/bn/asm/x86/mul_add.pl87
-rw-r--r--openssl/trunk/crypto/bn/asm/x86/sqr.pl60
-rw-r--r--openssl/trunk/crypto/bn/asm/x86/sub.pl76
-rw-r--r--openssl/trunk/crypto/bn/asm/x86_64-gcc.c593
21 files changed, 20787 insertions, 0 deletions
diff --git a/openssl/trunk/crypto/bn/asm/README b/openssl/trunk/crypto/bn/asm/README
new file mode 100644
index 00000000..b0f3a68a
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/README
@@ -0,0 +1,27 @@
+<OBSOLETE>
+
+All assember in this directory are just version of the file
+crypto/bn/bn_asm.c.
+
+Quite a few of these files are just the assember output from gcc since on
+quite a few machines they are 2 times faster than the system compiler.
+
+For the x86, I have hand written assember because of the bad job all
+compilers seem to do on it. This normally gives a 2 time speed up in the RSA
+routines.
+
+For the DEC alpha, I also hand wrote the assember (except the division which
+is just the output from the C compiler pasted on the end of the file).
+On the 2 alpha C compilers I had access to, it was not possible to do
+64b x 64b -> 128b calculations (both long and the long long data types
+were 64 bits). So the hand assember gives access to the 128 bit result and
+a 2 times speedup :-).
+
+There are 3 versions of assember for the HP PA-RISC.
+
+pa-risc.s is the origional one which works fine and generated using gcc :-)
+
+pa-risc2W.s and pa-risc2.s are 64 and 32-bit PA-RISC 2.0 implementations
+by Chris Ruemmler from HP (with some help from the HP C compiler).
+
+</OBSOLETE>
diff --git a/openssl/trunk/crypto/bn/asm/bn-586.pl b/openssl/trunk/crypto/bn/asm/bn-586.pl
new file mode 100644
index 00000000..26c2685a
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/bn-586.pl
@@ -0,0 +1,675 @@
+#!/usr/local/bin/perl
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+$sse2=0;
+for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
+
+&external_label("OPENSSL_ia32cap_P") if ($sse2);
+
+&bn_mul_add_words("bn_mul_add_words");
+&bn_mul_words("bn_mul_words");
+&bn_sqr_words("bn_sqr_words");
+&bn_div_words("bn_div_words");
+&bn_add_words("bn_add_words");
+&bn_sub_words("bn_sub_words");
+&bn_sub_part_words("bn_sub_part_words");
+
+&asm_finish();
+
+sub bn_mul_add_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":"");
+
+ &comment("");
+ $Low="eax";
+ $High="edx";
+ $a="ebx";
+ $w="ebp";
+ $r="edi";
+ $c="esi";
+
+ &xor($c,$c); # clear carry
+ &mov($r,&wparam(0)); #
+
+ &mov("ecx",&wparam(2)); #
+ &mov($a,&wparam(1)); #
+
+ &and("ecx",0xfffffff8); # num / 8
+ &mov($w,&wparam(3)); #
+
+ &push("ecx"); # Up the stack for a tmp variable
+
+ &jz(&label("maw_finish"));
+
+ if ($sse2) {
+ &picmeup("eax","OPENSSL_ia32cap_P");
+ &bt(&DWP(0,"eax"),26);
+ &jnc(&label("maw_loop"));
+
+ &movd("mm0",$w); # mm0 = w
+ &pxor("mm1","mm1"); # mm1 = carry_in
+
+ &set_label("maw_sse2_loop",0);
+ &movd("mm3",&DWP(0,$r,"",0)); # mm3 = r[0]
+ &paddq("mm1","mm3"); # mm1 = carry_in + r[0]
+ &movd("mm2",&DWP(0,$a,"",0)); # mm2 = a[0]
+ &pmuludq("mm2","mm0"); # mm2 = w*a[0]
+ &movd("mm4",&DWP(4,$a,"",0)); # mm4 = a[1]
+ &pmuludq("mm4","mm0"); # mm4 = w*a[1]
+ &movd("mm6",&DWP(8,$a,"",0)); # mm6 = a[2]
+ &pmuludq("mm6","mm0"); # mm6 = w*a[2]
+ &movd("mm7",&DWP(12,$a,"",0)); # mm7 = a[3]
+ &pmuludq("mm7","mm0"); # mm7 = w*a[3]
+ &paddq("mm1","mm2"); # mm1 = carry_in + r[0] + w*a[0]
+ &movd("mm3",&DWP(4,$r,"",0)); # mm3 = r[1]
+ &paddq("mm3","mm4"); # mm3 = r[1] + w*a[1]
+ &movd("mm5",&DWP(8,$r,"",0)); # mm5 = r[2]
+ &paddq("mm5","mm6"); # mm5 = r[2] + w*a[2]
+ &movd("mm4",&DWP(12,$r,"",0)); # mm4 = r[3]
+ &paddq("mm7","mm4"); # mm7 = r[3] + w*a[3]
+ &movd(&DWP(0,$r,"",0),"mm1");
+ &movd("mm2",&DWP(16,$a,"",0)); # mm2 = a[4]
+ &pmuludq("mm2","mm0"); # mm2 = w*a[4]
+ &psrlq("mm1",32); # mm1 = carry0
+ &movd("mm4",&DWP(20,$a,"",0)); # mm4 = a[5]
+ &pmuludq("mm4","mm0"); # mm4 = w*a[5]
+ &paddq("mm1","mm3"); # mm1 = carry0 + r[1] + w*a[1]
+ &movd("mm6",&DWP(24,$a,"",0)); # mm6 = a[6]
+ &pmuludq("mm6","mm0"); # mm6 = w*a[6]
+ &movd(&DWP(4,$r,"",0),"mm1");
+ &psrlq("mm1",32); # mm1 = carry1
+ &movd("mm3",&DWP(28,$a,"",0)); # mm3 = a[7]
+ &add($a,32);
+ &pmuludq("mm3","mm0"); # mm3 = w*a[7]
+ &paddq("mm1","mm5"); # mm1 = carry1 + r[2] + w*a[2]
+ &movd("mm5",&DWP(16,$r,"",0)); # mm5 = r[4]
+ &paddq("mm2","mm5"); # mm2 = r[4] + w*a[4]
+ &movd(&DWP(8,$r,"",0),"mm1");
+ &psrlq("mm1",32); # mm1 = carry2
+ &paddq("mm1","mm7"); # mm1 = carry2 + r[3] + w*a[3]
+ &movd("mm5",&DWP(20,$r,"",0)); # mm5 = r[5]
+ &paddq("mm4","mm5"); # mm4 = r[5] + w*a[5]
+ &movd(&DWP(12,$r,"",0),"mm1");
+ &psrlq("mm1",32); # mm1 = carry3
+ &paddq("mm1","mm2"); # mm1 = carry3 + r[4] + w*a[4]
+ &movd("mm5",&DWP(24,$r,"",0)); # mm5 = r[6]
+ &paddq("mm6","mm5"); # mm6 = r[6] + w*a[6]
+ &movd(&DWP(16,$r,"",0),"mm1");
+ &psrlq("mm1",32); # mm1 = carry4
+ &paddq("mm1","mm4"); # mm1 = carry4 + r[5] + w*a[5]
+ &movd("mm5",&DWP(28,$r,"",0)); # mm5 = r[7]
+ &paddq("mm3","mm5"); # mm3 = r[7] + w*a[7]
+ &movd(&DWP(20,$r,"",0),"mm1");
+ &psrlq("mm1",32); # mm1 = carry5
+ &paddq("mm1","mm6"); # mm1 = carry5 + r[6] + w*a[6]
+ &movd(&DWP(24,$r,"",0),"mm1");
+ &psrlq("mm1",32); # mm1 = carry6
+ &paddq("mm1","mm3"); # mm1 = carry6 + r[7] + w*a[7]
+ &movd(&DWP(28,$r,"",0),"mm1");
+ &add($r,32);
+ &psrlq("mm1",32); # mm1 = carry_out
+
+ &sub("ecx",8);
+ &jnz(&label("maw_sse2_loop"));
+
+ &movd($c,"mm1"); # c = carry_out
+ &emms();
+
+ &jmp(&label("maw_finish"));
+ }
+
+ &set_label("maw_loop",0);
+
+ &mov(&swtmp(0),"ecx"); #
+
+ for ($i=0; $i<32; $i+=4)
+ {
+ &comment("Round $i");
+
+ &mov("eax",&DWP($i,$a,"",0)); # *a
+ &mul($w); # *a * w
+ &add("eax",$c); # L(t)+= *r
+ &mov($c,&DWP($i,$r,"",0)); # L(t)+= *r
+ &adc("edx",0); # H(t)+=carry
+ &add("eax",$c); # L(t)+=c
+ &adc("edx",0); # H(t)+=carry
+ &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t);
+ &mov($c,"edx"); # c= H(t);
+ }
+
+ &comment("");
+ &mov("ecx",&swtmp(0)); #
+ &add($a,32);
+ &add($r,32);
+ &sub("ecx",8);
+ &jnz(&label("maw_loop"));
+
+ &set_label("maw_finish",0);
+ &mov("ecx",&wparam(2)); # get num
+ &and("ecx",7);
+ &jnz(&label("maw_finish2")); # helps branch prediction
+ &jmp(&label("maw_end"));
+
+ &set_label("maw_finish2",1);
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov("eax",&DWP($i*4,$a,"",0));# *a
+ &mul($w); # *a * w
+ &add("eax",$c); # L(t)+=c
+ &mov($c,&DWP($i*4,$r,"",0)); # L(t)+= *r
+ &adc("edx",0); # H(t)+=carry
+ &add("eax",$c);
+ &adc("edx",0); # H(t)+=carry
+ &dec("ecx") if ($i != 7-1);
+ &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t);
+ &mov($c,"edx"); # c= H(t);
+ &jz(&label("maw_end")) if ($i != 7-1);
+ }
+ &set_label("maw_end",0);
+ &mov("eax",$c);
+
+ &pop("ecx"); # clear variable from
+
+ &function_end($name);
+ }
+
+sub bn_mul_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $Low="eax";
+ $High="edx";
+ $a="ebx";
+ $w="ecx";
+ $r="edi";
+ $c="esi";
+ $num="ebp";
+
+ &xor($c,$c); # clear carry
+ &mov($r,&wparam(0)); #
+ &mov($a,&wparam(1)); #
+ &mov($num,&wparam(2)); #
+ &mov($w,&wparam(3)); #
+
+ &and($num,0xfffffff8); # num / 8
+ &jz(&label("mw_finish"));
+
+ &set_label("mw_loop",0);
+ for ($i=0; $i<32; $i+=4)
+ {
+ &comment("Round $i");
+
+ &mov("eax",&DWP($i,$a,"",0)); # *a
+ &mul($w); # *a * w
+ &add("eax",$c); # L(t)+=c
+ # XXX
+
+ &adc("edx",0); # H(t)+=carry
+ &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t);
+
+ &mov($c,"edx"); # c= H(t);
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($r,32);
+ &sub($num,8);
+ &jz(&label("mw_finish"));
+ &jmp(&label("mw_loop"));
+
+ &set_label("mw_finish",0);
+ &mov($num,&wparam(2)); # get num
+ &and($num,7);
+ &jnz(&label("mw_finish2"));
+ &jmp(&label("mw_end"));
+
+ &set_label("mw_finish2",1);
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov("eax",&DWP($i*4,$a,"",0));# *a
+ &mul($w); # *a * w
+ &add("eax",$c); # L(t)+=c
+ # XXX
+ &adc("edx",0); # H(t)+=carry
+ &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t);
+ &mov($c,"edx"); # c= H(t);
+ &dec($num) if ($i != 7-1);
+ &jz(&label("mw_end")) if ($i != 7-1);
+ }
+ &set_label("mw_end",0);
+ &mov("eax",$c);
+
+ &function_end($name);
+ }
+
+sub bn_sqr_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $r="esi";
+ $a="edi";
+ $num="ebx";
+
+ &mov($r,&wparam(0)); #
+ &mov($a,&wparam(1)); #
+ &mov($num,&wparam(2)); #
+
+ &and($num,0xfffffff8); # num / 8
+ &jz(&label("sw_finish"));
+
+ &set_label("sw_loop",0);
+ for ($i=0; $i<32; $i+=4)
+ {
+ &comment("Round $i");
+ &mov("eax",&DWP($i,$a,"",0)); # *a
+ # XXX
+ &mul("eax"); # *a * *a
+ &mov(&DWP($i*2,$r,"",0),"eax"); #
+ &mov(&DWP($i*2+4,$r,"",0),"edx");#
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($r,64);
+ &sub($num,8);
+ &jnz(&label("sw_loop"));
+
+ &set_label("sw_finish",0);
+ &mov($num,&wparam(2)); # get num
+ &and($num,7);
+ &jz(&label("sw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov("eax",&DWP($i*4,$a,"",0)); # *a
+ # XXX
+ &mul("eax"); # *a * *a
+ &mov(&DWP($i*8,$r,"",0),"eax"); #
+ &dec($num) if ($i != 7-1);
+ &mov(&DWP($i*8+4,$r,"",0),"edx");
+ &jz(&label("sw_end")) if ($i != 7-1);
+ }
+ &set_label("sw_end",0);
+
+ &function_end($name);
+ }
+
+sub bn_div_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+ &mov("edx",&wparam(0)); #
+ &mov("eax",&wparam(1)); #
+ &mov("ebx",&wparam(2)); #
+ &div("ebx");
+ &function_end($name);
+ }
+
+sub bn_add_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $a="esi";
+ $b="edi";
+ $c="eax";
+ $r="ebx";
+ $tmp1="ecx";
+ $tmp2="edx";
+ $num="ebp";
+
+ &mov($r,&wparam(0)); # get r
+ &mov($a,&wparam(1)); # get a
+ &mov($b,&wparam(2)); # get b
+ &mov($num,&wparam(3)); # get num
+ &xor($c,$c); # clear carry
+ &and($num,0xfffffff8); # num / 8
+
+ &jz(&label("aw_finish"));
+
+ &set_label("aw_loop",0);
+ for ($i=0; $i<8; $i++)
+ {
+ &comment("Round $i");
+
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
+ &add($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &add($tmp1,$tmp2);
+ &adc($c,0);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($b,32);
+ &add($r,32);
+ &sub($num,8);
+ &jnz(&label("aw_loop"));
+
+ &set_label("aw_finish",0);
+ &mov($num,&wparam(3)); # get num
+ &and($num,7);
+ &jz(&label("aw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+ &add($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &add($tmp1,$tmp2);
+ &adc($c,0);
+ &dec($num) if ($i != 6);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ &jz(&label("aw_end")) if ($i != 6);
+ }
+ &set_label("aw_end",0);
+
+# &mov("eax",$c); # $c is "eax"
+
+ &function_end($name);
+ }
+
+sub bn_sub_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $a="esi";
+ $b="edi";
+ $c="eax";
+ $r="ebx";
+ $tmp1="ecx";
+ $tmp2="edx";
+ $num="ebp";
+
+ &mov($r,&wparam(0)); # get r
+ &mov($a,&wparam(1)); # get a
+ &mov($b,&wparam(2)); # get b
+ &mov($num,&wparam(3)); # get num
+ &xor($c,$c); # clear carry
+ &and($num,0xfffffff8); # num / 8
+
+ &jz(&label("aw_finish"));
+
+ &set_label("aw_loop",0);
+ for ($i=0; $i<8; $i++)
+ {
+ &comment("Round $i");
+
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
+ &sub($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &sub($tmp1,$tmp2);
+ &adc($c,0);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($b,32);
+ &add($r,32);
+ &sub($num,8);
+ &jnz(&label("aw_loop"));
+
+ &set_label("aw_finish",0);
+ &mov($num,&wparam(3)); # get num
+ &and($num,7);
+ &jz(&label("aw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+ &sub($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &sub($tmp1,$tmp2);
+ &adc($c,0);
+ &dec($num) if ($i != 6);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ &jz(&label("aw_end")) if ($i != 6);
+ }
+ &set_label("aw_end",0);
+
+# &mov("eax",$c); # $c is "eax"
+
+ &function_end($name);
+ }
+
+sub bn_sub_part_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $a="esi";
+ $b="edi";
+ $c="eax";
+ $r="ebx";
+ $tmp1="ecx";
+ $tmp2="edx";
+ $num="ebp";
+
+ &mov($r,&wparam(0)); # get r
+ &mov($a,&wparam(1)); # get a
+ &mov($b,&wparam(2)); # get b
+ &mov($num,&wparam(3)); # get num
+ &xor($c,$c); # clear carry
+ &and($num,0xfffffff8); # num / 8
+
+ &jz(&label("aw_finish"));
+
+ &set_label("aw_loop",0);
+ for ($i=0; $i<8; $i++)
+ {
+ &comment("Round $i");
+
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
+ &sub($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &sub($tmp1,$tmp2);
+ &adc($c,0);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($b,32);
+ &add($r,32);
+ &sub($num,8);
+ &jnz(&label("aw_loop"));
+
+ &set_label("aw_finish",0);
+ &mov($num,&wparam(3)); # get num
+ &and($num,7);
+ &jz(&label("aw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov($tmp1,&DWP(0,$a,"",0)); # *a
+ &mov($tmp2,&DWP(0,$b,"",0));# *b
+ &sub($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &sub($tmp1,$tmp2);
+ &adc($c,0);
+ &mov(&DWP(0,$r,"",0),$tmp1); # *r
+ &add($a, 4);
+ &add($b, 4);
+ &add($r, 4);
+ &dec($num) if ($i != 6);
+ &jz(&label("aw_end")) if ($i != 6);
+ }
+ &set_label("aw_end",0);
+
+ &cmp(&wparam(4),0);
+ &je(&label("pw_end"));
+
+ &mov($num,&wparam(4)); # get dl
+ &cmp($num,0);
+ &je(&label("pw_end"));
+ &jge(&label("pw_pos"));
+
+ &comment("pw_neg");
+ &mov($tmp2,0);
+ &sub($tmp2,$num);
+ &mov($num,$tmp2);
+ &and($num,0xfffffff8); # num / 8
+ &jz(&label("pw_neg_finish"));
+
+ &set_label("pw_neg_loop",0);
+ for ($i=0; $i<8; $i++)
+ {
+ &comment("dl<0 Round $i");
+
+ &mov($tmp1,0);
+ &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
+ &sub($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &sub($tmp1,$tmp2);
+ &adc($c,0);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ }
+
+ &comment("");
+ &add($b,32);
+ &add($r,32);
+ &sub($num,8);
+ &jnz(&label("pw_neg_loop"));
+
+ &set_label("pw_neg_finish",0);
+ &mov($tmp2,&wparam(4)); # get dl
+ &mov($num,0);
+ &sub($num,$tmp2);
+ &and($num,7);
+ &jz(&label("pw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("dl<0 Tail Round $i");
+ &mov($tmp1,0);
+ &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+ &sub($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &sub($tmp1,$tmp2);
+ &adc($c,0);
+ &dec($num) if ($i != 6);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ &jz(&label("pw_end")) if ($i != 6);
+ }
+
+ &jmp(&label("pw_end"));
+
+ &set_label("pw_pos",0);
+
+ &and($num,0xfffffff8); # num / 8
+ &jz(&label("pw_pos_finish"));
+
+ &set_label("pw_pos_loop",0);
+
+ for ($i=0; $i<8; $i++)
+ {
+ &comment("dl>0 Round $i");
+
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &sub($tmp1,$c);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ &jnc(&label("pw_nc".$i));
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($r,32);
+ &sub($num,8);
+ &jnz(&label("pw_pos_loop"));
+
+ &set_label("pw_pos_finish",0);
+ &mov($num,&wparam(4)); # get dl
+ &and($num,7);
+ &jz(&label("pw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("dl>0 Tail Round $i");
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &sub($tmp1,$c);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ &jnc(&label("pw_tail_nc".$i));
+ &dec($num) if ($i != 6);
+ &jz(&label("pw_end")) if ($i != 6);
+ }
+ &mov($c,1);
+ &jmp(&label("pw_end"));
+
+ &set_label("pw_nc_loop",0);
+ for ($i=0; $i<8; $i++)
+ {
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ &set_label("pw_nc".$i,0);
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($r,32);
+ &sub($num,8);
+ &jnz(&label("pw_nc_loop"));
+
+ &mov($num,&wparam(4)); # get dl
+ &and($num,7);
+ &jz(&label("pw_nc_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ &set_label("pw_tail_nc".$i,0);
+ &dec($num) if ($i != 6);
+ &jz(&label("pw_nc_end")) if ($i != 6);
+ }
+
+ &set_label("pw_nc_end",0);
+ &mov($c,0);
+
+ &set_label("pw_end",0);
+
+# &mov("eax",$c); # $c is "eax"
+
+ &function_end($name);
+ }
+
diff --git a/openssl/trunk/crypto/bn/asm/co-586.pl b/openssl/trunk/crypto/bn/asm/co-586.pl
new file mode 100644
index 00000000..5d962cb9
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/co-586.pl
@@ -0,0 +1,286 @@
+#!/usr/local/bin/perl
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+&asm_init($ARGV[0],$0);
+
+&bn_mul_comba("bn_mul_comba8",8);
+&bn_mul_comba("bn_mul_comba4",4);
+&bn_sqr_comba("bn_sqr_comba8",8);
+&bn_sqr_comba("bn_sqr_comba4",4);
+
+&asm_finish();
+
+sub mul_add_c
+ {
+ local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+ # pos == -1 if eax and edx are pre-loaded, 0 to load from next
+ # words, and 1 if load return value
+
+ &comment("mul a[$ai]*b[$bi]");
+
+ # "eax" and "edx" will always be pre-loaded.
+ # &mov("eax",&DWP($ai*4,$a,"",0)) ;
+ # &mov("edx",&DWP($bi*4,$b,"",0));
+
+ &mul("edx");
+ &add($c0,"eax");
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # laod next a
+ &mov("eax",&wparam(0)) if $pos > 0; # load r[]
+ ###
+ &adc($c1,"edx");
+ &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0; # laod next b
+ &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # laod next b
+ ###
+ &adc($c2,0);
+ # is pos > 1, it means it is the last loop
+ &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[];
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # laod next a
+ }
+
+sub sqr_add_c
+ {
+ local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+ # pos == -1 if eax and edx are pre-loaded, 0 to load from next
+ # words, and 1 if load return value
+
+ &comment("sqr a[$ai]*a[$bi]");
+
+ # "eax" and "edx" will always be pre-loaded.
+ # &mov("eax",&DWP($ai*4,$a,"",0)) ;
+ # &mov("edx",&DWP($bi*4,$b,"",0));
+
+ if ($ai == $bi)
+ { &mul("eax");}
+ else
+ { &mul("edx");}
+ &add($c0,"eax");
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a
+ ###
+ &adc($c1,"edx");
+ &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
+ ###
+ &adc($c2,0);
+ # is pos > 1, it means it is the last loop
+ &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[];
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b
+ }
+
+sub sqr_add_c2
+ {
+ local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+ # pos == -1 if eax and edx are pre-loaded, 0 to load from next
+ # words, and 1 if load return value
+
+ &comment("sqr a[$ai]*a[$bi]");
+
+ # "eax" and "edx" will always be pre-loaded.
+ # &mov("eax",&DWP($ai*4,$a,"",0)) ;
+ # &mov("edx",&DWP($bi*4,$a,"",0));
+
+ if ($ai == $bi)
+ { &mul("eax");}
+ else
+ { &mul("edx");}
+ &add("eax","eax");
+ ###
+ &adc("edx","edx");
+ ###
+ &adc($c2,0);
+ &add($c0,"eax");
+ &adc($c1,"edx");
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b
+ &adc($c2,0);
+ &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[];
+ &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
+ ###
+ }
+
+sub bn_mul_comba
+ {
+ local($name,$num)=@_;
+ local($a,$b,$c0,$c1,$c2);
+ local($i,$as,$ae,$bs,$be,$ai,$bi);
+ local($tot,$end);
+
+ &function_begin_B($name,"");
+
+ $c0="ebx";
+ $c1="ecx";
+ $c2="ebp";
+ $a="esi";
+ $b="edi";
+
+ $as=0;
+ $ae=0;
+ $bs=0;
+ $be=0;
+ $tot=$num+$num-1;
+
+ &push("esi");
+ &mov($a,&wparam(1));
+ &push("edi");
+ &mov($b,&wparam(2));
+ &push("ebp");
+ &push("ebx");
+
+ &xor($c0,$c0);
+ &mov("eax",&DWP(0,$a,"",0)); # load the first word
+ &xor($c1,$c1);
+ &mov("edx",&DWP(0,$b,"",0)); # load the first second
+
+ for ($i=0; $i<$tot; $i++)
+ {
+ $ai=$as;
+ $bi=$bs;
+ $end=$be+1;
+
+ &comment("################## Calculate word $i");
+
+ for ($j=$bs; $j<$end; $j++)
+ {
+ &xor($c2,$c2) if ($j == $bs);
+ if (($j+1) == $end)
+ {
+ $v=1;
+ $v=2 if (($i+1) == $tot);
+ }
+ else
+ { $v=0; }
+ if (($j+1) != $end)
+ {
+ $na=($ai-1);
+ $nb=($bi+1);
+ }
+ else
+ {
+ $na=$as+($i < ($num-1));
+ $nb=$bs+($i >= ($num-1));
+ }
+#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
+ &mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
+ if ($v)
+ {
+ &comment("saved r[$i]");
+ # &mov("eax",&wparam(0));
+ # &mov(&DWP($i*4,"eax","",0),$c0);
+ ($c0,$c1,$c2)=($c1,$c2,$c0);
+ }
+ $ai--;
+ $bi++;
+ }
+ $as++ if ($i < ($num-1));
+ $ae++ if ($i >= ($num-1));
+
+ $bs++ if ($i >= ($num-1));
+ $be++ if ($i < ($num-1));
+ }
+ &comment("save r[$i]");
+ # &mov("eax",&wparam(0));
+ &mov(&DWP($i*4,"eax","",0),$c0);
+
+ &pop("ebx");
+ &pop("ebp");
+ &pop("edi");
+ &pop("esi");
+ &ret();
+ &function_end_B($name);
+ }
+
+sub bn_sqr_comba
+ {
+ local($name,$num)=@_;
+ local($r,$a,$c0,$c1,$c2)=@_;
+ local($i,$as,$ae,$bs,$be,$ai,$bi);
+ local($b,$tot,$end,$half);
+
+ &function_begin_B($name,"");
+
+ $c0="ebx";
+ $c1="ecx";
+ $c2="ebp";
+ $a="esi";
+ $r="edi";
+
+ &push("esi");
+ &push("edi");
+ &push("ebp");
+ &push("ebx");
+ &mov($r,&wparam(0));
+ &mov($a,&wparam(1));
+ &xor($c0,$c0);
+ &xor($c1,$c1);
+ &mov("eax",&DWP(0,$a,"",0)); # load the first word
+
+ $as=0;
+ $ae=0;
+ $bs=0;
+ $be=0;
+ $tot=$num+$num-1;
+
+ for ($i=0; $i<$tot; $i++)
+ {
+ $ai=$as;
+ $bi=$bs;
+ $end=$be+1;
+
+ &comment("############### Calculate word $i");
+ for ($j=$bs; $j<$end; $j++)
+ {
+ &xor($c2,$c2) if ($j == $bs);
+ if (($ai-1) < ($bi+1))
+ {
+ $v=1;
+ $v=2 if ($i+1) == $tot;
+ }
+ else
+ { $v=0; }
+ if (!$v)
+ {
+ $na=$ai-1;
+ $nb=$bi+1;
+ }
+ else
+ {
+ $na=$as+($i < ($num-1));
+ $nb=$bs+($i >= ($num-1));
+ }
+ if ($ai == $bi)
+ {
+ &sqr_add_c($r,$a,$ai,$bi,
+ $c0,$c1,$c2,$v,$i,$na,$nb);
+ }
+ else
+ {
+ &sqr_add_c2($r,$a,$ai,$bi,
+ $c0,$c1,$c2,$v,$i,$na,$nb);
+ }
+ if ($v)
+ {
+ &comment("saved r[$i]");
+ #&mov(&DWP($i*4,$r,"",0),$c0);
+ ($c0,$c1,$c2)=($c1,$c2,$c0);
+ last;
+ }
+ $ai--;
+ $bi++;
+ }
+ $as++ if ($i < ($num-1));
+ $ae++ if ($i >= ($num-1));
+
+ $bs++ if ($i >= ($num-1));
+ $be++ if ($i < ($num-1));
+ }
+ &mov(&DWP($i*4,$r,"",0),$c0);
+ &pop("ebx");
+ &pop("ebp");
+ &pop("edi");
+ &pop("esi");
+ &ret();
+ &function_end_B($name);
+ }
diff --git a/openssl/trunk/crypto/bn/asm/ia64.S b/openssl/trunk/crypto/bn/asm/ia64.S
new file mode 100644
index 00000000..7b82b820
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/ia64.S
@@ -0,0 +1,1560 @@
+.explicit
+.text
+.ident "ia64.S, Version 2.1"
+.ident "IA-64 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+//
+// ====================================================================
+// Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+// project.
+//
+// Rights for redistribution and usage in source and binary forms are
+// granted according to the OpenSSL license. Warranty of any kind is
+// disclaimed.
+// ====================================================================
+//
+// Version 2.x is Itanium2 re-tune. Few words about how Itanum2 is
+// different from Itanium to this module viewpoint. Most notably, is it
+// "wider" than Itanium? Can you experience loop scalability as
+// discussed in commentary sections? Not really:-( Itanium2 has 6
+// integer ALU ports, i.e. it's 2 ports wider, but it's not enough to
+// spin twice as fast, as I need 8 IALU ports. Amount of floating point
+// ports is the same, i.e. 2, while I need 4. In other words, to this
+// module Itanium2 remains effectively as "wide" as Itanium. Yet it's
+// essentially different in respect to this module, and a re-tune was
+// required. Well, because some intruction latencies has changed. Most
+// noticeably those intensively used:
+//
+// Itanium Itanium2
+// ldf8 9 6 L2 hit
+// ld8 2 1 L1 hit
+// getf 2 5
+// xma[->getf] 7[+1] 4[+0]
+// add[->st8] 1[+1] 1[+0]
+//
+// What does it mean? You might ratiocinate that the original code
+// should run just faster... Because sum of latencies is smaller...
+// Wrong! Note that getf latency increased. This means that if a loop is
+// scheduled for lower latency (as they were), then it will suffer from
+// stall condition and the code will therefore turn anti-scalable, e.g.
+// original bn_mul_words spun at 5*n or 2.5 times slower than expected
+// on Itanium2! What to do? Reschedule loops for Itanium2? But then
+// Itanium would exhibit anti-scalability. So I've chosen to reschedule
+// for worst latency for every instruction aiming for best *all-round*
+// performance.
+
+// Q. How much faster does it get?
+// A. Here is the output from 'openssl speed rsa dsa' for vanilla
+// 0.9.6a compiled with gcc version 2.96 20000731 (Red Hat
+// Linux 7.1 2.96-81):
+//
+// sign verify sign/s verify/s
+// rsa 512 bits 0.0036s 0.0003s 275.3 2999.2
+// rsa 1024 bits 0.0203s 0.0011s 49.3 894.1
+// rsa 2048 bits 0.1331s 0.0040s 7.5 250.9
+// rsa 4096 bits 0.9270s 0.0147s 1.1 68.1
+// sign verify sign/s verify/s
+// dsa 512 bits 0.0035s 0.0043s 288.3 234.8
+// dsa 1024 bits 0.0111s 0.0135s 90.0 74.2
+//
+// And here is similar output but for this assembler
+// implementation:-)
+//
+// sign verify sign/s verify/s
+// rsa 512 bits 0.0021s 0.0001s 549.4 9638.5
+// rsa 1024 bits 0.0055s 0.0002s 183.8 4481.1
+// rsa 2048 bits 0.0244s 0.0006s 41.4 1726.3
+// rsa 4096 bits 0.1295s 0.0018s 7.7 561.5
+// sign verify sign/s verify/s
+// dsa 512 bits 0.0012s 0.0013s 891.9 756.6
+// dsa 1024 bits 0.0023s 0.0028s 440.4 376.2
+//
+// Yes, you may argue that it's not fair comparison as it's
+// possible to craft the C implementation with BN_UMULT_HIGH
+// inline assembler macro. But of course! Here is the output
+// with the macro:
+//
+// sign verify sign/s verify/s
+// rsa 512 bits 0.0020s 0.0002s 495.0 6561.0
+// rsa 1024 bits 0.0086s 0.0004s 116.2 2235.7
+// rsa 2048 bits 0.0519s 0.0015s 19.3 667.3
+// rsa 4096 bits 0.3464s 0.0053s 2.9 187.7
+// sign verify sign/s verify/s
+// dsa 512 bits 0.0016s 0.0020s 613.1 510.5
+// dsa 1024 bits 0.0045s 0.0054s 221.0 183.9
+//
+// My code is still way faster, huh:-) And I believe that even
+// higher performance can be achieved. Note that as keys get
+// longer, performance gain is larger. Why? According to the
+// profiler there is another player in the field, namely
+// BN_from_montgomery consuming larger and larger portion of CPU
+// time as keysize decreases. I therefore consider putting effort
+// to assembler implementation of the following routine:
+//
+// void bn_mul_add_mont (BN_ULONG *rp,BN_ULONG *np,int nl,BN_ULONG n0)
+// {
+// int i,j;
+// BN_ULONG v;
+//
+// for (i=0; i<nl; i++)
+// {
+// v=bn_mul_add_words(rp,np,nl,(rp[0]*n0)&BN_MASK2);
+// nrp++;
+// rp++;
+// if (((nrp[-1]+=v)&BN_MASK2) < v)
+// for (j=0; ((++nrp[j])&BN_MASK2) == 0; j++) ;
+// }
+// }
+//
+// It might as well be beneficial to implement even combaX
+// variants, as it appears as it can literally unleash the
+// performance (see comment section to bn_mul_comba8 below).
+//
+// And finally for your reference the output for 0.9.6a compiled
+// with SGIcc version 0.01.0-12 (keep in mind that for the moment
+// of this writing it's not possible to convince SGIcc to use
+// BN_UMULT_HIGH inline assembler macro, yet the code is fast,
+// i.e. for a compiler generated one:-):
+//
+// sign verify sign/s verify/s
+// rsa 512 bits 0.0022s 0.0002s 452.7 5894.3
+// rsa 1024 bits 0.0097s 0.0005s 102.7 2002.9
+// rsa 2048 bits 0.0578s 0.0017s 17.3 600.2
+// rsa 4096 bits 0.3838s 0.0061s 2.6 164.5
+// sign verify sign/s verify/s
+// dsa 512 bits 0.0018s 0.0022s 547.3 459.6
+// dsa 1024 bits 0.0051s 0.0062s 196.6 161.3
+//
+// Oh! Benchmarks were performed on 733MHz Lion-class Itanium
+// system running Redhat Linux 7.1 (very special thanks to Ray
+// McCaffity of Williams Communications for providing an account).
+//
+// Q. What's the heck with 'rum 1<<5' at the end of every function?
+// A. Well, by clearing the "upper FP registers written" bit of the
+// User Mask I want to excuse the kernel from preserving upper
+// (f32-f128) FP register bank over process context switch, thus
+// minimizing bus bandwidth consumption during the switch (i.e.
+// after PKI opration completes and the program is off doing
+// something else like bulk symmetric encryption). Having said
+// this, I also want to point out that it might be good idea
+// to compile the whole toolkit (as well as majority of the
+// programs for that matter) with -mfixed-range=f32-f127 command
+// line option. No, it doesn't prevent the compiler from writing
+// to upper bank, but at least discourages to do so. If you don't
+// like the idea you have the option to compile the module with
+// -Drum=nop.m in command line.
+//
+
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+#define ADDP addp4
+#else
+#define ADDP add
+#endif
+
+#if 1
+//
+// bn_[add|sub]_words routines.
+//
+// Loops are spinning in 2*(n+5) ticks on Itanuim (provided that the
+// data reside in L1 cache, i.e. 2 ticks away). It's possible to
+// compress the epilogue and get down to 2*n+6, but at the cost of
+// scalability (the neat feature of this implementation is that it
+// shall automagically spin in n+5 on "wider" IA-64 implementations:-)
+// I consider that the epilogue is short enough as it is to trade tiny
+// performance loss on Itanium for scalability.
+//
+// BN_ULONG bn_add_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num)
+//
+.global bn_add_words#
+.proc bn_add_words#
+.align 64
+.skip 32 // makes the loop body aligned at 64-byte boundary
+bn_add_words:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+{ .mii; alloc r2=ar.pfs,4,12,0,16
+ cmp4.le p6,p0=r35,r0 };;
+{ .mfb; mov r8=r0 // return value
+(p6) br.ret.spnt.many b0 };;
+
+ .save ar.lc,r3
+{ .mib; sub r10=r35,r0,1
+ mov r3=ar.lc
+ brp.loop.imp .L_bn_add_words_ctop,.L_bn_add_words_cend-16
+ }
+ .body
+{ .mib; ADDP r14=0,r32 // rp
+ mov r9=pr };;
+{ .mii; ADDP r15=0,r33 // ap
+ mov ar.lc=r10
+ mov ar.ec=6 }
+{ .mib; ADDP r16=0,r34 // bp
+ mov pr.rot=1<<16 };;
+
+.L_bn_add_words_ctop:
+{ .mii; (p16) ld8 r32=[r16],8 // b=*(bp++)
+ (p18) add r39=r37,r34
+ (p19) cmp.ltu.unc p56,p0=r40,r38 }
+{ .mfb; (p0) nop.m 0x0
+ (p0) nop.f 0x0
+ (p0) nop.b 0x0 }
+{ .mii; (p16) ld8 r35=[r15],8 // a=*(ap++)
+ (p58) cmp.eq.or p57,p0=-1,r41 // (p20)
+ (p58) add r41=1,r41 } // (p20)
+{ .mfb; (p21) st8 [r14]=r42,8 // *(rp++)=r
+ (p0) nop.f 0x0
+ br.ctop.sptk .L_bn_add_words_ctop };;
+.L_bn_add_words_cend:
+
+{ .mii;
+(p59) add r8=1,r8 // return value
+ mov pr=r9,0x1ffff
+ mov ar.lc=r3 }
+{ .mbb; nop.b 0x0
+ br.ret.sptk.many b0 };;
+.endp bn_add_words#
+
+//
+// BN_ULONG bn_sub_words(BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int num)
+//
+.global bn_sub_words#
+.proc bn_sub_words#
+.align 64
+.skip 32 // makes the loop body aligned at 64-byte boundary
+bn_sub_words:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+{ .mii; alloc r2=ar.pfs,4,12,0,16
+ cmp4.le p6,p0=r35,r0 };;
+{ .mfb; mov r8=r0 // return value
+(p6) br.ret.spnt.many b0 };;
+
+ .save ar.lc,r3
+{ .mib; sub r10=r35,r0,1
+ mov r3=ar.lc
+ brp.loop.imp .L_bn_sub_words_ctop,.L_bn_sub_words_cend-16
+ }
+ .body
+{ .mib; ADDP r14=0,r32 // rp
+ mov r9=pr };;
+{ .mii; ADDP r15=0,r33 // ap
+ mov ar.lc=r10
+ mov ar.ec=6 }
+{ .mib; ADDP r16=0,r34 // bp
+ mov pr.rot=1<<16 };;
+
+.L_bn_sub_words_ctop:
+{ .mii; (p16) ld8 r32=[r16],8 // b=*(bp++)
+ (p18) sub r39=r37,r34
+ (p19) cmp.gtu.unc p56,p0=r40,r38 }
+{ .mfb; (p0) nop.m 0x0
+ (p0) nop.f 0x0
+ (p0) nop.b 0x0 }
+{ .mii; (p16) ld8 r35=[r15],8 // a=*(ap++)
+ (p58) cmp.eq.or p57,p0=0,r41 // (p20)
+ (p58) add r41=-1,r41 } // (p20)
+{ .mbb; (p21) st8 [r14]=r42,8 // *(rp++)=r
+ (p0) nop.b 0x0
+ br.ctop.sptk .L_bn_sub_words_ctop };;
+.L_bn_sub_words_cend:
+
+{ .mii;
+(p59) add r8=1,r8 // return value
+ mov pr=r9,0x1ffff
+ mov ar.lc=r3 }
+{ .mbb; nop.b 0x0
+ br.ret.sptk.many b0 };;
+.endp bn_sub_words#
+#endif
+
+#if 0
+#define XMA_TEMPTATION
+#endif
+
+#if 1
+//
+// BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+//
+.global bn_mul_words#
+.proc bn_mul_words#
+.align 64
+.skip 32 // makes the loop body aligned at 64-byte boundary
+bn_mul_words:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+#ifdef XMA_TEMPTATION
+{ .mfi; alloc r2=ar.pfs,4,0,0,0 };;
+#else
+{ .mfi; alloc r2=ar.pfs,4,12,0,16 };;
+#endif
+{ .mib; mov r8=r0 // return value
+ cmp4.le p6,p0=r34,r0
+(p6) br.ret.spnt.many b0 };;
+
+ .save ar.lc,r3
+{ .mii; sub r10=r34,r0,1
+ mov r3=ar.lc
+ mov r9=pr };;
+
+ .body
+{ .mib; setf.sig f8=r35 // w
+ mov pr.rot=0x800001<<16
+ // ------^----- serves as (p50) at first (p27)
+ brp.loop.imp .L_bn_mul_words_ctop,.L_bn_mul_words_cend-16
+ }
+
+#ifndef XMA_TEMPTATION
+
+{ .mmi; ADDP r14=0,r32 // rp
+ ADDP r15=0,r33 // ap
+ mov ar.lc=r10 }
+{ .mmi; mov r40=0 // serves as r35 at first (p27)
+ mov ar.ec=13 };;
+
+// This loop spins in 2*(n+12) ticks. It's scheduled for data in Itanium
+// L2 cache (i.e. 9 ticks away) as floating point load/store instructions
+// bypass L1 cache and L2 latency is actually best-case scenario for
+// ldf8. The loop is not scalable and shall run in 2*(n+12) even on
+// "wider" IA-64 implementations. It's a trade-off here. n+24 loop
+// would give us ~5% in *overall* performance improvement on "wider"
+// IA-64, but would hurt Itanium for about same because of longer
+// epilogue. As it's a matter of few percents in either case I've
+// chosen to trade the scalability for development time (you can see
+// this very instruction sequence in bn_mul_add_words loop which in
+// turn is scalable).
+.L_bn_mul_words_ctop:
+{ .mfi; (p25) getf.sig r36=f52 // low
+ (p21) xmpy.lu f48=f37,f8
+ (p28) cmp.ltu p54,p50=r41,r39 }
+{ .mfi; (p16) ldf8 f32=[r15],8
+ (p21) xmpy.hu f40=f37,f8
+ (p0) nop.i 0x0 };;
+{ .mii; (p25) getf.sig r32=f44 // high
+ .pred.rel "mutex",p50,p54
+ (p50) add r40=r38,r35 // (p27)
+ (p54) add r40=r38,r35,1 } // (p27)
+{ .mfb; (p28) st8 [r14]=r41,8
+ (p0) nop.f 0x0
+ br.ctop.sptk .L_bn_mul_words_ctop };;
+.L_bn_mul_words_cend:
+
+{ .mii; nop.m 0x0
+.pred.rel "mutex",p51,p55
+(p51) add r8=r36,r0
+(p55) add r8=r36,r0,1 }
+{ .mfb; nop.m 0x0
+ nop.f 0x0
+ nop.b 0x0 }
+
+#else // XMA_TEMPTATION
+
+ setf.sig f37=r0 // serves as carry at (p18) tick
+ mov ar.lc=r10
+ mov ar.ec=5;;
+
+// Most of you examining this code very likely wonder why in the name
+// of Intel the following loop is commented out? Indeed, it looks so
+// neat that you find it hard to believe that it's something wrong
+// with it, right? The catch is that every iteration depends on the
+// result from previous one and the latter isn't available instantly.
+// The loop therefore spins at the latency of xma minus 1, or in other
+// words at 6*(n+4) ticks:-( Compare to the "production" loop above
+// that runs in 2*(n+11) where the low latency problem is worked around
+// by moving the dependency to one-tick latent interger ALU. Note that
+// "distance" between ldf8 and xma is not latency of ldf8, but the
+// *difference* between xma and ldf8 latencies.
+.L_bn_mul_words_ctop:
+{ .mfi; (p16) ldf8 f32=[r33],8
+ (p18) xma.hu f38=f34,f8,f39 }
+{ .mfb; (p20) stf8 [r32]=f37,8
+ (p18) xma.lu f35=f34,f8,f39
+ br.ctop.sptk .L_bn_mul_words_ctop };;
+.L_bn_mul_words_cend:
+
+ getf.sig r8=f41 // the return value
+
+#endif // XMA_TEMPTATION
+
+{ .mii; nop.m 0x0
+ mov pr=r9,0x1ffff
+ mov ar.lc=r3 }
+{ .mfb; rum 1<<5 // clear um.mfh
+ nop.f 0x0
+ br.ret.sptk.many b0 };;
+.endp bn_mul_words#
+#endif
+
+#if 1
+//
+// BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+//
+.global bn_mul_add_words#
+.proc bn_mul_add_words#
+.align 64
+.skip 48 // makes the loop body aligned at 64-byte boundary
+bn_mul_add_words:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+ .save ar.lc,r3
+ .save pr,r9
+{ .mmi; alloc r2=ar.pfs,4,4,0,8
+ cmp4.le p6,p0=r34,r0
+ mov r3=ar.lc };;
+{ .mib; mov r8=r0 // return value
+ sub r10=r34,r0,1
+(p6) br.ret.spnt.many b0 };;
+
+ .body
+{ .mib; setf.sig f8=r35 // w
+ mov r9=pr
+ brp.loop.imp .L_bn_mul_add_words_ctop,.L_bn_mul_add_words_cend-16
+ }
+{ .mmi; ADDP r14=0,r32 // rp
+ ADDP r15=0,r33 // ap
+ mov ar.lc=r10 }
+{ .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)
+ br.ctop.sptk .L_bn_mul_add_words_ctop};;
+.L_bn_mul_add_words_cend:
+
+{ .mmi; .pred.rel "mutex",p40,p42
+(p40) add r8=r35,r0
+(p42) add r8=r35,r0,1
+ mov pr=r9,0x1ffff }
+{ .mib; rum 1<<5 // clear um.mfh
+ mov ar.lc=r3
+ br.ret.sptk.many b0 };;
+.endp bn_mul_add_words#
+#endif
+
+#if 1
+//
+// void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
+//
+.global bn_sqr_words#
+.proc bn_sqr_words#
+.align 64
+.skip 32 // makes the loop body aligned at 64-byte boundary
+bn_sqr_words:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+{ .mii; alloc r2=ar.pfs,3,0,0,0
+ sxt4 r34=r34 };;
+{ .mii; cmp.le p6,p0=r34,r0
+ mov r8=r0 } // return value
+{ .mfb; ADDP r32=0,r32
+ nop.f 0x0
+(p6) br.ret.spnt.many b0 };;
+
+ .save ar.lc,r3
+{ .mii; sub r10=r34,r0,1
+ mov r3=ar.lc
+ mov r9=pr };;
+
+ .body
+{ .mib; ADDP r33=0,r33
+ mov pr.rot=1<<16
+ brp.loop.imp .L_bn_sqr_words_ctop,.L_bn_sqr_words_cend-16
+ }
+{ .mii; add r34=8,r32
+ mov ar.lc=r10
+ mov ar.ec=18 };;
+
+// 2*(n+17) on Itanium, (n+17) on "wider" IA-64 implementations. It's
+// possible to compress the epilogue (I'm getting tired to write this
+// comment over and over) and get down to 2*n+16 at the cost of
+// scalability. The decision will very likely be reconsidered after the
+// benchmark program is profiled. I.e. if perfomance gain on Itanium
+// will appear larger than loss on "wider" IA-64, then the loop should
+// be explicitely split and the epilogue compressed.
+.L_bn_sqr_words_ctop:
+{ .mfi; (p16) ldf8 f32=[r33],8
+ (p25) xmpy.lu f42=f41,f41
+ (p0) nop.i 0x0 }
+{ .mib; (p33) stf8 [r32]=f50,16
+ (p0) nop.i 0x0
+ (p0) nop.b 0x0 }
+{ .mfi; (p0) nop.m 0x0
+ (p25) xmpy.hu f52=f41,f41
+ (p0) nop.i 0x0 }
+{ .mib; (p33) stf8 [r34]=f60,16
+ (p0) nop.i 0x0
+ br.ctop.sptk .L_bn_sqr_words_ctop };;
+.L_bn_sqr_words_cend:
+
+{ .mii; nop.m 0x0
+ mov pr=r9,0x1ffff
+ mov ar.lc=r3 }
+{ .mfb; rum 1<<5 // clear um.mfh
+ nop.f 0x0
+ br.ret.sptk.many b0 };;
+.endp bn_sqr_words#
+#endif
+
+#if 1
+// Apparently we win nothing by implementing special bn_sqr_comba8.
+// Yes, it is possible to reduce the number of multiplications by
+// almost factor of two, but then the amount of additions would
+// increase by factor of two (as we would have to perform those
+// otherwise performed by xma ourselves). Normally we would trade
+// anyway as multiplications are way more expensive, but not this
+// time... Multiplication kernel is fully pipelined and as we drain
+// one 128-bit multiplication result per clock cycle multiplications
+// are effectively as inexpensive as additions. Special implementation
+// might become of interest for "wider" IA-64 implementation as you'll
+// be able to get through the multiplication phase faster (there won't
+// be any stall issues as discussed in the commentary section below and
+// you therefore will be able to employ all 4 FP units)... But these
+// Itanium days it's simply too hard to justify the effort so I just
+// drop down to bn_mul_comba8 code:-)
+//
+// void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+//
+.global bn_sqr_comba8#
+.proc bn_sqr_comba8#
+.align 64
+bn_sqr_comba8:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+{ .mii; alloc r2=ar.pfs,2,1,0,0
+ addp4 r33=0,r33
+ addp4 r32=0,r32 };;
+{ .mii;
+#else
+{ .mii; alloc r2=ar.pfs,2,1,0,0
+#endif
+ mov r34=r33
+ add r14=8,r33 };;
+ .body
+{ .mii; add r17=8,r34
+ add r15=16,r33
+ add r18=16,r34 }
+{ .mfb; add r16=24,r33
+ br .L_cheat_entry_point8 };;
+.endp bn_sqr_comba8#
+#endif
+
+#if 1
+// I've estimated this routine to run in ~120 ticks, but in reality
+// (i.e. according to ar.itc) it takes ~160 ticks. Are those extra
+// cycles consumed for instructions fetch? Or did I misinterpret some
+// clause in Itanium µ-architecture manual? Comments are welcomed and
+// highly appreciated.
+//
+// On Itanium 2 it takes ~190 ticks. This is because of stalls on
+// result from getf.sig. I do nothing about it at this point for
+// reasons depicted below.
+//
+// However! It should be noted that even 160 ticks is darn good result
+// as it's over 10 (yes, ten, spelled as t-e-n) times faster than the
+// C version (compiled with gcc with inline assembler). I really
+// kicked compiler's butt here, didn't I? Yeah! This brings us to the
+// following statement. It's damn shame that this routine isn't called
+// very often nowadays! According to the profiler most CPU time is
+// consumed by bn_mul_add_words called from BN_from_montgomery. In
+// order to estimate what we're missing, I've compared the performance
+// of this routine against "traditional" implementation, i.e. against
+// following routine:
+//
+// void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+// { r[ 8]=bn_mul_words( &(r[0]),a,8,b[0]);
+// r[ 9]=bn_mul_add_words(&(r[1]),a,8,b[1]);
+// r[10]=bn_mul_add_words(&(r[2]),a,8,b[2]);
+// r[11]=bn_mul_add_words(&(r[3]),a,8,b[3]);
+// r[12]=bn_mul_add_words(&(r[4]),a,8,b[4]);
+// r[13]=bn_mul_add_words(&(r[5]),a,8,b[5]);
+// r[14]=bn_mul_add_words(&(r[6]),a,8,b[6]);
+// r[15]=bn_mul_add_words(&(r[7]),a,8,b[7]);
+// }
+//
+// The one below is over 8 times faster than the one above:-( Even
+// more reasons to "combafy" bn_mul_add_mont...
+//
+// And yes, this routine really made me wish there were an optimizing
+// assembler! It also feels like it deserves a dedication.
+//
+// To my wife for being there and to my kids...
+//
+// void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+//
+#define carry1 r14
+#define carry2 r15
+#define carry3 r34
+.global bn_mul_comba8#
+.proc bn_mul_comba8#
+.align 64
+bn_mul_comba8:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+{ .mii; alloc r2=ar.pfs,3,0,0,0
+ addp4 r33=0,r33
+ addp4 r34=0,r34 };;
+{ .mii; addp4 r32=0,r32
+#else
+{ .mii; alloc r2=ar.pfs,3,0,0,0
+#endif
+ add r14=8,r33
+ add r17=8,r34 }
+ .body
+{ .mii; add r15=16,r33
+ add r18=16,r34
+ add r16=24,r33 }
+.L_cheat_entry_point8:
+{ .mmi; add r19=24,r34
+
+ ldf8 f32=[r33],32 };;
+
+{ .mmi; ldf8 f120=[r34],32
+ ldf8 f121=[r17],32 }
+{ .mmi; ldf8 f122=[r18],32
+ ldf8 f123=[r19],32 };;
+{ .mmi; ldf8 f124=[r34]
+ ldf8 f125=[r17] }
+{ .mmi; ldf8 f126=[r18]
+ ldf8 f127=[r19] }
+
+{ .mmi; ldf8 f33=[r14],32
+ ldf8 f34=[r15],32 }
+{ .mmi; ldf8 f35=[r16],32;;
+ ldf8 f36=[r33] }
+{ .mmi; ldf8 f37=[r14]
+ ldf8 f38=[r15] }
+{ .mfi; ldf8 f39=[r16]
+// -------\ Entering multiplier's heaven /-------
+// ------------\ /------------
+// -----------------\ /-----------------
+// ----------------------\/----------------------
+ xma.hu f41=f32,f120,f0 }
+{ .mfi; xma.lu f40=f32,f120,f0 };; // (*)
+{ .mfi; xma.hu f51=f32,f121,f0 }
+{ .mfi; xma.lu f50=f32,f121,f0 };;
+{ .mfi; xma.hu f61=f32,f122,f0 }
+{ .mfi; xma.lu f60=f32,f122,f0 };;
+{ .mfi; xma.hu f71=f32,f123,f0 }
+{ .mfi; xma.lu f70=f32,f123,f0 };;
+{ .mfi; xma.hu f81=f32,f124,f0 }
+{ .mfi; xma.lu f80=f32,f124,f0 };;
+{ .mfi; xma.hu f91=f32,f125,f0 }
+{ .mfi; xma.lu f90=f32,f125,f0 };;
+{ .mfi; xma.hu f101=f32,f126,f0 }
+{ .mfi; xma.lu f100=f32,f126,f0 };;
+{ .mfi; xma.hu f111=f32,f127,f0 }
+{ .mfi; xma.lu f110=f32,f127,f0 };;//
+// (*) You can argue that splitting at every second bundle would
+// prevent "wider" IA-64 implementations from achieving the peak
+// performance. Well, not really... The catch is that if you
+// intend to keep 4 FP units busy by splitting at every fourth
+// bundle and thus perform these 16 multiplications in 4 ticks,
+// the first bundle *below* would stall because the result from
+// the first xma bundle *above* won't be available for another 3
+// ticks (if not more, being an optimist, I assume that "wider"
+// implementation will have same latency:-). This stall will hold
+// you back and the performance would be as if every second bundle
+// were split *anyway*...
+{ .mfi; getf.sig r16=f40
+ xma.hu f42=f33,f120,f41
+ add r33=8,r32 }
+{ .mfi; xma.lu f41=f33,f120,f41 };;
+{ .mfi; getf.sig r24=f50
+ xma.hu f52=f33,f121,f51 }
+{ .mfi; xma.lu f51=f33,f121,f51 };;
+{ .mfi; st8 [r32]=r16,16
+ xma.hu f62=f33,f122,f61 }
+{ .mfi; xma.lu f61=f33,f122,f61 };;
+{ .mfi; xma.hu f72=f33,f123,f71 }
+{ .mfi; xma.lu f71=f33,f123,f71 };;
+{ .mfi; xma.hu f82=f33,f124,f81 }
+{ .mfi; xma.lu f81=f33,f124,f81 };;
+{ .mfi; xma.hu f92=f33,f125,f91 }
+{ .mfi; xma.lu f91=f33,f125,f91 };;
+{ .mfi; xma.hu f102=f33,f126,f101 }
+{ .mfi; xma.lu f101=f33,f126,f101 };;
+{ .mfi; xma.hu f112=f33,f127,f111 }
+{ .mfi; xma.lu f111=f33,f127,f111 };;//
+//-------------------------------------------------//
+{ .mfi; getf.sig r25=f41
+ xma.hu f43=f34,f120,f42 }
+{ .mfi; xma.lu f42=f34,f120,f42 };;
+{ .mfi; getf.sig r16=f60
+ xma.hu f53=f34,f121,f52 }
+{ .mfi; xma.lu f52=f34,f121,f52 };;
+{ .mfi; getf.sig r17=f51
+ xma.hu f63=f34,f122,f62
+ add r25=r25,r24 }
+{ .mfi; xma.lu f62=f34,f122,f62
+ mov carry1=0 };;
+{ .mfi; cmp.ltu p6,p0=r25,r24
+ xma.hu f73=f34,f123,f72 }
+{ .mfi; xma.lu f72=f34,f123,f72 };;
+{ .mfi; st8 [r33]=r25,16
+ xma.hu f83=f34,f124,f82
+(p6) add carry1=1,carry1 }
+{ .mfi; xma.lu f82=f34,f124,f82 };;
+{ .mfi; xma.hu f93=f34,f125,f92 }
+{ .mfi; xma.lu f92=f34,f125,f92 };;
+{ .mfi; xma.hu f103=f34,f126,f102 }
+{ .mfi; xma.lu f102=f34,f126,f102 };;
+{ .mfi; xma.hu f113=f34,f127,f112 }
+{ .mfi; xma.lu f112=f34,f127,f112 };;//
+//-------------------------------------------------//
+{ .mfi; getf.sig r18=f42
+ xma.hu f44=f35,f120,f43
+ add r17=r17,r16 }
+{ .mfi; xma.lu f43=f35,f120,f43 };;
+{ .mfi; getf.sig r24=f70
+ xma.hu f54=f35,f121,f53 }
+{ .mfi; mov carry2=0
+ xma.lu f53=f35,f121,f53 };;
+{ .mfi; getf.sig r25=f61
+ xma.hu f64=f35,f122,f63
+ cmp.ltu p7,p0=r17,r16 }
+{ .mfi; add r18=r18,r17
+ xma.lu f63=f35,f122,f63 };;
+{ .mfi; getf.sig r26=f52
+ xma.hu f74=f35,f123,f73
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r18,r17
+ xma.lu f73=f35,f123,f73
+ add r18=r18,carry1 };;
+{ .mfi;
+ xma.hu f84=f35,f124,f83
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r18,carry1
+ xma.lu f83=f35,f124,f83 };;
+{ .mfi; st8 [r32]=r18,16
+ xma.hu f94=f35,f125,f93
+(p7) add carry2=1,carry2 }
+{ .mfi; xma.lu f93=f35,f125,f93 };;
+{ .mfi; xma.hu f104=f35,f126,f103 }
+{ .mfi; xma.lu f103=f35,f126,f103 };;
+{ .mfi; xma.hu f114=f35,f127,f113 }
+{ .mfi; mov carry1=0
+ xma.lu f113=f35,f127,f113
+ add r25=r25,r24 };;//
+//-------------------------------------------------//
+{ .mfi; getf.sig r27=f43
+ xma.hu f45=f36,f120,f44
+ cmp.ltu p6,p0=r25,r24 }
+{ .mfi; xma.lu f44=f36,f120,f44
+ add r26=r26,r25 };;
+{ .mfi; getf.sig r16=f80
+ xma.hu f55=f36,f121,f54
+(p6) add carry1=1,carry1 }
+{ .mfi; xma.lu f54=f36,f121,f54 };;
+{ .mfi; getf.sig r17=f71
+ xma.hu f65=f36,f122,f64
+ cmp.ltu p6,p0=r26,r25 }
+{ .mfi; xma.lu f64=f36,f122,f64
+ add r27=r27,r26 };;
+{ .mfi; getf.sig r18=f62
+ xma.hu f75=f36,f123,f74
+(p6) add carry1=1,carry1 }
+{ .mfi; cmp.ltu p6,p0=r27,r26
+ xma.lu f74=f36,f123,f74
+ add r27=r27,carry2 };;
+{ .mfi; getf.sig r19=f53
+ xma.hu f85=f36,f124,f84
+(p6) add carry1=1,carry1 }
+{ .mfi; xma.lu f84=f36,f124,f84
+ cmp.ltu p6,p0=r27,carry2 };;
+{ .mfi; st8 [r33]=r27,16
+ xma.hu f95=f36,f125,f94
+(p6) add carry1=1,carry1 }
+{ .mfi; xma.lu f94=f36,f125,f94 };;
+{ .mfi; xma.hu f105=f36,f126,f104 }
+{ .mfi; mov carry2=0
+ xma.lu f104=f36,f126,f104
+ add r17=r17,r16 };;
+{ .mfi; xma.hu f115=f36,f127,f114
+ cmp.ltu p7,p0=r17,r16 }
+{ .mfi; xma.lu f114=f36,f127,f114
+ add r18=r18,r17 };;//
+//-------------------------------------------------//
+{ .mfi; getf.sig r20=f44
+ xma.hu f46=f37,f120,f45
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r18,r17
+ xma.lu f45=f37,f120,f45
+ add r19=r19,r18 };;
+{ .mfi; getf.sig r24=f90
+ xma.hu f56=f37,f121,f55 }
+{ .mfi; xma.lu f55=f37,f121,f55 };;
+{ .mfi; getf.sig r25=f81
+ xma.hu f66=f37,f122,f65
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r19,r18
+ xma.lu f65=f37,f122,f65
+ add r20=r20,r19 };;
+{ .mfi; getf.sig r26=f72
+ xma.hu f76=f37,f123,f75
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r20,r19
+ xma.lu f75=f37,f123,f75
+ add r20=r20,carry1 };;
+{ .mfi; getf.sig r27=f63
+ xma.hu f86=f37,f124,f85
+(p7) add carry2=1,carry2 }
+{ .mfi; xma.lu f85=f37,f124,f85
+ cmp.ltu p7,p0=r20,carry1 };;
+{ .mfi; getf.sig r28=f54
+ xma.hu f96=f37,f125,f95
+(p7) add carry2=1,carry2 }
+{ .mfi; st8 [r32]=r20,16
+ xma.lu f95=f37,f125,f95 };;
+{ .mfi; xma.hu f106=f37,f126,f105 }
+{ .mfi; mov carry1=0
+ xma.lu f105=f37,f126,f105
+ add r25=r25,r24 };;
+{ .mfi; xma.hu f116=f37,f127,f115
+ cmp.ltu p6,p0=r25,r24 }
+{ .mfi; xma.lu f115=f37,f127,f115
+ add r26=r26,r25 };;//
+//-------------------------------------------------//
+{ .mfi; getf.sig r29=f45
+ xma.hu f47=f38,f120,f46
+(p6) add carry1=1,carry1 }
+{ .mfi; cmp.ltu p6,p0=r26,r25
+ xma.lu f46=f38,f120,f46
+ add r27=r27,r26 };;
+{ .mfi; getf.sig r16=f100
+ xma.hu f57=f38,f121,f56
+(p6) add carry1=1,carry1 }
+{ .mfi; cmp.ltu p6,p0=r27,r26
+ xma.lu f56=f38,f121,f56
+ add r28=r28,r27 };;
+{ .mfi; getf.sig r17=f91
+ xma.hu f67=f38,f122,f66
+(p6) add carry1=1,carry1 }
+{ .mfi; cmp.ltu p6,p0=r28,r27
+ xma.lu f66=f38,f122,f66
+ add r29=r29,r28 };;
+{ .mfi; getf.sig r18=f82
+ xma.hu f77=f38,f123,f76
+(p6) add carry1=1,carry1 }
+{ .mfi; cmp.ltu p6,p0=r29,r28
+ xma.lu f76=f38,f123,f76
+ add r29=r29,carry2 };;
+{ .mfi; getf.sig r19=f73
+ xma.hu f87=f38,f124,f86
+(p6) add carry1=1,carry1 }
+{ .mfi; xma.lu f86=f38,f124,f86
+ cmp.ltu p6,p0=r29,carry2 };;
+{ .mfi; getf.sig r20=f64
+ xma.hu f97=f38,f125,f96
+(p6) add carry1=1,carry1 }
+{ .mfi; st8 [r33]=r29,16
+ xma.lu f96=f38,f125,f96 };;
+{ .mfi; getf.sig r21=f55
+ xma.hu f107=f38,f126,f106 }
+{ .mfi; mov carry2=0
+ xma.lu f106=f38,f126,f106
+ add r17=r17,r16 };;
+{ .mfi; xma.hu f117=f38,f127,f116
+ cmp.ltu p7,p0=r17,r16 }
+{ .mfi; xma.lu f116=f38,f127,f116
+ add r18=r18,r17 };;//
+//-------------------------------------------------//
+{ .mfi; getf.sig r22=f46
+ xma.hu f48=f39,f120,f47
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r18,r17
+ xma.lu f47=f39,f120,f47
+ add r19=r19,r18 };;
+{ .mfi; getf.sig r24=f110
+ xma.hu f58=f39,f121,f57
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r19,r18
+ xma.lu f57=f39,f121,f57
+ add r20=r20,r19 };;
+{ .mfi; getf.sig r25=f101
+ xma.hu f68=f39,f122,f67
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r20,r19
+ xma.lu f67=f39,f122,f67
+ add r21=r21,r20 };;
+{ .mfi; getf.sig r26=f92
+ xma.hu f78=f39,f123,f77
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r21,r20
+ xma.lu f77=f39,f123,f77
+ add r22=r22,r21 };;
+{ .mfi; getf.sig r27=f83
+ xma.hu f88=f39,f124,f87
+(p7) add carry2=1,carry2 }
+{ .mfi; cmp.ltu p7,p0=r22,r21
+ xma.lu f87=f39,f124,f87
+ add r22=r22,carry1 };;
+{ .mfi; getf.sig r28=f74
+ xma.hu f98=f39,f125,f97
+(p7) add carry2=1,carry2 }
+{ .mfi; xma.lu f97=f39,f125,f97
+ cmp.ltu p7,p0=r22,carry1 };;
+{ .mfi; getf.sig r29=f65
+ xma.hu f108=f39,f126,f107
+(p7) add carry2=1,carry2 }
+{ .mfi; st8 [r32]=r22,16
+ xma.lu f107=f39,f126,f107 };;
+{ .mfi; getf.sig r30=f56
+ xma.hu f118=f39,f127,f117 }
+{ .mfi; xma.lu f117=f39,f127,f117 };;//
+//-------------------------------------------------//
+// Leaving muliplier's heaven... Quite a ride, huh?
+
+{ .mii; getf.sig r31=f47
+ add r25=r25,r24
+ mov carry1=0 };;
+{ .mii; getf.sig r16=f111
+ cmp.ltu p6,p0=r25,r24
+ add r26=r26,r25 };;
+{ .mfb; getf.sig r17=f102 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r26,r25
+ add r27=r27,r26 };;
+{ .mfb; nop.m 0x0 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r27,r26
+ add r28=r28,r27 };;
+{ .mii; getf.sig r18=f93
+ add r17=r17,r16
+ mov carry3=0 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r28,r27
+ add r29=r29,r28 };;
+{ .mii; getf.sig r19=f84
+ cmp.ltu p7,p0=r17,r16 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r29,r28
+ add r30=r30,r29 };;
+{ .mii; getf.sig r20=f75
+ add r18=r18,r17 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r30,r29
+ add r31=r31,r30 };;
+{ .mfb; getf.sig r21=f66 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r18,r17
+ add r19=r19,r18 }
+{ .mfb; nop.m 0x0 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r31,r30
+ add r31=r31,carry2 };;
+{ .mfb; getf.sig r22=f57 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r19,r18
+ add r20=r20,r19 }
+{ .mfb; nop.m 0x0 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r31,carry2 };;
+{ .mfb; getf.sig r23=f48 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r20,r19
+ add r21=r21,r20 }
+{ .mii;
+(p6) add carry1=1,carry1 }
+{ .mfb; st8 [r33]=r31,16 };;
+
+{ .mfb; getf.sig r24=f112 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r21,r20
+ add r22=r22,r21 };;
+{ .mfb; getf.sig r25=f103 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r22,r21
+ add r23=r23,r22 };;
+{ .mfb; getf.sig r26=f94 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r23,r22
+ add r23=r23,carry1 };;
+{ .mfb; getf.sig r27=f85 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p8=r23,carry1};;
+{ .mii; getf.sig r28=f76
+ add r25=r25,r24
+ mov carry1=0 }
+{ .mii; st8 [r32]=r23,16
+ (p7) add carry2=1,carry3
+ (p8) add carry2=0,carry3 };;
+
+{ .mfb; nop.m 0x0 }
+{ .mii; getf.sig r29=f67
+ cmp.ltu p6,p0=r25,r24
+ add r26=r26,r25 };;
+{ .mfb; getf.sig r30=f58 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r26,r25
+ add r27=r27,r26 };;
+{ .mfb; getf.sig r16=f113 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r27,r26
+ add r28=r28,r27 };;
+{ .mfb; getf.sig r17=f104 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r28,r27
+ add r29=r29,r28 };;
+{ .mfb; getf.sig r18=f95 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r29,r28
+ add r30=r30,r29 };;
+{ .mii; getf.sig r19=f86
+ add r17=r17,r16
+ mov carry3=0 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r30,r29
+ add r30=r30,carry2 };;
+{ .mii; getf.sig r20=f77
+ cmp.ltu p7,p0=r17,r16
+ add r18=r18,r17 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r30,carry2 };;
+{ .mfb; getf.sig r21=f68 }
+{ .mii; st8 [r33]=r30,16
+(p6) add carry1=1,carry1 };;
+
+{ .mfb; getf.sig r24=f114 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r18,r17
+ add r19=r19,r18 };;
+{ .mfb; getf.sig r25=f105 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r19,r18
+ add r20=r20,r19 };;
+{ .mfb; getf.sig r26=f96 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r20,r19
+ add r21=r21,r20 };;
+{ .mfb; getf.sig r27=f87 }
+{ .mii; (p7) add carry3=1,carry3
+ cmp.ltu p7,p0=r21,r20
+ add r21=r21,carry1 };;
+{ .mib; getf.sig r28=f78
+ add r25=r25,r24 }
+{ .mib; (p7) add carry3=1,carry3
+ cmp.ltu p7,p8=r21,carry1};;
+{ .mii; st8 [r32]=r21,16
+ (p7) add carry2=1,carry3
+ (p8) add carry2=0,carry3 }
+
+{ .mii; mov carry1=0
+ cmp.ltu p6,p0=r25,r24
+ add r26=r26,r25 };;
+{ .mfb; getf.sig r16=f115 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r26,r25
+ add r27=r27,r26 };;
+{ .mfb; getf.sig r17=f106 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r27,r26
+ add r28=r28,r27 };;
+{ .mfb; getf.sig r18=f97 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r28,r27
+ add r28=r28,carry2 };;
+{ .mib; getf.sig r19=f88
+ add r17=r17,r16 }
+{ .mib;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r28,carry2 };;
+{ .mii; st8 [r33]=r28,16
+(p6) add carry1=1,carry1 }
+
+{ .mii; mov carry2=0
+ cmp.ltu p7,p0=r17,r16
+ add r18=r18,r17 };;
+{ .mfb; getf.sig r24=f116 }
+{ .mii; (p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r18,r17
+ add r19=r19,r18 };;
+{ .mfb; getf.sig r25=f107 }
+{ .mii; (p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r19,r18
+ add r19=r19,carry1 };;
+{ .mfb; getf.sig r26=f98 }
+{ .mii; (p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r19,carry1};;
+{ .mii; st8 [r32]=r19,16
+ (p7) add carry2=1,carry2 }
+
+{ .mfb; add r25=r25,r24 };;
+
+{ .mfb; getf.sig r16=f117 }
+{ .mii; mov carry1=0
+ cmp.ltu p6,p0=r25,r24
+ add r26=r26,r25 };;
+{ .mfb; getf.sig r17=f108 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r26,r25
+ add r26=r26,carry2 };;
+{ .mfb; nop.m 0x0 }
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r26,carry2 };;
+{ .mii; st8 [r33]=r26,16
+(p6) add carry1=1,carry1 }
+
+{ .mfb; add r17=r17,r16 };;
+{ .mfb; getf.sig r24=f118 }
+{ .mii; mov carry2=0
+ cmp.ltu p7,p0=r17,r16
+ add r17=r17,carry1 };;
+{ .mii; (p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r17,carry1};;
+{ .mii; st8 [r32]=r17
+ (p7) add carry2=1,carry2 };;
+{ .mfb; add r24=r24,carry2 };;
+{ .mib; st8 [r33]=r24 }
+
+{ .mib; rum 1<<5 // clear um.mfh
+ br.ret.sptk.many b0 };;
+.endp bn_mul_comba8#
+#undef carry3
+#undef carry2
+#undef carry1
+#endif
+
+#if 1
+// It's possible to make it faster (see comment to bn_sqr_comba8), but
+// I reckon it doesn't worth the effort. Basically because the routine
+// (actually both of them) practically never called... So I just play
+// same trick as with bn_sqr_comba8.
+//
+// void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+//
+.global bn_sqr_comba4#
+.proc bn_sqr_comba4#
+.align 64
+bn_sqr_comba4:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+{ .mii; alloc r2=ar.pfs,2,1,0,0
+ addp4 r32=0,r32
+ addp4 r33=0,r33 };;
+{ .mii;
+#else
+{ .mii; alloc r2=ar.pfs,2,1,0,0
+#endif
+ mov r34=r33
+ add r14=8,r33 };;
+ .body
+{ .mii; add r17=8,r34
+ add r15=16,r33
+ add r18=16,r34 }
+{ .mfb; add r16=24,r33
+ br .L_cheat_entry_point4 };;
+.endp bn_sqr_comba4#
+#endif
+
+#if 1
+// Runs in ~115 cycles and ~4.5 times faster than C. Well, whatever...
+//
+// void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+//
+#define carry1 r14
+#define carry2 r15
+.global bn_mul_comba4#
+.proc bn_mul_comba4#
+.align 64
+bn_mul_comba4:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+#if defined(_HPUX_SOURCE) && !defined(_LP64)
+{ .mii; alloc r2=ar.pfs,3,0,0,0
+ addp4 r33=0,r33
+ addp4 r34=0,r34 };;
+{ .mii; addp4 r32=0,r32
+#else
+{ .mii; alloc r2=ar.pfs,3,0,0,0
+#endif
+ add r14=8,r33
+ add r17=8,r34 }
+ .body
+{ .mii; add r15=16,r33
+ add r18=16,r34
+ add r16=24,r33 };;
+.L_cheat_entry_point4:
+{ .mmi; add r19=24,r34
+
+ ldf8 f32=[r33] }
+
+{ .mmi; ldf8 f120=[r34]
+ ldf8 f121=[r17] };;
+{ .mmi; ldf8 f122=[r18]
+ ldf8 f123=[r19] }
+
+{ .mmi; ldf8 f33=[r14]
+ ldf8 f34=[r15] }
+{ .mfi; ldf8 f35=[r16]
+
+ xma.hu f41=f32,f120,f0 }
+{ .mfi; xma.lu f40=f32,f120,f0 };;
+{ .mfi; xma.hu f51=f32,f121,f0 }
+{ .mfi; xma.lu f50=f32,f121,f0 };;
+{ .mfi; xma.hu f61=f32,f122,f0 }
+{ .mfi; xma.lu f60=f32,f122,f0 };;
+{ .mfi; xma.hu f71=f32,f123,f0 }
+{ .mfi; xma.lu f70=f32,f123,f0 };;//
+// Major stall takes place here, and 3 more places below. Result from
+// first xma is not available for another 3 ticks.
+{ .mfi; getf.sig r16=f40
+ xma.hu f42=f33,f120,f41
+ add r33=8,r32 }
+{ .mfi; xma.lu f41=f33,f120,f41 };;
+{ .mfi; getf.sig r24=f50
+ xma.hu f52=f33,f121,f51 }
+{ .mfi; xma.lu f51=f33,f121,f51 };;
+{ .mfi; st8 [r32]=r16,16
+ xma.hu f62=f33,f122,f61 }
+{ .mfi; xma.lu f61=f33,f122,f61 };;
+{ .mfi; xma.hu f72=f33,f123,f71 }
+{ .mfi; xma.lu f71=f33,f123,f71 };;//
+//-------------------------------------------------//
+{ .mfi; getf.sig r25=f41
+ xma.hu f43=f34,f120,f42 }
+{ .mfi; xma.lu f42=f34,f120,f42 };;
+{ .mfi; getf.sig r16=f60
+ xma.hu f53=f34,f121,f52 }
+{ .mfi; xma.lu f52=f34,f121,f52 };;
+{ .mfi; getf.sig r17=f51
+ xma.hu f63=f34,f122,f62
+ add r25=r25,r24 }
+{ .mfi; mov carry1=0
+ xma.lu f62=f34,f122,f62 };;
+{ .mfi; st8 [r33]=r25,16
+ xma.hu f73=f34,f123,f72
+ cmp.ltu p6,p0=r25,r24 }
+{ .mfi; xma.lu f72=f34,f123,f72 };;//
+//-------------------------------------------------//
+{ .mfi; getf.sig r18=f42
+ xma.hu f44=f35,f120,f43
+(p6) add carry1=1,carry1 }
+{ .mfi; add r17=r17,r16
+ xma.lu f43=f35,f120,f43
+ mov carry2=0 };;
+{ .mfi; getf.sig r24=f70
+ xma.hu f54=f35,f121,f53
+ cmp.ltu p7,p0=r17,r16 }
+{ .mfi; xma.lu f53=f35,f121,f53 };;
+{ .mfi; getf.sig r25=f61
+ xma.hu f64=f35,f122,f63
+ add r18=r18,r17 }
+{ .mfi; xma.lu f63=f35,f122,f63
+(p7) add carry2=1,carry2 };;
+{ .mfi; getf.sig r26=f52
+ xma.hu f74=f35,f123,f73
+ cmp.ltu p7,p0=r18,r17 }
+{ .mfi; xma.lu f73=f35,f123,f73
+ add r18=r18,carry1 };;
+//-------------------------------------------------//
+{ .mii; st8 [r32]=r18,16
+(p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r18,carry1 };;
+
+{ .mfi; getf.sig r27=f43 // last major stall
+(p7) add carry2=1,carry2 };;
+{ .mii; getf.sig r16=f71
+ add r25=r25,r24
+ mov carry1=0 };;
+{ .mii; getf.sig r17=f62
+ cmp.ltu p6,p0=r25,r24
+ add r26=r26,r25 };;
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r26,r25
+ add r27=r27,r26 };;
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r27,r26
+ add r27=r27,carry2 };;
+{ .mii; getf.sig r18=f53
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r27,carry2 };;
+{ .mfi; st8 [r33]=r27,16
+(p6) add carry1=1,carry1 }
+
+{ .mii; getf.sig r19=f44
+ add r17=r17,r16
+ mov carry2=0 };;
+{ .mii; getf.sig r24=f72
+ cmp.ltu p7,p0=r17,r16
+ add r18=r18,r17 };;
+{ .mii; (p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r18,r17
+ add r19=r19,r18 };;
+{ .mii; (p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r19,r18
+ add r19=r19,carry1 };;
+{ .mii; getf.sig r25=f63
+ (p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r19,carry1};;
+{ .mii; st8 [r32]=r19,16
+ (p7) add carry2=1,carry2 }
+
+{ .mii; getf.sig r26=f54
+ add r25=r25,r24
+ mov carry1=0 };;
+{ .mii; getf.sig r16=f73
+ cmp.ltu p6,p0=r25,r24
+ add r26=r26,r25 };;
+{ .mii;
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r26,r25
+ add r26=r26,carry2 };;
+{ .mii; getf.sig r17=f64
+(p6) add carry1=1,carry1
+ cmp.ltu p6,p0=r26,carry2 };;
+{ .mii; st8 [r33]=r26,16
+(p6) add carry1=1,carry1 }
+
+{ .mii; getf.sig r24=f74
+ add r17=r17,r16
+ mov carry2=0 };;
+{ .mii; cmp.ltu p7,p0=r17,r16
+ add r17=r17,carry1 };;
+
+{ .mii; (p7) add carry2=1,carry2
+ cmp.ltu p7,p0=r17,carry1};;
+{ .mii; st8 [r32]=r17,16
+ (p7) add carry2=1,carry2 };;
+
+{ .mii; add r24=r24,carry2 };;
+{ .mii; st8 [r33]=r24 }
+
+{ .mib; rum 1<<5 // clear um.mfh
+ br.ret.sptk.many b0 };;
+.endp bn_mul_comba4#
+#undef carry2
+#undef carry1
+#endif
+
+#if 1
+//
+// BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+//
+// In the nutshell it's a port of my MIPS III/IV implementation.
+//
+#define AT r14
+#define H r16
+#define HH r20
+#define L r17
+#define D r18
+#define DH r22
+#define I r21
+
+#if 0
+// Some preprocessors (most notably HP-UX) appear to be allergic to
+// macros enclosed to parenthesis [as these three were].
+#define cont p16
+#define break p0 // p20
+#define equ p24
+#else
+cont=p16
+break=p0
+equ=p24
+#endif
+
+.global abort#
+.global bn_div_words#
+.proc bn_div_words#
+.align 64
+bn_div_words:
+ .prologue
+ .fframe 0
+ .save ar.pfs,r2
+ .save b0,r3
+{ .mii; alloc r2=ar.pfs,3,5,0,8
+ mov r3=b0
+ mov r10=pr };;
+{ .mmb; cmp.eq p6,p0=r34,r0
+ mov r8=-1
+(p6) br.ret.spnt.many b0 };;
+
+ .body
+{ .mii; mov H=r32 // save h
+ mov ar.ec=0 // don't rotate at exit
+ mov pr.rot=0 }
+{ .mii; mov L=r33 // save l
+ mov r36=r0 };;
+
+.L_divw_shift: // -vv- note signed comparison
+{ .mfi; (p0) cmp.lt p16,p0=r0,r34 // d
+ (p0) shladd r33=r34,1,r0 }
+{ .mfb; (p0) add r35=1,r36
+ (p0) nop.f 0x0
+(p16) br.wtop.dpnt .L_divw_shift };;
+
+{ .mii; mov D=r34
+ shr.u DH=r34,32
+ sub r35=64,r36 };;
+{ .mii; setf.sig f7=DH
+ shr.u AT=H,r35
+ mov I=r36 };;
+{ .mib; cmp.ne p6,p0=r0,AT
+ shl H=H,r36
+(p6) br.call.spnt.clr b0=abort };; // overflow, die...
+
+{ .mfi; fcvt.xuf.s1 f7=f7
+ shr.u AT=L,r35 };;
+{ .mii; shl L=L,r36
+ or H=H,AT };;
+
+{ .mii; nop.m 0x0
+ cmp.leu p6,p0=D,H;;
+(p6) sub H=H,D }
+
+{ .mlx; setf.sig f14=D
+ movl AT=0xffffffff };;
+///////////////////////////////////////////////////////////
+{ .mii; setf.sig f6=H
+ shr.u HH=H,32;;
+ cmp.eq p6,p7=HH,DH };;
+{ .mfb;
+(p6) setf.sig f8=AT
+(p7) fcvt.xuf.s1 f6=f6
+(p7) br.call.sptk b6=.L_udiv64_32_b6 };;
+
+{ .mfi; getf.sig r33=f8 // q
+ xmpy.lu f9=f8,f14 }
+{ .mfi; xmpy.hu f10=f8,f14
+ shrp H=H,L,32 };;
+
+{ .mmi; getf.sig r35=f9 // tl
+ getf.sig r31=f10 };; // th
+
+.L_divw_1st_iter:
+{ .mii; (p0) add r32=-1,r33
+ (p0) cmp.eq equ,cont=HH,r31 };;
+{ .mii; (p0) cmp.ltu p8,p0=r35,D
+ (p0) sub r34=r35,D
+ (equ) cmp.leu break,cont=r35,H };;
+{ .mib; (cont) cmp.leu cont,break=HH,r31
+ (p8) add r31=-1,r31
+(cont) br.wtop.spnt .L_divw_1st_iter };;
+///////////////////////////////////////////////////////////
+{ .mii; sub H=H,r35
+ shl r8=r33,32
+ shl L=L,32 };;
+///////////////////////////////////////////////////////////
+{ .mii; setf.sig f6=H
+ shr.u HH=H,32;;
+ cmp.eq p6,p7=HH,DH };;
+{ .mfb;
+(p6) setf.sig f8=AT
+(p7) fcvt.xuf.s1 f6=f6
+(p7) br.call.sptk b6=.L_udiv64_32_b6 };;
+
+{ .mfi; getf.sig r33=f8 // q
+ xmpy.lu f9=f8,f14 }
+{ .mfi; xmpy.hu f10=f8,f14
+ shrp H=H,L,32 };;
+
+{ .mmi; getf.sig r35=f9 // tl
+ getf.sig r31=f10 };; // th
+
+.L_divw_2nd_iter:
+{ .mii; (p0) add r32=-1,r33
+ (p0) cmp.eq equ,cont=HH,r31 };;
+{ .mii; (p0) cmp.ltu p8,p0=r35,D
+ (p0) sub r34=r35,D
+ (equ) cmp.leu break,cont=r35,H };;
+{ .mib; (cont) cmp.leu cont,break=HH,r31
+ (p8) add r31=-1,r31
+(cont) br.wtop.spnt .L_divw_2nd_iter };;
+///////////////////////////////////////////////////////////
+{ .mii; sub H=H,r35
+ or r8=r8,r33
+ mov ar.pfs=r2 };;
+{ .mii; shr.u r9=H,I // remainder if anybody wants it
+ mov pr=r10,0x1ffff }
+{ .mfb; br.ret.sptk.many b0 };;
+
+// Unsigned 64 by 32 (well, by 64 for the moment) bit integer division
+// procedure.
+//
+// inputs: f6 = (double)a, f7 = (double)b
+// output: f8 = (int)(a/b)
+// clobbered: f8,f9,f10,f11,pred
+pred=p15
+// One can argue that this snippet is copyrighted to Intel
+// Corporation, as it's essentially identical to one of those
+// found in "Divide, Square Root and Remainder" section at
+// http://www.intel.com/software/products/opensource/libraries/num.htm.
+// Yes, I admit that the referred code was used as template,
+// but after I realized that there hardly is any other instruction
+// sequence which would perform this operation. I mean I figure that
+// any independent attempt to implement high-performance division
+// will result in code virtually identical to the Intel code. It
+// should be noted though that below division kernel is 1 cycle
+// faster than Intel one (note commented splits:-), not to mention
+// original prologue (rather lack of one) and epilogue.
+.align 32
+.skip 16
+.L_udiv64_32_b6:
+ frcpa.s1 f8,pred=f6,f7;; // [0] y0 = 1 / b
+
+(pred) fnma.s1 f9=f7,f8,f1 // [5] e0 = 1 - b * y0
+(pred) fmpy.s1 f10=f6,f8;; // [5] q0 = a * y0
+(pred) fmpy.s1 f11=f9,f9 // [10] e1 = e0 * e0
+(pred) fma.s1 f10=f9,f10,f10;; // [10] q1 = q0 + e0 * q0
+(pred) fma.s1 f8=f9,f8,f8 //;; // [15] y1 = y0 + e0 * y0
+(pred) fma.s1 f9=f11,f10,f10;; // [15] q2 = q1 + e1 * q1
+(pred) fma.s1 f8=f11,f8,f8 //;; // [20] y2 = y1 + e1 * y1
+(pred) fnma.s1 f10=f7,f9,f6;; // [20] r2 = a - b * q2
+(pred) fma.s1 f8=f10,f8,f9;; // [25] q3 = q2 + r2 * y2
+
+ fcvt.fxu.trunc.s1 f8=f8 // [30] q = trunc(q3)
+ br.ret.sptk.many b6;;
+.endp bn_div_words#
+#endif
diff --git a/openssl/trunk/crypto/bn/asm/mips3.s b/openssl/trunk/crypto/bn/asm/mips3.s
new file mode 100644
index 00000000..dca4105c
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/mips3.s
@@ -0,0 +1,2201 @@
+.rdata
+.asciiz "mips3.s, Version 1.1"
+.asciiz "MIPS III/IV ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+/*
+ * ====================================================================
+ * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+ * project.
+ *
+ * Rights for redistribution and usage in source and binary forms are
+ * granted according to the OpenSSL license. Warranty of any kind is
+ * disclaimed.
+ * ====================================================================
+ */
+
+/*
+ * This is my modest contributon to the OpenSSL project (see
+ * http://www.openssl.org/ for more information about it) and is
+ * a drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c
+ * module. For updates see http://fy.chalmers.se/~appro/hpe/.
+ *
+ * The module is designed to work with either of the "new" MIPS ABI(5),
+ * namely N32 or N64, offered by IRIX 6.x. It's not ment to work under
+ * IRIX 5.x not only because it doesn't support new ABIs but also
+ * because 5.x kernels put R4x00 CPU into 32-bit mode and all those
+ * 64-bit instructions (daddu, dmultu, etc.) found below gonna only
+ * cause illegal instruction exception:-(
+ *
+ * In addition the code depends on preprocessor flags set up by MIPSpro
+ * compiler driver (either as or cc) and therefore (probably?) can't be
+ * compiled by the GNU assembler. GNU C driver manages fine though...
+ * I mean as long as -mmips-as is specified or is the default option,
+ * because then it simply invokes /usr/bin/as which in turn takes
+ * perfect care of the preprocessor definitions. Another neat feature
+ * offered by the MIPSpro assembler is an optimization pass. This gave
+ * me the opportunity to have the code looking more regular as all those
+ * architecture dependent instruction rescheduling details were left to
+ * the assembler. Cool, huh?
+ *
+ * Performance improvement is astonishing! 'apps/openssl speed rsa dsa'
+ * goes way over 3 times faster!
+ *
+ * <appro@fy.chalmers.se>
+ */
+#include <asm.h>
+#include <regdef.h>
+
+#if _MIPS_ISA>=4
+#define MOVNZ(cond,dst,src) \
+ movn dst,src,cond
+#else
+#define MOVNZ(cond,dst,src) \
+ .set noreorder; \
+ bnezl cond,.+8; \
+ move dst,src; \
+ .set reorder
+#endif
+
+.text
+
+.set noat
+.set reorder
+
+#define MINUS4 v1
+
+.align 5
+LEAF(bn_mul_add_words)
+ .set noreorder
+ bgtzl a2,.L_bn_mul_add_words_proceed
+ ld t0,0(a1)
+ jr ra
+ move v0,zero
+ .set reorder
+
+.L_bn_mul_add_words_proceed:
+ li MINUS4,-4
+ and ta0,a2,MINUS4
+ move v0,zero
+ beqz ta0,.L_bn_mul_add_words_tail
+
+.L_bn_mul_add_words_loop:
+ dmultu t0,a3
+ ld t1,0(a0)
+ ld t2,8(a1)
+ ld t3,8(a0)
+ ld ta0,16(a1)
+ ld ta1,16(a0)
+ daddu t1,v0
+ sltu v0,t1,v0 /* All manuals say it "compares 32-bit
+ * values", but it seems to work fine
+ * even on 64-bit registers. */
+ mflo AT
+ mfhi t0
+ daddu t1,AT
+ daddu v0,t0
+ sltu AT,t1,AT
+ sd t1,0(a0)
+ daddu v0,AT
+
+ dmultu t2,a3
+ ld ta2,24(a1)
+ ld ta3,24(a0)
+ daddu t3,v0
+ sltu v0,t3,v0
+ mflo AT
+ mfhi t2
+ daddu t3,AT
+ daddu v0,t2
+ sltu AT,t3,AT
+ sd t3,8(a0)
+ daddu v0,AT
+
+ dmultu ta0,a3
+ subu a2,4
+ PTR_ADD a0,32
+ PTR_ADD a1,32
+ daddu ta1,v0
+ sltu v0,ta1,v0
+ mflo AT
+ mfhi ta0
+ daddu ta1,AT
+ daddu v0,ta0
+ sltu AT,ta1,AT
+ sd ta1,-16(a0)
+ daddu v0,AT
+
+
+ dmultu ta2,a3
+ and ta0,a2,MINUS4
+ daddu ta3,v0
+ sltu v0,ta3,v0
+ mflo AT
+ mfhi ta2
+ daddu ta3,AT
+ daddu v0,ta2
+ sltu AT,ta3,AT
+ sd ta3,-8(a0)
+ daddu v0,AT
+ .set noreorder
+ bgtzl ta0,.L_bn_mul_add_words_loop
+ ld t0,0(a1)
+
+ bnezl a2,.L_bn_mul_add_words_tail
+ ld t0,0(a1)
+ .set reorder
+
+.L_bn_mul_add_words_return:
+ jr ra
+
+.L_bn_mul_add_words_tail:
+ dmultu t0,a3
+ ld t1,0(a0)
+ subu a2,1
+ daddu t1,v0
+ sltu v0,t1,v0
+ mflo AT
+ mfhi t0
+ daddu t1,AT
+ daddu v0,t0
+ sltu AT,t1,AT
+ sd t1,0(a0)
+ daddu v0,AT
+ beqz a2,.L_bn_mul_add_words_return
+
+ ld t0,8(a1)
+ dmultu t0,a3
+ ld t1,8(a0)
+ subu a2,1
+ daddu t1,v0
+ sltu v0,t1,v0
+ mflo AT
+ mfhi t0
+ daddu t1,AT
+ daddu v0,t0
+ sltu AT,t1,AT
+ sd t1,8(a0)
+ daddu v0,AT
+ beqz a2,.L_bn_mul_add_words_return
+
+ ld t0,16(a1)
+ dmultu t0,a3
+ ld t1,16(a0)
+ daddu t1,v0
+ sltu v0,t1,v0
+ mflo AT
+ mfhi t0
+ daddu t1,AT
+ daddu v0,t0
+ sltu AT,t1,AT
+ sd t1,16(a0)
+ daddu v0,AT
+ jr ra
+END(bn_mul_add_words)
+
+.align 5
+LEAF(bn_mul_words)
+ .set noreorder
+ bgtzl a2,.L_bn_mul_words_proceed
+ ld t0,0(a1)
+ jr ra
+ move v0,zero
+ .set reorder
+
+.L_bn_mul_words_proceed:
+ li MINUS4,-4
+ and ta0,a2,MINUS4
+ move v0,zero
+ beqz ta0,.L_bn_mul_words_tail
+
+.L_bn_mul_words_loop:
+ dmultu t0,a3
+ ld t2,8(a1)
+ ld ta0,16(a1)
+ ld ta2,24(a1)
+ mflo AT
+ mfhi t0
+ daddu v0,AT
+ sltu t1,v0,AT
+ sd v0,0(a0)
+ daddu v0,t1,t0
+
+ dmultu t2,a3
+ subu a2,4
+ PTR_ADD a0,32
+ PTR_ADD a1,32
+ mflo AT
+ mfhi t2
+ daddu v0,AT
+ sltu t3,v0,AT
+ sd v0,-24(a0)
+ daddu v0,t3,t2
+
+ dmultu ta0,a3
+ mflo AT
+ mfhi ta0
+ daddu v0,AT
+ sltu ta1,v0,AT
+ sd v0,-16(a0)
+ daddu v0,ta1,ta0
+
+
+ dmultu ta2,a3
+ and ta0,a2,MINUS4
+ mflo AT
+ mfhi ta2
+ daddu v0,AT
+ sltu ta3,v0,AT
+ sd v0,-8(a0)
+ daddu v0,ta3,ta2
+ .set noreorder
+ bgtzl ta0,.L_bn_mul_words_loop
+ ld t0,0(a1)
+
+ bnezl a2,.L_bn_mul_words_tail
+ ld t0,0(a1)
+ .set reorder
+
+.L_bn_mul_words_return:
+ jr ra
+
+.L_bn_mul_words_tail:
+ dmultu t0,a3
+ subu a2,1
+ mflo AT
+ mfhi t0
+ daddu v0,AT
+ sltu t1,v0,AT
+ sd v0,0(a0)
+ daddu v0,t1,t0
+ beqz a2,.L_bn_mul_words_return
+
+ ld t0,8(a1)
+ dmultu t0,a3
+ subu a2,1
+ mflo AT
+ mfhi t0
+ daddu v0,AT
+ sltu t1,v0,AT
+ sd v0,8(a0)
+ daddu v0,t1,t0
+ beqz a2,.L_bn_mul_words_return
+
+ ld t0,16(a1)
+ dmultu t0,a3
+ mflo AT
+ mfhi t0
+ daddu v0,AT
+ sltu t1,v0,AT
+ sd v0,16(a0)
+ daddu v0,t1,t0
+ jr ra
+END(bn_mul_words)
+
+.align 5
+LEAF(bn_sqr_words)
+ .set noreorder
+ bgtzl a2,.L_bn_sqr_words_proceed
+ ld t0,0(a1)
+ jr ra
+ move v0,zero
+ .set reorder
+
+.L_bn_sqr_words_proceed:
+ li MINUS4,-4
+ and ta0,a2,MINUS4
+ move v0,zero
+ beqz ta0,.L_bn_sqr_words_tail
+
+.L_bn_sqr_words_loop:
+ dmultu t0,t0
+ ld t2,8(a1)
+ ld ta0,16(a1)
+ ld ta2,24(a1)
+ mflo t1
+ mfhi t0
+ sd t1,0(a0)
+ sd t0,8(a0)
+
+ dmultu t2,t2
+ subu a2,4
+ PTR_ADD a0,64
+ PTR_ADD a1,32
+ mflo t3
+ mfhi t2
+ sd t3,-48(a0)
+ sd t2,-40(a0)
+
+ dmultu ta0,ta0
+ mflo ta1
+ mfhi ta0
+ sd ta1,-32(a0)
+ sd ta0,-24(a0)
+
+
+ dmultu ta2,ta2
+ and ta0,a2,MINUS4
+ mflo ta3
+ mfhi ta2
+ sd ta3,-16(a0)
+ sd ta2,-8(a0)
+
+ .set noreorder
+ bgtzl ta0,.L_bn_sqr_words_loop
+ ld t0,0(a1)
+
+ bnezl a2,.L_bn_sqr_words_tail
+ ld t0,0(a1)
+ .set reorder
+
+.L_bn_sqr_words_return:
+ move v0,zero
+ jr ra
+
+.L_bn_sqr_words_tail:
+ dmultu t0,t0
+ subu a2,1
+ mflo t1
+ mfhi t0
+ sd t1,0(a0)
+ sd t0,8(a0)
+ beqz a2,.L_bn_sqr_words_return
+
+ ld t0,8(a1)
+ dmultu t0,t0
+ subu a2,1
+ mflo t1
+ mfhi t0
+ sd t1,16(a0)
+ sd t0,24(a0)
+ beqz a2,.L_bn_sqr_words_return
+
+ ld t0,16(a1)
+ dmultu t0,t0
+ mflo t1
+ mfhi t0
+ sd t1,32(a0)
+ sd t0,40(a0)
+ jr ra
+END(bn_sqr_words)
+
+.align 5
+LEAF(bn_add_words)
+ .set noreorder
+ bgtzl a3,.L_bn_add_words_proceed
+ ld t0,0(a1)
+ jr ra
+ move v0,zero
+ .set reorder
+
+.L_bn_add_words_proceed:
+ li MINUS4,-4
+ and AT,a3,MINUS4
+ move v0,zero
+ beqz AT,.L_bn_add_words_tail
+
+.L_bn_add_words_loop:
+ ld ta0,0(a2)
+ subu a3,4
+ ld t1,8(a1)
+ and AT,a3,MINUS4
+ ld t2,16(a1)
+ PTR_ADD a2,32
+ ld t3,24(a1)
+ PTR_ADD a0,32
+ ld ta1,-24(a2)
+ PTR_ADD a1,32
+ ld ta2,-16(a2)
+ ld ta3,-8(a2)
+ daddu ta0,t0
+ sltu t8,ta0,t0
+ daddu t0,ta0,v0
+ sltu v0,t0,ta0
+ sd t0,-32(a0)
+ daddu v0,t8
+
+ daddu ta1,t1
+ sltu t9,ta1,t1
+ daddu t1,ta1,v0
+ sltu v0,t1,ta1
+ sd t1,-24(a0)
+ daddu v0,t9
+
+ daddu ta2,t2
+ sltu t8,ta2,t2
+ daddu t2,ta2,v0
+ sltu v0,t2,ta2
+ sd t2,-16(a0)
+ daddu v0,t8
+
+ daddu ta3,t3
+ sltu t9,ta3,t3
+ daddu t3,ta3,v0
+ sltu v0,t3,ta3
+ sd t3,-8(a0)
+ daddu v0,t9
+
+ .set noreorder
+ bgtzl AT,.L_bn_add_words_loop
+ ld t0,0(a1)
+
+ bnezl a3,.L_bn_add_words_tail
+ ld t0,0(a1)
+ .set reorder
+
+.L_bn_add_words_return:
+ jr ra
+
+.L_bn_add_words_tail:
+ ld ta0,0(a2)
+ daddu ta0,t0
+ subu a3,1
+ sltu t8,ta0,t0
+ daddu t0,ta0,v0
+ sltu v0,t0,ta0
+ sd t0,0(a0)
+ daddu v0,t8
+ beqz a3,.L_bn_add_words_return
+
+ ld t1,8(a1)
+ ld ta1,8(a2)
+ daddu ta1,t1
+ subu a3,1
+ sltu t9,ta1,t1
+ daddu t1,ta1,v0
+ sltu v0,t1,ta1
+ sd t1,8(a0)
+ daddu v0,t9
+ beqz a3,.L_bn_add_words_return
+
+ ld t2,16(a1)
+ ld ta2,16(a2)
+ daddu ta2,t2
+ sltu t8,ta2,t2
+ daddu t2,ta2,v0
+ sltu v0,t2,ta2
+ sd t2,16(a0)
+ daddu v0,t8
+ jr ra
+END(bn_add_words)
+
+.align 5
+LEAF(bn_sub_words)
+ .set noreorder
+ bgtzl a3,.L_bn_sub_words_proceed
+ ld t0,0(a1)
+ jr ra
+ move v0,zero
+ .set reorder
+
+.L_bn_sub_words_proceed:
+ li MINUS4,-4
+ and AT,a3,MINUS4
+ move v0,zero
+ beqz AT,.L_bn_sub_words_tail
+
+.L_bn_sub_words_loop:
+ ld ta0,0(a2)
+ subu a3,4
+ ld t1,8(a1)
+ and AT,a3,MINUS4
+ ld t2,16(a1)
+ PTR_ADD a2,32
+ ld t3,24(a1)
+ PTR_ADD a0,32
+ ld ta1,-24(a2)
+ PTR_ADD a1,32
+ ld ta2,-16(a2)
+ ld ta3,-8(a2)
+ sltu t8,t0,ta0
+ dsubu t0,ta0
+ dsubu ta0,t0,v0
+ sd ta0,-32(a0)
+ MOVNZ (t0,v0,t8)
+
+ sltu t9,t1,ta1
+ dsubu t1,ta1
+ dsubu ta1,t1,v0
+ sd ta1,-24(a0)
+ MOVNZ (t1,v0,t9)
+
+
+ sltu t8,t2,ta2
+ dsubu t2,ta2
+ dsubu ta2,t2,v0
+ sd ta2,-16(a0)
+ MOVNZ (t2,v0,t8)
+
+ sltu t9,t3,ta3
+ dsubu t3,ta3
+ dsubu ta3,t3,v0
+ sd ta3,-8(a0)
+ MOVNZ (t3,v0,t9)
+
+ .set noreorder
+ bgtzl AT,.L_bn_sub_words_loop
+ ld t0,0(a1)
+
+ bnezl a3,.L_bn_sub_words_tail
+ ld t0,0(a1)
+ .set reorder
+
+.L_bn_sub_words_return:
+ jr ra
+
+.L_bn_sub_words_tail:
+ ld ta0,0(a2)
+ subu a3,1
+ sltu t8,t0,ta0
+ dsubu t0,ta0
+ dsubu ta0,t0,v0
+ MOVNZ (t0,v0,t8)
+ sd ta0,0(a0)
+ beqz a3,.L_bn_sub_words_return
+
+ ld t1,8(a1)
+ subu a3,1
+ ld ta1,8(a2)
+ sltu t9,t1,ta1
+ dsubu t1,ta1
+ dsubu ta1,t1,v0
+ MOVNZ (t1,v0,t9)
+ sd ta1,8(a0)
+ beqz a3,.L_bn_sub_words_return
+
+ ld t2,16(a1)
+ ld ta2,16(a2)
+ sltu t8,t2,ta2
+ dsubu t2,ta2
+ dsubu ta2,t2,v0
+ MOVNZ (t2,v0,t8)
+ sd ta2,16(a0)
+ jr ra
+END(bn_sub_words)
+
+#undef MINUS4
+
+.align 5
+LEAF(bn_div_3_words)
+ .set reorder
+ move a3,a0 /* we know that bn_div_words doesn't
+ * touch a3, ta2, ta3 and preserves a2
+ * so that we can save two arguments
+ * and return address in registers
+ * instead of stack:-)
+ */
+ ld a0,(a3)
+ move ta2,a1
+ ld a1,-8(a3)
+ bne a0,a2,.L_bn_div_3_words_proceed
+ li v0,-1
+ jr ra
+.L_bn_div_3_words_proceed:
+ move ta3,ra
+ bal bn_div_words
+ move ra,ta3
+ dmultu ta2,v0
+ ld t2,-16(a3)
+ move ta0,zero
+ mfhi t1
+ mflo t0
+ sltu t8,t1,v1
+.L_bn_div_3_words_inner_loop:
+ bnez t8,.L_bn_div_3_words_inner_loop_done
+ sgeu AT,t2,t0
+ seq t9,t1,v1
+ and AT,t9
+ sltu t3,t0,ta2
+ daddu v1,a2
+ dsubu t1,t3
+ dsubu t0,ta2
+ sltu t8,t1,v1
+ sltu ta0,v1,a2
+ or t8,ta0
+ .set noreorder
+ beqzl AT,.L_bn_div_3_words_inner_loop
+ dsubu v0,1
+ .set reorder
+.L_bn_div_3_words_inner_loop_done:
+ jr ra
+END(bn_div_3_words)
+
+.align 5
+LEAF(bn_div_words)
+ .set noreorder
+ bnezl a2,.L_bn_div_words_proceed
+ move v1,zero
+ jr ra
+ li v0,-1 /* I'd rather signal div-by-zero
+ * which can be done with 'break 7' */
+
+.L_bn_div_words_proceed:
+ bltz a2,.L_bn_div_words_body
+ move t9,v1
+ dsll a2,1
+ bgtz a2,.-4
+ addu t9,1
+
+ .set reorder
+ negu t1,t9
+ li t2,-1
+ dsll t2,t1
+ and t2,a0
+ dsrl AT,a1,t1
+ .set noreorder
+ bnezl t2,.+8
+ break 6 /* signal overflow */
+ .set reorder
+ dsll a0,t9
+ dsll a1,t9
+ or a0,AT
+
+#define QT ta0
+#define HH ta1
+#define DH v1
+.L_bn_div_words_body:
+ dsrl DH,a2,32
+ sgeu AT,a0,a2
+ .set noreorder
+ bnezl AT,.+8
+ dsubu a0,a2
+ .set reorder
+
+ li QT,-1
+ dsrl HH,a0,32
+ dsrl QT,32 /* q=0xffffffff */
+ beq DH,HH,.L_bn_div_words_skip_div1
+ ddivu zero,a0,DH
+ mflo QT
+.L_bn_div_words_skip_div1:
+ dmultu a2,QT
+ dsll t3,a0,32
+ dsrl AT,a1,32
+ or t3,AT
+ mflo t0
+ mfhi t1
+.L_bn_div_words_inner_loop1:
+ sltu t2,t3,t0
+ seq t8,HH,t1
+ sltu AT,HH,t1
+ and t2,t8
+ sltu v0,t0,a2
+ or AT,t2
+ .set noreorder
+ beqz AT,.L_bn_div_words_inner_loop1_done
+ dsubu t1,v0
+ dsubu t0,a2
+ b .L_bn_div_words_inner_loop1
+ dsubu QT,1
+ .set reorder
+.L_bn_div_words_inner_loop1_done:
+
+ dsll a1,32
+ dsubu a0,t3,t0
+ dsll v0,QT,32
+
+ li QT,-1
+ dsrl HH,a0,32
+ dsrl QT,32 /* q=0xffffffff */
+ beq DH,HH,.L_bn_div_words_skip_div2
+ ddivu zero,a0,DH
+ mflo QT
+.L_bn_div_words_skip_div2:
+#undef DH
+ dmultu a2,QT
+ dsll t3,a0,32
+ dsrl AT,a1,32
+ or t3,AT
+ mflo t0
+ mfhi t1
+.L_bn_div_words_inner_loop2:
+ sltu t2,t3,t0
+ seq t8,HH,t1
+ sltu AT,HH,t1
+ and t2,t8
+ sltu v1,t0,a2
+ or AT,t2
+ .set noreorder
+ beqz AT,.L_bn_div_words_inner_loop2_done
+ dsubu t1,v1
+ dsubu t0,a2
+ b .L_bn_div_words_inner_loop2
+ dsubu QT,1
+ .set reorder
+.L_bn_div_words_inner_loop2_done:
+#undef HH
+
+ dsubu a0,t3,t0
+ or v0,QT
+ dsrl v1,a0,t9 /* v1 contains remainder if anybody wants it */
+ dsrl a2,t9 /* restore a2 */
+ jr ra
+#undef QT
+END(bn_div_words)
+
+#define a_0 t0
+#define a_1 t1
+#define a_2 t2
+#define a_3 t3
+#define b_0 ta0
+#define b_1 ta1
+#define b_2 ta2
+#define b_3 ta3
+
+#define a_4 s0
+#define a_5 s2
+#define a_6 s4
+#define a_7 a1 /* once we load a[7] we don't need a anymore */
+#define b_4 s1
+#define b_5 s3
+#define b_6 s5
+#define b_7 a2 /* once we load b[7] we don't need b anymore */
+
+#define t_1 t8
+#define t_2 t9
+
+#define c_1 v0
+#define c_2 v1
+#define c_3 a3
+
+#define FRAME_SIZE 48
+
+.align 5
+LEAF(bn_mul_comba8)
+ .set noreorder
+ PTR_SUB sp,FRAME_SIZE
+ .frame sp,64,ra
+ .set reorder
+ ld a_0,0(a1) /* If compiled with -mips3 option on
+ * R5000 box assembler barks on this
+ * line with "shouldn't have mult/div
+ * as last instruction in bb (R10K
+ * bug)" warning. If anybody out there
+ * has a clue about how to circumvent
+ * this do send me a note.
+ * <appro@fy.chalmers.se>
+ */
+ ld b_0,0(a2)
+ ld a_1,8(a1)
+ ld a_2,16(a1)
+ ld a_3,24(a1)
+ ld b_1,8(a2)
+ ld b_2,16(a2)
+ ld b_3,24(a2)
+ dmultu a_0,b_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
+ sd s0,0(sp)
+ sd s1,8(sp)
+ sd s2,16(sp)
+ sd s3,24(sp)
+ sd s4,32(sp)
+ sd s5,40(sp)
+ mflo c_1
+ mfhi c_2
+
+ dmultu a_0,b_1 /* mul_add_c(a[0],b[1],c2,c3,c1); */
+ ld a_4,32(a1)
+ ld a_5,40(a1)
+ ld a_6,48(a1)
+ ld a_7,56(a1)
+ ld b_4,32(a2)
+ ld b_5,40(a2)
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu c_3,t_2,AT
+ dmultu a_1,b_0 /* mul_add_c(a[1],b[0],c2,c3,c1); */
+ ld b_6,48(a2)
+ ld b_7,56(a2)
+ sd c_1,0(a0) /* r[0]=c1; */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu c_1,c_3,t_2
+ sd c_2,8(a0) /* r[1]=c2; */
+
+ dmultu a_2,b_0 /* mul_add_c(a[2],b[0],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ dmultu a_1,b_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu c_2,c_1,t_2
+ dmultu a_0,b_2 /* mul_add_c(a[0],b[2],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,16(a0) /* r[2]=c3; */
+
+ dmultu a_0,b_3 /* mul_add_c(a[0],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu c_3,c_2,t_2
+ dmultu a_1,b_2 /* mul_add_c(a[1],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_2,b_1 /* mul_add_c(a[2],b[1],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_3,b_0 /* mul_add_c(a[3],b[0],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,24(a0) /* r[3]=c1; */
+
+ dmultu a_4,b_0 /* mul_add_c(a[4],b[0],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu c_1,c_3,t_2
+ dmultu a_3,b_1 /* mul_add_c(a[3],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_2,b_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_1,b_3 /* mul_add_c(a[1],b[3],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_0,b_4 /* mul_add_c(a[0],b[4],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,32(a0) /* r[4]=c2; */
+
+ dmultu a_0,b_5 /* mul_add_c(a[0],b[5],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu c_2,c_1,t_2
+ dmultu a_1,b_4 /* mul_add_c(a[1],b[4],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_2,b_3 /* mul_add_c(a[2],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_3,b_2 /* mul_add_c(a[3],b[2],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_4,b_1 /* mul_add_c(a[4],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_5,b_0 /* mul_add_c(a[5],b[0],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,40(a0) /* r[5]=c3; */
+
+ dmultu a_6,b_0 /* mul_add_c(a[6],b[0],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu c_3,c_2,t_2
+ dmultu a_5,b_1 /* mul_add_c(a[5],b[1],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_4,b_2 /* mul_add_c(a[4],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_3,b_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_2,b_4 /* mul_add_c(a[2],b[4],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_1,b_5 /* mul_add_c(a[1],b[5],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_0,b_6 /* mul_add_c(a[0],b[6],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,48(a0) /* r[6]=c1; */
+
+ dmultu a_0,b_7 /* mul_add_c(a[0],b[7],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu c_1,c_3,t_2
+ dmultu a_1,b_6 /* mul_add_c(a[1],b[6],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_2,b_5 /* mul_add_c(a[2],b[5],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_3,b_4 /* mul_add_c(a[3],b[4],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_4,b_3 /* mul_add_c(a[4],b[3],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_5,b_2 /* mul_add_c(a[5],b[2],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_6,b_1 /* mul_add_c(a[6],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_7,b_0 /* mul_add_c(a[7],b[0],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,56(a0) /* r[7]=c2; */
+
+ dmultu a_7,b_1 /* mul_add_c(a[7],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu c_2,c_1,t_2
+ dmultu a_6,b_2 /* mul_add_c(a[6],b[2],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_5,b_3 /* mul_add_c(a[5],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_4,b_4 /* mul_add_c(a[4],b[4],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_3,b_5 /* mul_add_c(a[3],b[5],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_2,b_6 /* mul_add_c(a[2],b[6],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_1,b_7 /* mul_add_c(a[1],b[7],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,64(a0) /* r[8]=c3; */
+
+ dmultu a_2,b_7 /* mul_add_c(a[2],b[7],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu c_3,c_2,t_2
+ dmultu a_3,b_6 /* mul_add_c(a[3],b[6],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_4,b_5 /* mul_add_c(a[4],b[5],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_5,b_4 /* mul_add_c(a[5],b[4],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_6,b_3 /* mul_add_c(a[6],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_7,b_2 /* mul_add_c(a[7],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,72(a0) /* r[9]=c1; */
+
+ dmultu a_7,b_3 /* mul_add_c(a[7],b[3],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu c_1,c_3,t_2
+ dmultu a_6,b_4 /* mul_add_c(a[6],b[4],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_5,b_5 /* mul_add_c(a[5],b[5],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_4,b_6 /* mul_add_c(a[4],b[6],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_3,b_7 /* mul_add_c(a[3],b[7],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,80(a0) /* r[10]=c2; */
+
+ dmultu a_4,b_7 /* mul_add_c(a[4],b[7],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu c_2,c_1,t_2
+ dmultu a_5,b_6 /* mul_add_c(a[5],b[6],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_6,b_5 /* mul_add_c(a[6],b[5],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_7,b_4 /* mul_add_c(a[7],b[4],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,88(a0) /* r[11]=c3; */
+
+ dmultu a_7,b_5 /* mul_add_c(a[7],b[5],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu c_3,c_2,t_2
+ dmultu a_6,b_6 /* mul_add_c(a[6],b[6],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_5,b_7 /* mul_add_c(a[5],b[7],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,96(a0) /* r[12]=c1; */
+
+ dmultu a_6,b_7 /* mul_add_c(a[6],b[7],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu c_1,c_3,t_2
+ dmultu a_7,b_6 /* mul_add_c(a[7],b[6],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,104(a0) /* r[13]=c2; */
+
+ dmultu a_7,b_7 /* mul_add_c(a[7],b[7],c3,c1,c2); */
+ ld s0,0(sp)
+ ld s1,8(sp)
+ ld s2,16(sp)
+ ld s3,24(sp)
+ ld s4,32(sp)
+ ld s5,40(sp)
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sd c_3,112(a0) /* r[14]=c3; */
+ sd c_1,120(a0) /* r[15]=c1; */
+
+ PTR_ADD sp,FRAME_SIZE
+
+ jr ra
+END(bn_mul_comba8)
+
+.align 5
+LEAF(bn_mul_comba4)
+ .set reorder
+ ld a_0,0(a1)
+ ld b_0,0(a2)
+ ld a_1,8(a1)
+ ld a_2,16(a1)
+ dmultu a_0,b_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
+ ld a_3,24(a1)
+ ld b_1,8(a2)
+ ld b_2,16(a2)
+ ld b_3,24(a2)
+ mflo c_1
+ mfhi c_2
+ sd c_1,0(a0)
+
+ dmultu a_0,b_1 /* mul_add_c(a[0],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu c_3,t_2,AT
+ dmultu a_1,b_0 /* mul_add_c(a[1],b[0],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu c_1,c_3,t_2
+ sd c_2,8(a0)
+
+ dmultu a_2,b_0 /* mul_add_c(a[2],b[0],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ dmultu a_1,b_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu c_2,c_1,t_2
+ dmultu a_0,b_2 /* mul_add_c(a[0],b[2],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,16(a0)
+
+ dmultu a_0,b_3 /* mul_add_c(a[0],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu c_3,c_2,t_2
+ dmultu a_1,b_2 /* mul_add_c(a[1],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_2,b_1 /* mul_add_c(a[2],b[1],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_3,b_0 /* mul_add_c(a[3],b[0],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,24(a0)
+
+ dmultu a_3,b_1 /* mul_add_c(a[3],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu c_1,c_3,t_2
+ dmultu a_2,b_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_1,b_3 /* mul_add_c(a[1],b[3],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,32(a0)
+
+ dmultu a_2,b_3 /* mul_add_c(a[2],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu c_2,c_1,t_2
+ dmultu a_3,b_2 /* mul_add_c(a[3],b[2],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,40(a0)
+
+ dmultu a_3,b_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sd c_1,48(a0)
+ sd c_2,56(a0)
+
+ jr ra
+END(bn_mul_comba4)
+
+#undef a_4
+#undef a_5
+#undef a_6
+#undef a_7
+#define a_4 b_0
+#define a_5 b_1
+#define a_6 b_2
+#define a_7 b_3
+
+.align 5
+LEAF(bn_sqr_comba8)
+ .set reorder
+ ld a_0,0(a1)
+ ld a_1,8(a1)
+ ld a_2,16(a1)
+ ld a_3,24(a1)
+
+ dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
+ ld a_4,32(a1)
+ ld a_5,40(a1)
+ ld a_6,48(a1)
+ ld a_7,56(a1)
+ mflo c_1
+ mfhi c_2
+ sd c_1,0(a0)
+
+ dmultu a_0,a_1 /* mul_add_c2(a[0],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt c_1,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu c_3,t_2,AT
+ sd c_2,8(a0)
+
+ dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt c_2,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,16(a0)
+
+ dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt c_3,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_1,a_2 /* mul_add_c2(a[1],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_3,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,24(a0)
+
+ dmultu a_4,a_0 /* mul_add_c2(a[4],b[0],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt c_1,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_1,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,32(a0)
+
+ dmultu a_0,a_5 /* mul_add_c2(a[0],b[5],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt c_2,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_1,a_4 /* mul_add_c2(a[1],b[4],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_2,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_2,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,40(a0)
+
+ dmultu a_6,a_0 /* mul_add_c2(a[6],b[0],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt c_3,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_5,a_1 /* mul_add_c2(a[5],b[1],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_3,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_4,a_2 /* mul_add_c2(a[4],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_3,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,48(a0)
+
+ dmultu a_0,a_7 /* mul_add_c2(a[0],b[7],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt c_1,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_1,a_6 /* mul_add_c2(a[1],b[6],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_1,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_2,a_5 /* mul_add_c2(a[2],b[5],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_1,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_3,a_4 /* mul_add_c2(a[3],b[4],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_1,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,56(a0)
+
+ dmultu a_7,a_1 /* mul_add_c2(a[7],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt c_2,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_6,a_2 /* mul_add_c2(a[6],b[2],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_2,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_5,a_3 /* mul_add_c2(a[5],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_2,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_4,a_4 /* mul_add_c(a[4],b[4],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,64(a0)
+
+ dmultu a_2,a_7 /* mul_add_c2(a[2],b[7],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt c_3,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_3,a_6 /* mul_add_c2(a[3],b[6],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_3,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_4,a_5 /* mul_add_c2(a[4],b[5],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_3,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,72(a0)
+
+ dmultu a_7,a_3 /* mul_add_c2(a[7],b[3],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt c_1,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_6,a_4 /* mul_add_c2(a[6],b[4],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_1,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_5,a_5 /* mul_add_c(a[5],b[5],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,80(a0)
+
+ dmultu a_4,a_7 /* mul_add_c2(a[4],b[7],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt c_2,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_5,a_6 /* mul_add_c2(a[5],b[6],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_2,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,88(a0)
+
+ dmultu a_7,a_5 /* mul_add_c2(a[7],b[5],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt c_3,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_6,a_6 /* mul_add_c(a[6],b[6],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,96(a0)
+
+ dmultu a_6,a_7 /* mul_add_c2(a[6],b[7],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt c_1,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,104(a0)
+
+ dmultu a_7,a_7 /* mul_add_c(a[7],b[7],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sd c_3,112(a0)
+ sd c_1,120(a0)
+
+ jr ra
+END(bn_sqr_comba8)
+
+.align 5
+LEAF(bn_sqr_comba4)
+ .set reorder
+ ld a_0,0(a1)
+ ld a_1,8(a1)
+ ld a_2,16(a1)
+ ld a_3,24(a1)
+ dmultu a_0,a_0 /* mul_add_c(a[0],b[0],c1,c2,c3); */
+ mflo c_1
+ mfhi c_2
+ sd c_1,0(a0)
+
+ dmultu a_0,a_1 /* mul_add_c2(a[0],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt c_1,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu c_3,t_2,AT
+ sd c_2,8(a0)
+
+ dmultu a_2,a_0 /* mul_add_c2(a[2],b[0],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt c_2,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ dmultu a_1,a_1 /* mul_add_c(a[1],b[1],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,16(a0)
+
+ dmultu a_0,a_3 /* mul_add_c2(a[0],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt c_3,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ dmultu a_1,a_2 /* mul_add_c(a2[1],b[2],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ slt AT,t_2,zero
+ daddu c_3,AT
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sltu AT,c_2,t_2
+ daddu c_3,AT
+ sd c_1,24(a0)
+
+ dmultu a_3,a_1 /* mul_add_c2(a[3],b[1],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ slt c_1,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ dmultu a_2,a_2 /* mul_add_c(a[2],b[2],c2,c3,c1); */
+ mflo t_1
+ mfhi t_2
+ daddu c_2,t_1
+ sltu AT,c_2,t_1
+ daddu t_2,AT
+ daddu c_3,t_2
+ sltu AT,c_3,t_2
+ daddu c_1,AT
+ sd c_2,32(a0)
+
+ dmultu a_2,a_3 /* mul_add_c2(a[2],b[3],c3,c1,c2); */
+ mflo t_1
+ mfhi t_2
+ slt c_2,t_2,zero
+ dsll t_2,1
+ slt a2,t_1,zero
+ daddu t_2,a2
+ dsll t_1,1
+ daddu c_3,t_1
+ sltu AT,c_3,t_1
+ daddu t_2,AT
+ daddu c_1,t_2
+ sltu AT,c_1,t_2
+ daddu c_2,AT
+ sd c_3,40(a0)
+
+ dmultu a_3,a_3 /* mul_add_c(a[3],b[3],c1,c2,c3); */
+ mflo t_1
+ mfhi t_2
+ daddu c_1,t_1
+ sltu AT,c_1,t_1
+ daddu t_2,AT
+ daddu c_2,t_2
+ sd c_1,48(a0)
+ sd c_2,56(a0)
+
+ jr ra
+END(bn_sqr_comba4)
diff --git a/openssl/trunk/crypto/bn/asm/pa-risc2.s b/openssl/trunk/crypto/bn/asm/pa-risc2.s
new file mode 100644
index 00000000..f3b16290
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/pa-risc2.s
@@ -0,0 +1,1618 @@
+;
+; PA-RISC 2.0 implementation of bn_asm code, based on the
+; 64-bit version of the code. This code is effectively the
+; same as the 64-bit version except the register model is
+; slightly different given all values must be 32-bit between
+; function calls. Thus the 64-bit return values are returned
+; in %ret0 and %ret1 vs just %ret0 as is done in 64-bit
+;
+;
+; This code is approximately 2x faster than the C version
+; for RSA/DSA.
+;
+; See http://devresource.hp.com/ for more details on the PA-RISC
+; architecture. Also see the book "PA-RISC 2.0 Architecture"
+; by Gerry Kane for information on the instruction set architecture.
+;
+; Code written by Chris Ruemmler (with some help from the HP C
+; compiler).
+;
+; The code compiles with HP's assembler
+;
+
+ .level 2.0N
+ .space $TEXT$
+ .subspa $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY
+
+;
+; Global Register definitions used for the routines.
+;
+; Some information about HP's runtime architecture for 32-bits.
+;
+; "Caller save" means the calling function must save the register
+; if it wants the register to be preserved.
+; "Callee save" means if a function uses the register, it must save
+; the value before using it.
+;
+; For the floating point registers
+;
+; "caller save" registers: fr4-fr11, fr22-fr31
+; "callee save" registers: fr12-fr21
+; "special" registers: fr0-fr3 (status and exception registers)
+;
+; For the integer registers
+; value zero : r0
+; "caller save" registers: r1,r19-r26
+; "callee save" registers: r3-r18
+; return register : r2 (rp)
+; return values ; r28,r29 (ret0,ret1)
+; Stack pointer ; r30 (sp)
+; millicode return ptr ; r31 (also a caller save register)
+
+
+;
+; Arguments to the routines
+;
+r_ptr .reg %r26
+a_ptr .reg %r25
+b_ptr .reg %r24
+num .reg %r24
+n .reg %r23
+
+;
+; Note that the "w" argument for bn_mul_add_words and bn_mul_words
+; is passed on the stack at a delta of -56 from the top of stack
+; as the routine is entered.
+;
+
+;
+; Globals used in some routines
+;
+
+top_overflow .reg %r23
+high_mask .reg %r22 ; value 0xffffffff80000000L
+
+
+;------------------------------------------------------------------------------
+;
+; bn_mul_add_words
+;
+;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr,
+; int num, BN_ULONG w)
+;
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg3 = num
+; -56(sp) = w
+;
+; Local register definitions
+;
+
+fm1 .reg %fr22
+fm .reg %fr23
+ht_temp .reg %fr24
+ht_temp_1 .reg %fr25
+lt_temp .reg %fr26
+lt_temp_1 .reg %fr27
+fm1_1 .reg %fr28
+fm_1 .reg %fr29
+
+fw_h .reg %fr7L
+fw_l .reg %fr7R
+fw .reg %fr7
+
+fht_0 .reg %fr8L
+flt_0 .reg %fr8R
+t_float_0 .reg %fr8
+
+fht_1 .reg %fr9L
+flt_1 .reg %fr9R
+t_float_1 .reg %fr9
+
+tmp_0 .reg %r31
+tmp_1 .reg %r21
+m_0 .reg %r20
+m_1 .reg %r19
+ht_0 .reg %r1
+ht_1 .reg %r3
+lt_0 .reg %r4
+lt_1 .reg %r5
+m1_0 .reg %r6
+m1_1 .reg %r7
+rp_val .reg %r8
+rp_val_1 .reg %r9
+
+bn_mul_add_words
+ .export bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN
+ .proc
+ .callinfo frame=128
+ .entry
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ NOP ; Needed to make the loop 16-byte aligned
+ NOP ; needed to make the loop 16-byte aligned
+
+ STD %r5,16(%sp) ; save r5
+ NOP
+ STD %r6,24(%sp) ; save r6
+ STD %r7,32(%sp) ; save r7
+
+ STD %r8,40(%sp) ; save r8
+ STD %r9,48(%sp) ; save r9
+ COPY %r0,%ret1 ; return 0 by default
+ DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32
+
+ CMPIB,>= 0,num,bn_mul_add_words_exit ; if (num <= 0) then exit
+ LDO 128(%sp),%sp ; bump stack
+
+ ;
+ ; The loop is unrolled twice, so if there is only 1 number
+ ; then go straight to the cleanup code.
+ ;
+ CMPIB,= 1,num,bn_mul_add_words_single_top
+ FLDD -184(%sp),fw ; (-56-128) load up w into fw (fw_h/fw_l)
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+ ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
+ ; two 32-bit mutiplies can be issued per cycle.
+ ;
+bn_mul_add_words_unroll2
+
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ LDD 0(r_ptr),rp_val ; rp[0]
+ LDD 8(r_ptr),rp_val_1 ; rp[1]
+
+ XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l
+ XMPYU fht_1,fw_l,fm1_1 ; m1[1] = fht_1*fw_l
+ FSTD fm1,-16(%sp) ; -16(sp) = m1[0]
+ FSTD fm1_1,-48(%sp) ; -48(sp) = m1[1]
+
+ XMPYU flt_0,fw_h,fm ; m[0] = flt_0*fw_h
+ XMPYU flt_1,fw_h,fm_1 ; m[1] = flt_1*fw_h
+ FSTD fm,-8(%sp) ; -8(sp) = m[0]
+ FSTD fm_1,-40(%sp) ; -40(sp) = m[1]
+
+ XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h
+ XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp_1 = fht_1*fw_h
+ FSTD ht_temp,-24(%sp) ; -24(sp) = ht_temp
+ FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht_temp_1
+
+ XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
+ XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l
+ FSTD lt_temp,-32(%sp) ; -32(sp) = lt_temp
+ FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt_temp_1
+
+ LDD -8(%sp),m_0 ; m[0]
+ LDD -40(%sp),m_1 ; m[1]
+ LDD -16(%sp),m1_0 ; m1[0]
+ LDD -48(%sp),m1_1 ; m1[1]
+
+ LDD -24(%sp),ht_0 ; ht[0]
+ LDD -56(%sp),ht_1 ; ht[1]
+ ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m[0] + m1[0];
+ ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m[1] + m1[1];
+
+ LDD -32(%sp),lt_0
+ LDD -64(%sp),lt_1
+ CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m[0] < m1[0])
+ ADD,L ht_0,top_overflow,ht_0 ; ht[0] += (1<<32)
+
+ CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m[1] < m1[1])
+ ADD,L ht_1,top_overflow,ht_1 ; ht[1] += (1<<32)
+ EXTRD,U tmp_0,31,32,m_0 ; m[0]>>32
+ DEPD,Z tmp_0,31,32,m1_0 ; m1[0] = m[0]<<32
+
+ EXTRD,U tmp_1,31,32,m_1 ; m[1]>>32
+ DEPD,Z tmp_1,31,32,m1_1 ; m1[1] = m[1]<<32
+ ADD,L ht_0,m_0,ht_0 ; ht[0]+= (m[0]>>32)
+ ADD,L ht_1,m_1,ht_1 ; ht[1]+= (m[1]>>32)
+
+ ADD lt_0,m1_0,lt_0 ; lt[0] = lt[0]+m1[0];
+ ADD,DC ht_0,%r0,ht_0 ; ht[0]++
+ ADD lt_1,m1_1,lt_1 ; lt[1] = lt[1]+m1[1];
+ ADD,DC ht_1,%r0,ht_1 ; ht[1]++
+
+ ADD %ret1,lt_0,lt_0 ; lt[0] = lt[0] + c;
+ ADD,DC ht_0,%r0,ht_0 ; ht[0]++
+ ADD lt_0,rp_val,lt_0 ; lt[0] = lt[0]+rp[0]
+ ADD,DC ht_0,%r0,ht_0 ; ht[0]++
+
+ LDO -2(num),num ; num = num - 2;
+ ADD ht_0,lt_1,lt_1 ; lt[1] = lt[1] + ht_0 (c);
+ ADD,DC ht_1,%r0,ht_1 ; ht[1]++
+ STD lt_0,0(r_ptr) ; rp[0] = lt[0]
+
+ ADD lt_1,rp_val_1,lt_1 ; lt[1] = lt[1]+rp[1]
+ ADD,DC ht_1,%r0,%ret1 ; ht[1]++
+ LDO 16(a_ptr),a_ptr ; a_ptr += 2
+
+ STD lt_1,8(r_ptr) ; rp[1] = lt[1]
+ CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do
+ LDO 16(r_ptr),r_ptr ; r_ptr += 2
+
+ CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one
+
+ ;
+ ; Top of loop aligned on 64-byte boundary
+ ;
+bn_mul_add_words_single_top
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ LDD 0(r_ptr),rp_val ; rp[0]
+ LDO 8(a_ptr),a_ptr ; a_ptr++
+ XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l
+ FSTD fm1,-16(%sp) ; -16(sp) = m1
+ XMPYU flt_0,fw_h,fm ; m = lt*fw_h
+ FSTD fm,-8(%sp) ; -8(sp) = m
+ XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h
+ FSTD ht_temp,-24(%sp) ; -24(sp) = ht
+ XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
+ FSTD lt_temp,-32(%sp) ; -32(sp) = lt
+
+ LDD -8(%sp),m_0
+ LDD -16(%sp),m1_0 ; m1 = temp1
+ ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1;
+ LDD -24(%sp),ht_0
+ LDD -32(%sp),lt_0
+
+ CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1)
+ ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
+
+ EXTRD,U tmp_0,31,32,m_0 ; m>>32
+ DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
+
+ ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
+ ADD lt_0,m1_0,tmp_0 ; tmp_0 = lt+m1;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+ ADD %ret1,tmp_0,lt_0 ; lt = lt + c;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+ ADD lt_0,rp_val,lt_0 ; lt = lt+rp[0]
+ ADD,DC ht_0,%r0,%ret1 ; ht++
+ STD lt_0,0(r_ptr) ; rp[0] = lt
+
+bn_mul_add_words_exit
+ .EXIT
+
+ EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1
+ LDD -80(%sp),%r9 ; restore r9
+ LDD -88(%sp),%r8 ; restore r8
+ LDD -96(%sp),%r7 ; restore r7
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3 ; restore r3
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+;
+; arg0 = rp
+; arg1 = ap
+; arg3 = num
+; w on stack at -56(sp)
+
+bn_mul_words
+ .proc
+ .callinfo frame=128
+ .entry
+ .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ NOP
+ STD %r5,16(%sp) ; save r5
+
+ STD %r6,24(%sp) ; save r6
+ STD %r7,32(%sp) ; save r7
+ COPY %r0,%ret1 ; return 0 by default
+ DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32
+
+ CMPIB,>= 0,num,bn_mul_words_exit
+ LDO 128(%sp),%sp ; bump stack
+
+ ;
+ ; See if only 1 word to do, thus just do cleanup
+ ;
+ CMPIB,= 1,num,bn_mul_words_single_top
+ FLDD -184(%sp),fw ; (-56-128) load up w into fw (fw_h/fw_l)
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+ ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
+ ; two 32-bit mutiplies can be issued per cycle.
+ ;
+bn_mul_words_unroll2
+
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l
+ XMPYU fht_1,fw_l,fm1_1 ; m1[1] = ht*fw_l
+
+ FSTD fm1,-16(%sp) ; -16(sp) = m1
+ FSTD fm1_1,-48(%sp) ; -48(sp) = m1
+ XMPYU flt_0,fw_h,fm ; m = lt*fw_h
+ XMPYU flt_1,fw_h,fm_1 ; m = lt*fw_h
+
+ FSTD fm,-8(%sp) ; -8(sp) = m
+ FSTD fm_1,-40(%sp) ; -40(sp) = m
+ XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h
+ XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp = ht*fw_h
+
+ FSTD ht_temp,-24(%sp) ; -24(sp) = ht
+ FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht
+ XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
+ XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l
+
+ FSTD lt_temp,-32(%sp) ; -32(sp) = lt
+ FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt
+ LDD -8(%sp),m_0
+ LDD -40(%sp),m_1
+
+ LDD -16(%sp),m1_0
+ LDD -48(%sp),m1_1
+ LDD -24(%sp),ht_0
+ LDD -56(%sp),ht_1
+
+ ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m + m1;
+ ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m + m1;
+ LDD -32(%sp),lt_0
+ LDD -64(%sp),lt_1
+
+ CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m < m1)
+ ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
+ CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m < m1)
+ ADD,L ht_1,top_overflow,ht_1 ; ht += (1<<32)
+
+ EXTRD,U tmp_0,31,32,m_0 ; m>>32
+ DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
+ EXTRD,U tmp_1,31,32,m_1 ; m>>32
+ DEPD,Z tmp_1,31,32,m1_1 ; m1 = m<<32
+
+ ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
+ ADD,L ht_1,m_1,ht_1 ; ht+= (m>>32)
+ ADD lt_0,m1_0,lt_0 ; lt = lt+m1;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ ADD lt_1,m1_1,lt_1 ; lt = lt+m1;
+ ADD,DC ht_1,%r0,ht_1 ; ht++
+ ADD %ret1,lt_0,lt_0 ; lt = lt + c (ret1);
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ ADD ht_0,lt_1,lt_1 ; lt = lt + c (ht_0)
+ ADD,DC ht_1,%r0,ht_1 ; ht++
+ STD lt_0,0(r_ptr) ; rp[0] = lt
+ STD lt_1,8(r_ptr) ; rp[1] = lt
+
+ COPY ht_1,%ret1 ; carry = ht
+ LDO -2(num),num ; num = num - 2;
+ LDO 16(a_ptr),a_ptr ; ap += 2
+ CMPIB,<= 2,num,bn_mul_words_unroll2
+ LDO 16(r_ptr),r_ptr ; rp++
+
+ CMPIB,=,N 0,num,bn_mul_words_exit ; are we done?
+
+ ;
+ ; Top of loop aligned on 64-byte boundary
+ ;
+bn_mul_words_single_top
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+
+ XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l
+ FSTD fm1,-16(%sp) ; -16(sp) = m1
+ XMPYU flt_0,fw_h,fm ; m = lt*fw_h
+ FSTD fm,-8(%sp) ; -8(sp) = m
+ XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h
+ FSTD ht_temp,-24(%sp) ; -24(sp) = ht
+ XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
+ FSTD lt_temp,-32(%sp) ; -32(sp) = lt
+
+ LDD -8(%sp),m_0
+ LDD -16(%sp),m1_0
+ ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1;
+ LDD -24(%sp),ht_0
+ LDD -32(%sp),lt_0
+
+ CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1)
+ ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
+
+ EXTRD,U tmp_0,31,32,m_0 ; m>>32
+ DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
+
+ ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
+ ADD lt_0,m1_0,lt_0 ; lt= lt+m1;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ ADD %ret1,lt_0,lt_0 ; lt = lt + c;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ COPY ht_0,%ret1 ; copy carry
+ STD lt_0,0(r_ptr) ; rp[0] = lt
+
+bn_mul_words_exit
+ .EXIT
+ EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1
+ LDD -96(%sp),%r7 ; restore r7
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3 ; restore r3
+ .PROCEND
+
+;----------------------------------------------------------------------------
+;
+;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = num
+;
+
+bn_sqr_words
+ .proc
+ .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ NOP
+ STD %r5,16(%sp) ; save r5
+
+ CMPIB,>= 0,num,bn_sqr_words_exit
+ LDO 128(%sp),%sp ; bump stack
+
+ ;
+ ; If only 1, the goto straight to cleanup
+ ;
+ CMPIB,= 1,num,bn_sqr_words_single_top
+ DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+
+bn_sqr_words_unroll2
+ FLDD 0(a_ptr),t_float_0 ; a[0]
+ FLDD 8(a_ptr),t_float_1 ; a[1]
+ XMPYU fht_0,flt_0,fm ; m[0]
+ XMPYU fht_1,flt_1,fm_1 ; m[1]
+
+ FSTD fm,-24(%sp) ; store m[0]
+ FSTD fm_1,-56(%sp) ; store m[1]
+ XMPYU flt_0,flt_0,lt_temp ; lt[0]
+ XMPYU flt_1,flt_1,lt_temp_1 ; lt[1]
+
+ FSTD lt_temp,-16(%sp) ; store lt[0]
+ FSTD lt_temp_1,-48(%sp) ; store lt[1]
+ XMPYU fht_0,fht_0,ht_temp ; ht[0]
+ XMPYU fht_1,fht_1,ht_temp_1 ; ht[1]
+
+ FSTD ht_temp,-8(%sp) ; store ht[0]
+ FSTD ht_temp_1,-40(%sp) ; store ht[1]
+ LDD -24(%sp),m_0
+ LDD -56(%sp),m_1
+
+ AND m_0,high_mask,tmp_0 ; m[0] & Mask
+ AND m_1,high_mask,tmp_1 ; m[1] & Mask
+ DEPD,Z m_0,30,31,m_0 ; m[0] << 32+1
+ DEPD,Z m_1,30,31,m_1 ; m[1] << 32+1
+
+ LDD -16(%sp),lt_0
+ LDD -48(%sp),lt_1
+ EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m[0]&Mask >> 32-1
+ EXTRD,U tmp_1,32,33,tmp_1 ; tmp_1 = m[1]&Mask >> 32-1
+
+ LDD -8(%sp),ht_0
+ LDD -40(%sp),ht_1
+ ADD,L ht_0,tmp_0,ht_0 ; ht[0] += tmp_0
+ ADD,L ht_1,tmp_1,ht_1 ; ht[1] += tmp_1
+
+ ADD lt_0,m_0,lt_0 ; lt = lt+m
+ ADD,DC ht_0,%r0,ht_0 ; ht[0]++
+ STD lt_0,0(r_ptr) ; rp[0] = lt[0]
+ STD ht_0,8(r_ptr) ; rp[1] = ht[1]
+
+ ADD lt_1,m_1,lt_1 ; lt = lt+m
+ ADD,DC ht_1,%r0,ht_1 ; ht[1]++
+ STD lt_1,16(r_ptr) ; rp[2] = lt[1]
+ STD ht_1,24(r_ptr) ; rp[3] = ht[1]
+
+ LDO -2(num),num ; num = num - 2;
+ LDO 16(a_ptr),a_ptr ; ap += 2
+ CMPIB,<= 2,num,bn_sqr_words_unroll2
+ LDO 32(r_ptr),r_ptr ; rp += 4
+
+ CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done?
+
+ ;
+ ; Top of loop aligned on 64-byte boundary
+ ;
+bn_sqr_words_single_top
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+
+ XMPYU fht_0,flt_0,fm ; m
+ FSTD fm,-24(%sp) ; store m
+
+ XMPYU flt_0,flt_0,lt_temp ; lt
+ FSTD lt_temp,-16(%sp) ; store lt
+
+ XMPYU fht_0,fht_0,ht_temp ; ht
+ FSTD ht_temp,-8(%sp) ; store ht
+
+ LDD -24(%sp),m_0 ; load m
+ AND m_0,high_mask,tmp_0 ; m & Mask
+ DEPD,Z m_0,30,31,m_0 ; m << 32+1
+ LDD -16(%sp),lt_0 ; lt
+
+ LDD -8(%sp),ht_0 ; ht
+ EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m&Mask >> 32-1
+ ADD m_0,lt_0,lt_0 ; lt = lt+m
+ ADD,L ht_0,tmp_0,ht_0 ; ht += tmp_0
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ STD lt_0,0(r_ptr) ; rp[0] = lt
+ STD ht_0,8(r_ptr) ; rp[1] = ht
+
+bn_sqr_words_exit
+ .EXIT
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = bp
+; arg3 = n
+
+t .reg %r22
+b .reg %r21
+l .reg %r20
+
+bn_add_words
+ .proc
+ .entry
+ .callinfo
+ .EXPORT bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .align 64
+
+ CMPIB,>= 0,n,bn_add_words_exit
+ COPY %r0,%ret1 ; return 0 by default
+
+ ;
+ ; If 2 or more numbers do the loop
+ ;
+ CMPIB,= 1,n,bn_add_words_single_top
+ NOP
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+bn_add_words_unroll2
+ LDD 0(a_ptr),t
+ LDD 0(b_ptr),b
+ ADD t,%ret1,t ; t = t+c;
+ ADD,DC %r0,%r0,%ret1 ; set c to carry
+ ADD t,b,l ; l = t + b[0]
+ ADD,DC %ret1,%r0,%ret1 ; c+= carry
+ STD l,0(r_ptr)
+
+ LDD 8(a_ptr),t
+ LDD 8(b_ptr),b
+ ADD t,%ret1,t ; t = t+c;
+ ADD,DC %r0,%r0,%ret1 ; set c to carry
+ ADD t,b,l ; l = t + b[0]
+ ADD,DC %ret1,%r0,%ret1 ; c+= carry
+ STD l,8(r_ptr)
+
+ LDO -2(n),n
+ LDO 16(a_ptr),a_ptr
+ LDO 16(b_ptr),b_ptr
+
+ CMPIB,<= 2,n,bn_add_words_unroll2
+ LDO 16(r_ptr),r_ptr
+
+ CMPIB,=,N 0,n,bn_add_words_exit ; are we done?
+
+bn_add_words_single_top
+ LDD 0(a_ptr),t
+ LDD 0(b_ptr),b
+
+ ADD t,%ret1,t ; t = t+c;
+ ADD,DC %r0,%r0,%ret1 ; set c to carry (could use CMPCLR??)
+ ADD t,b,l ; l = t + b[0]
+ ADD,DC %ret1,%r0,%ret1 ; c+= carry
+ STD l,0(r_ptr)
+
+bn_add_words_exit
+ .EXIT
+ BVE (%rp)
+ EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = bp
+; arg3 = n
+
+t1 .reg %r22
+t2 .reg %r21
+sub_tmp1 .reg %r20
+sub_tmp2 .reg %r19
+
+
+bn_sub_words
+ .proc
+ .callinfo
+ .EXPORT bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+
+ CMPIB,>= 0,n,bn_sub_words_exit
+ COPY %r0,%ret1 ; return 0 by default
+
+ ;
+ ; If 2 or more numbers do the loop
+ ;
+ CMPIB,= 1,n,bn_sub_words_single_top
+ NOP
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+bn_sub_words_unroll2
+ LDD 0(a_ptr),t1
+ LDD 0(b_ptr),t2
+ SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
+ SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c;
+
+ CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
+ LDO 1(%r0),sub_tmp2
+
+ CMPCLR,*= t1,t2,%r0
+ COPY sub_tmp2,%ret1
+ STD sub_tmp1,0(r_ptr)
+
+ LDD 8(a_ptr),t1
+ LDD 8(b_ptr),t2
+ SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
+ SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c;
+ CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
+ LDO 1(%r0),sub_tmp2
+
+ CMPCLR,*= t1,t2,%r0
+ COPY sub_tmp2,%ret1
+ STD sub_tmp1,8(r_ptr)
+
+ LDO -2(n),n
+ LDO 16(a_ptr),a_ptr
+ LDO 16(b_ptr),b_ptr
+
+ CMPIB,<= 2,n,bn_sub_words_unroll2
+ LDO 16(r_ptr),r_ptr
+
+ CMPIB,=,N 0,n,bn_sub_words_exit ; are we done?
+
+bn_sub_words_single_top
+ LDD 0(a_ptr),t1
+ LDD 0(b_ptr),t2
+ SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
+ SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c;
+ CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
+ LDO 1(%r0),sub_tmp2
+
+ CMPCLR,*= t1,t2,%r0
+ COPY sub_tmp2,%ret1
+
+ STD sub_tmp1,0(r_ptr)
+
+bn_sub_words_exit
+ .EXIT
+ BVE (%rp)
+ EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+;------------------------------------------------------------------------------
+;
+; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d)
+;
+; arg0 = h
+; arg1 = l
+; arg2 = d
+;
+; This is mainly just output from the HP C compiler.
+;
+;------------------------------------------------------------------------------
+bn_div_words
+ .PROC
+ .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN
+ .IMPORT BN_num_bits_word,CODE
+ ;--- not PIC .IMPORT __iob,DATA
+ ;--- not PIC .IMPORT fprintf,CODE
+ .IMPORT abort,CODE
+ .IMPORT $$div2U,MILLICODE
+ .CALLINFO CALLER,FRAME=144,ENTRY_GR=%r9,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
+ .ENTRY
+ STW %r2,-20(%r30) ;offset 0x8ec
+ STW,MA %r3,192(%r30) ;offset 0x8f0
+ STW %r4,-188(%r30) ;offset 0x8f4
+ DEPD %r5,31,32,%r6 ;offset 0x8f8
+ STD %r6,-184(%r30) ;offset 0x8fc
+ DEPD %r7,31,32,%r8 ;offset 0x900
+ STD %r8,-176(%r30) ;offset 0x904
+ STW %r9,-168(%r30) ;offset 0x908
+ LDD -248(%r30),%r3 ;offset 0x90c
+ COPY %r26,%r4 ;offset 0x910
+ COPY %r24,%r5 ;offset 0x914
+ DEPD %r25,31,32,%r4 ;offset 0x918
+ CMPB,*<> %r3,%r0,$0006000C ;offset 0x91c
+ DEPD %r23,31,32,%r5 ;offset 0x920
+ MOVIB,TR -1,%r29,$00060002 ;offset 0x924
+ EXTRD,U %r29,31,32,%r28 ;offset 0x928
+$0006002A
+ LDO -1(%r29),%r29 ;offset 0x92c
+ SUB %r23,%r7,%r23 ;offset 0x930
+$00060024
+ SUB %r4,%r31,%r25 ;offset 0x934
+ AND %r25,%r19,%r26 ;offset 0x938
+ CMPB,*<>,N %r0,%r26,$00060046 ;offset 0x93c
+ DEPD,Z %r25,31,32,%r20 ;offset 0x940
+ OR %r20,%r24,%r21 ;offset 0x944
+ CMPB,*<<,N %r21,%r23,$0006002A ;offset 0x948
+ SUB %r31,%r2,%r31 ;offset 0x94c
+$00060046
+$0006002E
+ DEPD,Z %r23,31,32,%r25 ;offset 0x950
+ EXTRD,U %r23,31,32,%r26 ;offset 0x954
+ AND %r25,%r19,%r24 ;offset 0x958
+ ADD,L %r31,%r26,%r31 ;offset 0x95c
+ CMPCLR,*>>= %r5,%r24,%r0 ;offset 0x960
+ LDO 1(%r31),%r31 ;offset 0x964
+$00060032
+ CMPB,*<<=,N %r31,%r4,$00060036 ;offset 0x968
+ LDO -1(%r29),%r29 ;offset 0x96c
+ ADD,L %r4,%r3,%r4 ;offset 0x970
+$00060036
+ ADDIB,=,N -1,%r8,$D0 ;offset 0x974
+ SUB %r5,%r24,%r28 ;offset 0x978
+$0006003A
+ SUB %r4,%r31,%r24 ;offset 0x97c
+ SHRPD %r24,%r28,32,%r4 ;offset 0x980
+ DEPD,Z %r29,31,32,%r9 ;offset 0x984
+ DEPD,Z %r28,31,32,%r5 ;offset 0x988
+$0006001C
+ EXTRD,U %r4,31,32,%r31 ;offset 0x98c
+ CMPB,*<>,N %r31,%r2,$00060020 ;offset 0x990
+ MOVB,TR %r6,%r29,$D1 ;offset 0x994
+ STD %r29,-152(%r30) ;offset 0x998
+$0006000C
+ EXTRD,U %r3,31,32,%r25 ;offset 0x99c
+ COPY %r3,%r26 ;offset 0x9a0
+ EXTRD,U %r3,31,32,%r9 ;offset 0x9a4
+ EXTRD,U %r4,31,32,%r8 ;offset 0x9a8
+ .CALL ARGW0=GR,ARGW1=GR,RTNVAL=GR ;in=25,26;out=28;
+ B,L BN_num_bits_word,%r2 ;offset 0x9ac
+ EXTRD,U %r5,31,32,%r7 ;offset 0x9b0
+ LDI 64,%r20 ;offset 0x9b4
+ DEPD %r7,31,32,%r5 ;offset 0x9b8
+ DEPD %r8,31,32,%r4 ;offset 0x9bc
+ DEPD %r9,31,32,%r3 ;offset 0x9c0
+ CMPB,= %r28,%r20,$00060012 ;offset 0x9c4
+ COPY %r28,%r24 ;offset 0x9c8
+ MTSARCM %r24 ;offset 0x9cc
+ DEPDI,Z -1,%sar,1,%r19 ;offset 0x9d0
+ CMPB,*>>,N %r4,%r19,$D2 ;offset 0x9d4
+$00060012
+ SUBI 64,%r24,%r31 ;offset 0x9d8
+ CMPCLR,*<< %r4,%r3,%r0 ;offset 0x9dc
+ SUB %r4,%r3,%r4 ;offset 0x9e0
+$00060016
+ CMPB,= %r31,%r0,$0006001A ;offset 0x9e4
+ COPY %r0,%r9 ;offset 0x9e8
+ MTSARCM %r31 ;offset 0x9ec
+ DEPD,Z %r3,%sar,64,%r3 ;offset 0x9f0
+ SUBI 64,%r31,%r26 ;offset 0x9f4
+ MTSAR %r26 ;offset 0x9f8
+ SHRPD %r4,%r5,%sar,%r4 ;offset 0x9fc
+ MTSARCM %r31 ;offset 0xa00
+ DEPD,Z %r5,%sar,64,%r5 ;offset 0xa04
+$0006001A
+ DEPDI,Z -1,31,32,%r19 ;offset 0xa08
+ AND %r3,%r19,%r29 ;offset 0xa0c
+ EXTRD,U %r29,31,32,%r2 ;offset 0xa10
+ DEPDI,Z -1,63,32,%r6 ;offset 0xa14
+ MOVIB,TR 2,%r8,$0006001C ;offset 0xa18
+ EXTRD,U %r3,63,32,%r7 ;offset 0xa1c
+$D2
+ ;--- not PIC ADDIL LR'__iob-$global$,%r27,%r1 ;offset 0xa20
+ ;--- not PIC LDIL LR'C$7,%r21 ;offset 0xa24
+ ;--- not PIC LDO RR'__iob-$global$+32(%r1),%r26 ;offset 0xa28
+ ;--- not PIC .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR ;in=24,25,26;out=28;
+ ;--- not PIC B,L fprintf,%r2 ;offset 0xa2c
+ ;--- not PIC LDO RR'C$7(%r21),%r25 ;offset 0xa30
+ .CALL ;
+ B,L abort,%r2 ;offset 0xa34
+ NOP ;offset 0xa38
+ B $D3 ;offset 0xa3c
+ LDW -212(%r30),%r2 ;offset 0xa40
+$00060020
+ COPY %r4,%r26 ;offset 0xa44
+ EXTRD,U %r4,31,32,%r25 ;offset 0xa48
+ COPY %r2,%r24 ;offset 0xa4c
+ .CALL ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
+ B,L $$div2U,%r31 ;offset 0xa50
+ EXTRD,U %r2,31,32,%r23 ;offset 0xa54
+ DEPD %r28,31,32,%r29 ;offset 0xa58
+$00060022
+ STD %r29,-152(%r30) ;offset 0xa5c
+$D1
+ AND %r5,%r19,%r24 ;offset 0xa60
+ EXTRD,U %r24,31,32,%r24 ;offset 0xa64
+ STW %r2,-160(%r30) ;offset 0xa68
+ STW %r7,-128(%r30) ;offset 0xa6c
+ FLDD -152(%r30),%fr4 ;offset 0xa70
+ FLDD -152(%r30),%fr7 ;offset 0xa74
+ FLDW -160(%r30),%fr8L ;offset 0xa78
+ FLDW -128(%r30),%fr5L ;offset 0xa7c
+ XMPYU %fr8L,%fr7L,%fr10 ;offset 0xa80
+ FSTD %fr10,-136(%r30) ;offset 0xa84
+ XMPYU %fr8L,%fr7R,%fr22 ;offset 0xa88
+ FSTD %fr22,-144(%r30) ;offset 0xa8c
+ XMPYU %fr5L,%fr4L,%fr11 ;offset 0xa90
+ XMPYU %fr5L,%fr4R,%fr23 ;offset 0xa94
+ FSTD %fr11,-112(%r30) ;offset 0xa98
+ FSTD %fr23,-120(%r30) ;offset 0xa9c
+ LDD -136(%r30),%r28 ;offset 0xaa0
+ DEPD,Z %r28,31,32,%r31 ;offset 0xaa4
+ LDD -144(%r30),%r20 ;offset 0xaa8
+ ADD,L %r20,%r31,%r31 ;offset 0xaac
+ LDD -112(%r30),%r22 ;offset 0xab0
+ DEPD,Z %r22,31,32,%r22 ;offset 0xab4
+ LDD -120(%r30),%r21 ;offset 0xab8
+ B $00060024 ;offset 0xabc
+ ADD,L %r21,%r22,%r23 ;offset 0xac0
+$D0
+ OR %r9,%r29,%r29 ;offset 0xac4
+$00060040
+ EXTRD,U %r29,31,32,%r28 ;offset 0xac8
+$00060002
+$L2
+ LDW -212(%r30),%r2 ;offset 0xacc
+$D3
+ LDW -168(%r30),%r9 ;offset 0xad0
+ LDD -176(%r30),%r8 ;offset 0xad4
+ EXTRD,U %r8,31,32,%r7 ;offset 0xad8
+ LDD -184(%r30),%r6 ;offset 0xadc
+ EXTRD,U %r6,31,32,%r5 ;offset 0xae0
+ LDW -188(%r30),%r4 ;offset 0xae4
+ BVE (%r2) ;offset 0xae8
+ .EXIT
+ LDW,MB -192(%r30),%r3 ;offset 0xaec
+ .PROCEND ;in=23,25;out=28,29;fpin=105,107;
+
+
+
+
+;----------------------------------------------------------------------------
+;
+; Registers to hold 64-bit values to manipulate. The "L" part
+; of the register corresponds to the upper 32-bits, while the "R"
+; part corresponds to the lower 32-bits
+;
+; Note, that when using b6 and b7, the code must save these before
+; using them because they are callee save registers
+;
+;
+; Floating point registers to use to save values that
+; are manipulated. These don't collide with ftemp1-6 and
+; are all caller save registers
+;
+a0 .reg %fr22
+a0L .reg %fr22L
+a0R .reg %fr22R
+
+a1 .reg %fr23
+a1L .reg %fr23L
+a1R .reg %fr23R
+
+a2 .reg %fr24
+a2L .reg %fr24L
+a2R .reg %fr24R
+
+a3 .reg %fr25
+a3L .reg %fr25L
+a3R .reg %fr25R
+
+a4 .reg %fr26
+a4L .reg %fr26L
+a4R .reg %fr26R
+
+a5 .reg %fr27
+a5L .reg %fr27L
+a5R .reg %fr27R
+
+a6 .reg %fr28
+a6L .reg %fr28L
+a6R .reg %fr28R
+
+a7 .reg %fr29
+a7L .reg %fr29L
+a7R .reg %fr29R
+
+b0 .reg %fr30
+b0L .reg %fr30L
+b0R .reg %fr30R
+
+b1 .reg %fr31
+b1L .reg %fr31L
+b1R .reg %fr31R
+
+;
+; Temporary floating point variables, these are all caller save
+; registers
+;
+ftemp1 .reg %fr4
+ftemp2 .reg %fr5
+ftemp3 .reg %fr6
+ftemp4 .reg %fr7
+
+;
+; The B set of registers when used.
+;
+
+b2 .reg %fr8
+b2L .reg %fr8L
+b2R .reg %fr8R
+
+b3 .reg %fr9
+b3L .reg %fr9L
+b3R .reg %fr9R
+
+b4 .reg %fr10
+b4L .reg %fr10L
+b4R .reg %fr10R
+
+b5 .reg %fr11
+b5L .reg %fr11L
+b5R .reg %fr11R
+
+b6 .reg %fr12
+b6L .reg %fr12L
+b6R .reg %fr12R
+
+b7 .reg %fr13
+b7L .reg %fr13L
+b7R .reg %fr13R
+
+c1 .reg %r21 ; only reg
+temp1 .reg %r20 ; only reg
+temp2 .reg %r19 ; only reg
+temp3 .reg %r31 ; only reg
+
+m1 .reg %r28
+c2 .reg %r23
+high_one .reg %r1
+ht .reg %r6
+lt .reg %r5
+m .reg %r4
+c3 .reg %r3
+
+SQR_ADD_C .macro A0L,A0R,C1,C2,C3
+ XMPYU A0L,A0R,ftemp1 ; m
+ FSTD ftemp1,-24(%sp) ; store m
+
+ XMPYU A0R,A0R,ftemp2 ; lt
+ FSTD ftemp2,-16(%sp) ; store lt
+
+ XMPYU A0L,A0L,ftemp3 ; ht
+ FSTD ftemp3,-8(%sp) ; store ht
+
+ LDD -24(%sp),m ; load m
+ AND m,high_mask,temp2 ; m & Mask
+ DEPD,Z m,30,31,temp3 ; m << 32+1
+ LDD -16(%sp),lt ; lt
+
+ LDD -8(%sp),ht ; ht
+ EXTRD,U temp2,32,33,temp1 ; temp1 = m&Mask >> 32-1
+ ADD temp3,lt,lt ; lt = lt+m
+ ADD,L ht,temp1,ht ; ht += temp1
+ ADD,DC ht,%r0,ht ; ht++
+
+ ADD C1,lt,C1 ; c1=c1+lt
+ ADD,DC ht,%r0,ht ; ht++
+
+ ADD C2,ht,C2 ; c2=c2+ht
+ ADD,DC C3,%r0,C3 ; c3++
+.endm
+
+SQR_ADD_C2 .macro A0L,A0R,A1L,A1R,C1,C2,C3
+ XMPYU A0L,A1R,ftemp1 ; m1 = bl*ht
+ FSTD ftemp1,-16(%sp) ;
+ XMPYU A0R,A1L,ftemp2 ; m = bh*lt
+ FSTD ftemp2,-8(%sp) ;
+ XMPYU A0R,A1R,ftemp3 ; lt = bl*lt
+ FSTD ftemp3,-32(%sp)
+ XMPYU A0L,A1L,ftemp4 ; ht = bh*ht
+ FSTD ftemp4,-24(%sp) ;
+
+ LDD -8(%sp),m ; r21 = m
+ LDD -16(%sp),m1 ; r19 = m1
+ ADD,L m,m1,m ; m+m1
+
+ DEPD,Z m,31,32,temp3 ; (m+m1<<32)
+ LDD -24(%sp),ht ; r24 = ht
+
+ CMPCLR,*>>= m,m1,%r0 ; if (m < m1)
+ ADD,L ht,high_one,ht ; ht+=high_one
+
+ EXTRD,U m,31,32,temp1 ; m >> 32
+ LDD -32(%sp),lt ; lt
+ ADD,L ht,temp1,ht ; ht+= m>>32
+ ADD lt,temp3,lt ; lt = lt+m1
+ ADD,DC ht,%r0,ht ; ht++
+
+ ADD ht,ht,ht ; ht=ht+ht;
+ ADD,DC C3,%r0,C3 ; add in carry (c3++)
+
+ ADD lt,lt,lt ; lt=lt+lt;
+ ADD,DC ht,%r0,ht ; add in carry (ht++)
+
+ ADD C1,lt,C1 ; c1=c1+lt
+ ADD,DC,*NUV ht,%r0,ht ; add in carry (ht++)
+ LDO 1(C3),C3 ; bump c3 if overflow,nullify otherwise
+
+ ADD C2,ht,C2 ; c2 = c2 + ht
+ ADD,DC C3,%r0,C3 ; add in carry (c3++)
+.endm
+
+;
+;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+; arg0 = r_ptr
+; arg1 = a_ptr
+;
+
+bn_sqr_comba8
+ .PROC
+ .CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .ENTRY
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+
+ ;
+ ; Zero out carries
+ ;
+ COPY %r0,c1
+ COPY %r0,c2
+ COPY %r0,c3
+
+ LDO 128(%sp),%sp ; bump stack
+ DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
+ DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
+
+ ;
+ ; Load up all of the values we are going to use
+ ;
+ FLDD 0(a_ptr),a0
+ FLDD 8(a_ptr),a1
+ FLDD 16(a_ptr),a2
+ FLDD 24(a_ptr),a3
+ FLDD 32(a_ptr),a4
+ FLDD 40(a_ptr),a5
+ FLDD 48(a_ptr),a6
+ FLDD 56(a_ptr),a7
+
+ SQR_ADD_C a0L,a0R,c1,c2,c3
+ STD c1,0(r_ptr) ; r[0] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
+ STD c2,8(r_ptr) ; r[1] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C a1L,a1R,c3,c1,c2
+ SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
+ STD c3,16(r_ptr) ; r[2] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
+ SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
+ STD c1,24(r_ptr) ; r[3] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C a2L,a2R,c2,c3,c1
+ SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
+ SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1
+ STD c2,32(r_ptr) ; r[4] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2
+ SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2
+ SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
+ STD c3,40(r_ptr) ; r[5] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C a3L,a3R,c1,c2,c3
+ SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3
+ SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3
+ SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3
+ STD c1,48(r_ptr) ; r[6] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1
+ SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1
+ SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1
+ SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1
+ STD c2,56(r_ptr) ; r[7] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C a4L,a4R,c3,c1,c2
+ SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2
+ SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2
+ SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2
+ STD c3,64(r_ptr) ; r[8] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3
+ SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3
+ SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3
+ STD c1,72(r_ptr) ; r[9] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C a5L,a5R,c2,c3,c1
+ SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1
+ SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1
+ STD c2,80(r_ptr) ; r[10] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2
+ SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2
+ STD c3,88(r_ptr) ; r[11] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C a6L,a6R,c1,c2,c3
+ SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3
+ STD c1,96(r_ptr) ; r[12] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1
+ STD c2,104(r_ptr) ; r[13] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C a7L,a7R,c3,c1,c2
+ STD c3, 112(r_ptr) ; r[14] = c3
+ STD c1, 120(r_ptr) ; r[15] = c1
+
+ .EXIT
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+
+ .PROCEND
+
+;-----------------------------------------------------------------------------
+;
+;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+; arg0 = r_ptr
+; arg1 = a_ptr
+;
+
+bn_sqr_comba4
+ .proc
+ .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+
+ ;
+ ; Zero out carries
+ ;
+ COPY %r0,c1
+ COPY %r0,c2
+ COPY %r0,c3
+
+ LDO 128(%sp),%sp ; bump stack
+ DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
+ DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
+
+ ;
+ ; Load up all of the values we are going to use
+ ;
+ FLDD 0(a_ptr),a0
+ FLDD 8(a_ptr),a1
+ FLDD 16(a_ptr),a2
+ FLDD 24(a_ptr),a3
+ FLDD 32(a_ptr),a4
+ FLDD 40(a_ptr),a5
+ FLDD 48(a_ptr),a6
+ FLDD 56(a_ptr),a7
+
+ SQR_ADD_C a0L,a0R,c1,c2,c3
+
+ STD c1,0(r_ptr) ; r[0] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
+
+ STD c2,8(r_ptr) ; r[1] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C a1L,a1R,c3,c1,c2
+ SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
+
+ STD c3,16(r_ptr) ; r[2] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
+ SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
+
+ STD c1,24(r_ptr) ; r[3] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C a2L,a2R,c2,c3,c1
+ SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
+
+ STD c2,32(r_ptr) ; r[4] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
+ STD c3,40(r_ptr) ; r[5] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C a3L,a3R,c1,c2,c3
+ STD c1,48(r_ptr) ; r[6] = c1;
+ STD c2,56(r_ptr) ; r[7] = c2;
+
+ .EXIT
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+
+ .PROCEND
+
+
+;---------------------------------------------------------------------------
+
+MUL_ADD_C .macro A0L,A0R,B0L,B0R,C1,C2,C3
+ XMPYU A0L,B0R,ftemp1 ; m1 = bl*ht
+ FSTD ftemp1,-16(%sp) ;
+ XMPYU A0R,B0L,ftemp2 ; m = bh*lt
+ FSTD ftemp2,-8(%sp) ;
+ XMPYU A0R,B0R,ftemp3 ; lt = bl*lt
+ FSTD ftemp3,-32(%sp)
+ XMPYU A0L,B0L,ftemp4 ; ht = bh*ht
+ FSTD ftemp4,-24(%sp) ;
+
+ LDD -8(%sp),m ; r21 = m
+ LDD -16(%sp),m1 ; r19 = m1
+ ADD,L m,m1,m ; m+m1
+
+ DEPD,Z m,31,32,temp3 ; (m+m1<<32)
+ LDD -24(%sp),ht ; r24 = ht
+
+ CMPCLR,*>>= m,m1,%r0 ; if (m < m1)
+ ADD,L ht,high_one,ht ; ht+=high_one
+
+ EXTRD,U m,31,32,temp1 ; m >> 32
+ LDD -32(%sp),lt ; lt
+ ADD,L ht,temp1,ht ; ht+= m>>32
+ ADD lt,temp3,lt ; lt = lt+m1
+ ADD,DC ht,%r0,ht ; ht++
+
+ ADD C1,lt,C1 ; c1=c1+lt
+ ADD,DC ht,%r0,ht ; bump c3 if overflow,nullify otherwise
+
+ ADD C2,ht,C2 ; c2 = c2 + ht
+ ADD,DC C3,%r0,C3 ; add in carry (c3++)
+.endm
+
+
+;
+;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = b_ptr
+;
+
+bn_mul_comba8
+ .proc
+ .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+ FSTD %fr12,32(%sp) ; save r6
+ FSTD %fr13,40(%sp) ; save r7
+
+ ;
+ ; Zero out carries
+ ;
+ COPY %r0,c1
+ COPY %r0,c2
+ COPY %r0,c3
+
+ LDO 128(%sp),%sp ; bump stack
+ DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
+
+ ;
+ ; Load up all of the values we are going to use
+ ;
+ FLDD 0(a_ptr),a0
+ FLDD 8(a_ptr),a1
+ FLDD 16(a_ptr),a2
+ FLDD 24(a_ptr),a3
+ FLDD 32(a_ptr),a4
+ FLDD 40(a_ptr),a5
+ FLDD 48(a_ptr),a6
+ FLDD 56(a_ptr),a7
+
+ FLDD 0(b_ptr),b0
+ FLDD 8(b_ptr),b1
+ FLDD 16(b_ptr),b2
+ FLDD 24(b_ptr),b3
+ FLDD 32(b_ptr),b4
+ FLDD 40(b_ptr),b5
+ FLDD 48(b_ptr),b6
+ FLDD 56(b_ptr),b7
+
+ MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
+ STD c1,0(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
+ STD c2,8(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
+ MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
+ MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
+ STD c3,16(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
+ MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
+ MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
+ MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
+ STD c1,24(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1
+ MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
+ MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1
+ STD c2,32(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2
+ MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2
+ MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
+ MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
+ MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2
+ MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2
+ STD c3,40(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3
+ MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3
+ MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3
+ MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
+ MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3
+ MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3
+ MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3
+ STD c1,48(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1
+ MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1
+ MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1
+ MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1
+ MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1
+ MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1
+ STD c2,56(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2
+ MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2
+ MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2
+ MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2
+ MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2
+ MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2
+ MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2
+ STD c3,64(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3
+ MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3
+ MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3
+ MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3
+ MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3
+ MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3
+ STD c1,72(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1
+ MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1
+ MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1
+ MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1
+ MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1
+ STD c2,80(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2
+ MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2
+ MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2
+ MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2
+ STD c3,88(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3
+ MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3
+ MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3
+ STD c1,96(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1
+ MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1
+ STD c2,104(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2
+ STD c3,112(r_ptr)
+ STD c1,120(r_ptr)
+
+ .EXIT
+ FLDD -88(%sp),%fr13
+ FLDD -96(%sp),%fr12
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+
+ .PROCEND
+
+;-----------------------------------------------------------------------------
+;
+;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = b_ptr
+;
+
+bn_mul_comba4
+ .proc
+ .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+ FSTD %fr12,32(%sp) ; save r6
+ FSTD %fr13,40(%sp) ; save r7
+
+ ;
+ ; Zero out carries
+ ;
+ COPY %r0,c1
+ COPY %r0,c2
+ COPY %r0,c3
+
+ LDO 128(%sp),%sp ; bump stack
+ DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
+
+ ;
+ ; Load up all of the values we are going to use
+ ;
+ FLDD 0(a_ptr),a0
+ FLDD 8(a_ptr),a1
+ FLDD 16(a_ptr),a2
+ FLDD 24(a_ptr),a3
+
+ FLDD 0(b_ptr),b0
+ FLDD 8(b_ptr),b1
+ FLDD 16(b_ptr),b2
+ FLDD 24(b_ptr),b3
+
+ MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
+ STD c1,0(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
+ STD c2,8(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
+ MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
+ MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
+ STD c3,16(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
+ MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
+ MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
+ MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
+ STD c1,24(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
+ STD c2,32(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
+ MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
+ STD c3,40(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
+ STD c1,48(r_ptr)
+ STD c2,56(r_ptr)
+
+ .EXIT
+ FLDD -88(%sp),%fr13
+ FLDD -96(%sp),%fr12
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+
+ .PROCEND
+
+
+;--- not PIC .SPACE $TEXT$
+;--- not PIC .SUBSPA $CODE$
+;--- not PIC .SPACE $PRIVATE$,SORT=16
+;--- not PIC .IMPORT $global$,DATA
+;--- not PIC .SPACE $TEXT$
+;--- not PIC .SUBSPA $CODE$
+;--- not PIC .SUBSPA $LIT$,ACCESS=0x2c
+;--- not PIC C$7
+;--- not PIC .ALIGN 8
+;--- not PIC .STRINGZ "Division would overflow (%d)\n"
+ .END
diff --git a/openssl/trunk/crypto/bn/asm/pa-risc2W.s b/openssl/trunk/crypto/bn/asm/pa-risc2W.s
new file mode 100644
index 00000000..a9954575
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/pa-risc2W.s
@@ -0,0 +1,1605 @@
+;
+; PA-RISC 64-bit implementation of bn_asm code
+;
+; This code is approximately 2x faster than the C version
+; for RSA/DSA.
+;
+; See http://devresource.hp.com/ for more details on the PA-RISC
+; architecture. Also see the book "PA-RISC 2.0 Architecture"
+; by Gerry Kane for information on the instruction set architecture.
+;
+; Code written by Chris Ruemmler (with some help from the HP C
+; compiler).
+;
+; The code compiles with HP's assembler
+;
+
+ .level 2.0W
+ .space $TEXT$
+ .subspa $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY
+
+;
+; Global Register definitions used for the routines.
+;
+; Some information about HP's runtime architecture for 64-bits.
+;
+; "Caller save" means the calling function must save the register
+; if it wants the register to be preserved.
+; "Callee save" means if a function uses the register, it must save
+; the value before using it.
+;
+; For the floating point registers
+;
+; "caller save" registers: fr4-fr11, fr22-fr31
+; "callee save" registers: fr12-fr21
+; "special" registers: fr0-fr3 (status and exception registers)
+;
+; For the integer registers
+; value zero : r0
+; "caller save" registers: r1,r19-r26
+; "callee save" registers: r3-r18
+; return register : r2 (rp)
+; return values ; r28 (ret0,ret1)
+; Stack pointer ; r30 (sp)
+; global data pointer ; r27 (dp)
+; argument pointer ; r29 (ap)
+; millicode return ptr ; r31 (also a caller save register)
+
+
+;
+; Arguments to the routines
+;
+r_ptr .reg %r26
+a_ptr .reg %r25
+b_ptr .reg %r24
+num .reg %r24
+w .reg %r23
+n .reg %r23
+
+
+;
+; Globals used in some routines
+;
+
+top_overflow .reg %r29
+high_mask .reg %r22 ; value 0xffffffff80000000L
+
+
+;------------------------------------------------------------------------------
+;
+; bn_mul_add_words
+;
+;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr,
+; int num, BN_ULONG w)
+;
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = num
+; arg3 = w
+;
+; Local register definitions
+;
+
+fm1 .reg %fr22
+fm .reg %fr23
+ht_temp .reg %fr24
+ht_temp_1 .reg %fr25
+lt_temp .reg %fr26
+lt_temp_1 .reg %fr27
+fm1_1 .reg %fr28
+fm_1 .reg %fr29
+
+fw_h .reg %fr7L
+fw_l .reg %fr7R
+fw .reg %fr7
+
+fht_0 .reg %fr8L
+flt_0 .reg %fr8R
+t_float_0 .reg %fr8
+
+fht_1 .reg %fr9L
+flt_1 .reg %fr9R
+t_float_1 .reg %fr9
+
+tmp_0 .reg %r31
+tmp_1 .reg %r21
+m_0 .reg %r20
+m_1 .reg %r19
+ht_0 .reg %r1
+ht_1 .reg %r3
+lt_0 .reg %r4
+lt_1 .reg %r5
+m1_0 .reg %r6
+m1_1 .reg %r7
+rp_val .reg %r8
+rp_val_1 .reg %r9
+
+bn_mul_add_words
+ .export bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN
+ .proc
+ .callinfo frame=128
+ .entry
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ NOP ; Needed to make the loop 16-byte aligned
+ NOP ; Needed to make the loop 16-byte aligned
+
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+ STD %r7,32(%sp) ; save r7
+ STD %r8,40(%sp) ; save r8
+
+ STD %r9,48(%sp) ; save r9
+ COPY %r0,%ret0 ; return 0 by default
+ DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32
+ STD w,56(%sp) ; store w on stack
+
+ CMPIB,>= 0,num,bn_mul_add_words_exit ; if (num <= 0) then exit
+ LDO 128(%sp),%sp ; bump stack
+
+ ;
+ ; The loop is unrolled twice, so if there is only 1 number
+ ; then go straight to the cleanup code.
+ ;
+ CMPIB,= 1,num,bn_mul_add_words_single_top
+ FLDD -72(%sp),fw ; load up w into fp register fw (fw_h/fw_l)
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+ ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
+ ; two 32-bit mutiplies can be issued per cycle.
+ ;
+bn_mul_add_words_unroll2
+
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ LDD 0(r_ptr),rp_val ; rp[0]
+ LDD 8(r_ptr),rp_val_1 ; rp[1]
+
+ XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l
+ XMPYU fht_1,fw_l,fm1_1 ; m1[1] = fht_1*fw_l
+ FSTD fm1,-16(%sp) ; -16(sp) = m1[0]
+ FSTD fm1_1,-48(%sp) ; -48(sp) = m1[1]
+
+ XMPYU flt_0,fw_h,fm ; m[0] = flt_0*fw_h
+ XMPYU flt_1,fw_h,fm_1 ; m[1] = flt_1*fw_h
+ FSTD fm,-8(%sp) ; -8(sp) = m[0]
+ FSTD fm_1,-40(%sp) ; -40(sp) = m[1]
+
+ XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h
+ XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp_1 = fht_1*fw_h
+ FSTD ht_temp,-24(%sp) ; -24(sp) = ht_temp
+ FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht_temp_1
+
+ XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
+ XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l
+ FSTD lt_temp,-32(%sp) ; -32(sp) = lt_temp
+ FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt_temp_1
+
+ LDD -8(%sp),m_0 ; m[0]
+ LDD -40(%sp),m_1 ; m[1]
+ LDD -16(%sp),m1_0 ; m1[0]
+ LDD -48(%sp),m1_1 ; m1[1]
+
+ LDD -24(%sp),ht_0 ; ht[0]
+ LDD -56(%sp),ht_1 ; ht[1]
+ ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m[0] + m1[0];
+ ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m[1] + m1[1];
+
+ LDD -32(%sp),lt_0
+ LDD -64(%sp),lt_1
+ CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m[0] < m1[0])
+ ADD,L ht_0,top_overflow,ht_0 ; ht[0] += (1<<32)
+
+ CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m[1] < m1[1])
+ ADD,L ht_1,top_overflow,ht_1 ; ht[1] += (1<<32)
+ EXTRD,U tmp_0,31,32,m_0 ; m[0]>>32
+ DEPD,Z tmp_0,31,32,m1_0 ; m1[0] = m[0]<<32
+
+ EXTRD,U tmp_1,31,32,m_1 ; m[1]>>32
+ DEPD,Z tmp_1,31,32,m1_1 ; m1[1] = m[1]<<32
+ ADD,L ht_0,m_0,ht_0 ; ht[0]+= (m[0]>>32)
+ ADD,L ht_1,m_1,ht_1 ; ht[1]+= (m[1]>>32)
+
+ ADD lt_0,m1_0,lt_0 ; lt[0] = lt[0]+m1[0];
+ ADD,DC ht_0,%r0,ht_0 ; ht[0]++
+ ADD lt_1,m1_1,lt_1 ; lt[1] = lt[1]+m1[1];
+ ADD,DC ht_1,%r0,ht_1 ; ht[1]++
+
+ ADD %ret0,lt_0,lt_0 ; lt[0] = lt[0] + c;
+ ADD,DC ht_0,%r0,ht_0 ; ht[0]++
+ ADD lt_0,rp_val,lt_0 ; lt[0] = lt[0]+rp[0]
+ ADD,DC ht_0,%r0,ht_0 ; ht[0]++
+
+ LDO -2(num),num ; num = num - 2;
+ ADD ht_0,lt_1,lt_1 ; lt[1] = lt[1] + ht_0 (c);
+ ADD,DC ht_1,%r0,ht_1 ; ht[1]++
+ STD lt_0,0(r_ptr) ; rp[0] = lt[0]
+
+ ADD lt_1,rp_val_1,lt_1 ; lt[1] = lt[1]+rp[1]
+ ADD,DC ht_1,%r0,%ret0 ; ht[1]++
+ LDO 16(a_ptr),a_ptr ; a_ptr += 2
+
+ STD lt_1,8(r_ptr) ; rp[1] = lt[1]
+ CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do
+ LDO 16(r_ptr),r_ptr ; r_ptr += 2
+
+ CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one
+
+ ;
+ ; Top of loop aligned on 64-byte boundary
+ ;
+bn_mul_add_words_single_top
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ LDD 0(r_ptr),rp_val ; rp[0]
+ LDO 8(a_ptr),a_ptr ; a_ptr++
+ XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l
+ FSTD fm1,-16(%sp) ; -16(sp) = m1
+ XMPYU flt_0,fw_h,fm ; m = lt*fw_h
+ FSTD fm,-8(%sp) ; -8(sp) = m
+ XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h
+ FSTD ht_temp,-24(%sp) ; -24(sp) = ht
+ XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
+ FSTD lt_temp,-32(%sp) ; -32(sp) = lt
+
+ LDD -8(%sp),m_0
+ LDD -16(%sp),m1_0 ; m1 = temp1
+ ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1;
+ LDD -24(%sp),ht_0
+ LDD -32(%sp),lt_0
+
+ CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1)
+ ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
+
+ EXTRD,U tmp_0,31,32,m_0 ; m>>32
+ DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
+
+ ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
+ ADD lt_0,m1_0,tmp_0 ; tmp_0 = lt+m1;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+ ADD %ret0,tmp_0,lt_0 ; lt = lt + c;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+ ADD lt_0,rp_val,lt_0 ; lt = lt+rp[0]
+ ADD,DC ht_0,%r0,%ret0 ; ht++
+ STD lt_0,0(r_ptr) ; rp[0] = lt
+
+bn_mul_add_words_exit
+ .EXIT
+ LDD -80(%sp),%r9 ; restore r9
+ LDD -88(%sp),%r8 ; restore r8
+ LDD -96(%sp),%r7 ; restore r7
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3 ; restore r3
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = num
+; arg3 = w
+
+bn_mul_words
+ .proc
+ .callinfo frame=128
+ .entry
+ .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+
+ STD %r7,32(%sp) ; save r7
+ COPY %r0,%ret0 ; return 0 by default
+ DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32
+ STD w,56(%sp) ; w on stack
+
+ CMPIB,>= 0,num,bn_mul_words_exit
+ LDO 128(%sp),%sp ; bump stack
+
+ ;
+ ; See if only 1 word to do, thus just do cleanup
+ ;
+ CMPIB,= 1,num,bn_mul_words_single_top
+ FLDD -72(%sp),fw ; load up w into fp register fw (fw_h/fw_l)
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+ ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus
+ ; two 32-bit mutiplies can be issued per cycle.
+ ;
+bn_mul_words_unroll2
+
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+ XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l
+ XMPYU fht_1,fw_l,fm1_1 ; m1[1] = ht*fw_l
+
+ FSTD fm1,-16(%sp) ; -16(sp) = m1
+ FSTD fm1_1,-48(%sp) ; -48(sp) = m1
+ XMPYU flt_0,fw_h,fm ; m = lt*fw_h
+ XMPYU flt_1,fw_h,fm_1 ; m = lt*fw_h
+
+ FSTD fm,-8(%sp) ; -8(sp) = m
+ FSTD fm_1,-40(%sp) ; -40(sp) = m
+ XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h
+ XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp = ht*fw_h
+
+ FSTD ht_temp,-24(%sp) ; -24(sp) = ht
+ FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht
+ XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
+ XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l
+
+ FSTD lt_temp,-32(%sp) ; -32(sp) = lt
+ FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt
+ LDD -8(%sp),m_0
+ LDD -40(%sp),m_1
+
+ LDD -16(%sp),m1_0
+ LDD -48(%sp),m1_1
+ LDD -24(%sp),ht_0
+ LDD -56(%sp),ht_1
+
+ ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m + m1;
+ ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m + m1;
+ LDD -32(%sp),lt_0
+ LDD -64(%sp),lt_1
+
+ CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m < m1)
+ ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
+ CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m < m1)
+ ADD,L ht_1,top_overflow,ht_1 ; ht += (1<<32)
+
+ EXTRD,U tmp_0,31,32,m_0 ; m>>32
+ DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
+ EXTRD,U tmp_1,31,32,m_1 ; m>>32
+ DEPD,Z tmp_1,31,32,m1_1 ; m1 = m<<32
+
+ ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
+ ADD,L ht_1,m_1,ht_1 ; ht+= (m>>32)
+ ADD lt_0,m1_0,lt_0 ; lt = lt+m1;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ ADD lt_1,m1_1,lt_1 ; lt = lt+m1;
+ ADD,DC ht_1,%r0,ht_1 ; ht++
+ ADD %ret0,lt_0,lt_0 ; lt = lt + c (ret0);
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ ADD ht_0,lt_1,lt_1 ; lt = lt + c (ht_0)
+ ADD,DC ht_1,%r0,ht_1 ; ht++
+ STD lt_0,0(r_ptr) ; rp[0] = lt
+ STD lt_1,8(r_ptr) ; rp[1] = lt
+
+ COPY ht_1,%ret0 ; carry = ht
+ LDO -2(num),num ; num = num - 2;
+ LDO 16(a_ptr),a_ptr ; ap += 2
+ CMPIB,<= 2,num,bn_mul_words_unroll2
+ LDO 16(r_ptr),r_ptr ; rp++
+
+ CMPIB,=,N 0,num,bn_mul_words_exit ; are we done?
+
+ ;
+ ; Top of loop aligned on 64-byte boundary
+ ;
+bn_mul_words_single_top
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+
+ XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l
+ FSTD fm1,-16(%sp) ; -16(sp) = m1
+ XMPYU flt_0,fw_h,fm ; m = lt*fw_h
+ FSTD fm,-8(%sp) ; -8(sp) = m
+ XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h
+ FSTD ht_temp,-24(%sp) ; -24(sp) = ht
+ XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l
+ FSTD lt_temp,-32(%sp) ; -32(sp) = lt
+
+ LDD -8(%sp),m_0
+ LDD -16(%sp),m1_0
+ ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1;
+ LDD -24(%sp),ht_0
+ LDD -32(%sp),lt_0
+
+ CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1)
+ ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32)
+
+ EXTRD,U tmp_0,31,32,m_0 ; m>>32
+ DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32
+
+ ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32)
+ ADD lt_0,m1_0,lt_0 ; lt= lt+m1;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ ADD %ret0,lt_0,lt_0 ; lt = lt + c;
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ COPY ht_0,%ret0 ; copy carry
+ STD lt_0,0(r_ptr) ; rp[0] = lt
+
+bn_mul_words_exit
+ .EXIT
+ LDD -96(%sp),%r7 ; restore r7
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3 ; restore r3
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = num
+;
+
+bn_sqr_words
+ .proc
+ .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ NOP
+ STD %r5,16(%sp) ; save r5
+
+ CMPIB,>= 0,num,bn_sqr_words_exit
+ LDO 128(%sp),%sp ; bump stack
+
+ ;
+ ; If only 1, the goto straight to cleanup
+ ;
+ CMPIB,= 1,num,bn_sqr_words_single_top
+ DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+
+bn_sqr_words_unroll2
+ FLDD 0(a_ptr),t_float_0 ; a[0]
+ FLDD 8(a_ptr),t_float_1 ; a[1]
+ XMPYU fht_0,flt_0,fm ; m[0]
+ XMPYU fht_1,flt_1,fm_1 ; m[1]
+
+ FSTD fm,-24(%sp) ; store m[0]
+ FSTD fm_1,-56(%sp) ; store m[1]
+ XMPYU flt_0,flt_0,lt_temp ; lt[0]
+ XMPYU flt_1,flt_1,lt_temp_1 ; lt[1]
+
+ FSTD lt_temp,-16(%sp) ; store lt[0]
+ FSTD lt_temp_1,-48(%sp) ; store lt[1]
+ XMPYU fht_0,fht_0,ht_temp ; ht[0]
+ XMPYU fht_1,fht_1,ht_temp_1 ; ht[1]
+
+ FSTD ht_temp,-8(%sp) ; store ht[0]
+ FSTD ht_temp_1,-40(%sp) ; store ht[1]
+ LDD -24(%sp),m_0
+ LDD -56(%sp),m_1
+
+ AND m_0,high_mask,tmp_0 ; m[0] & Mask
+ AND m_1,high_mask,tmp_1 ; m[1] & Mask
+ DEPD,Z m_0,30,31,m_0 ; m[0] << 32+1
+ DEPD,Z m_1,30,31,m_1 ; m[1] << 32+1
+
+ LDD -16(%sp),lt_0
+ LDD -48(%sp),lt_1
+ EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m[0]&Mask >> 32-1
+ EXTRD,U tmp_1,32,33,tmp_1 ; tmp_1 = m[1]&Mask >> 32-1
+
+ LDD -8(%sp),ht_0
+ LDD -40(%sp),ht_1
+ ADD,L ht_0,tmp_0,ht_0 ; ht[0] += tmp_0
+ ADD,L ht_1,tmp_1,ht_1 ; ht[1] += tmp_1
+
+ ADD lt_0,m_0,lt_0 ; lt = lt+m
+ ADD,DC ht_0,%r0,ht_0 ; ht[0]++
+ STD lt_0,0(r_ptr) ; rp[0] = lt[0]
+ STD ht_0,8(r_ptr) ; rp[1] = ht[1]
+
+ ADD lt_1,m_1,lt_1 ; lt = lt+m
+ ADD,DC ht_1,%r0,ht_1 ; ht[1]++
+ STD lt_1,16(r_ptr) ; rp[2] = lt[1]
+ STD ht_1,24(r_ptr) ; rp[3] = ht[1]
+
+ LDO -2(num),num ; num = num - 2;
+ LDO 16(a_ptr),a_ptr ; ap += 2
+ CMPIB,<= 2,num,bn_sqr_words_unroll2
+ LDO 32(r_ptr),r_ptr ; rp += 4
+
+ CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done?
+
+ ;
+ ; Top of loop aligned on 64-byte boundary
+ ;
+bn_sqr_words_single_top
+ FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R)
+
+ XMPYU fht_0,flt_0,fm ; m
+ FSTD fm,-24(%sp) ; store m
+
+ XMPYU flt_0,flt_0,lt_temp ; lt
+ FSTD lt_temp,-16(%sp) ; store lt
+
+ XMPYU fht_0,fht_0,ht_temp ; ht
+ FSTD ht_temp,-8(%sp) ; store ht
+
+ LDD -24(%sp),m_0 ; load m
+ AND m_0,high_mask,tmp_0 ; m & Mask
+ DEPD,Z m_0,30,31,m_0 ; m << 32+1
+ LDD -16(%sp),lt_0 ; lt
+
+ LDD -8(%sp),ht_0 ; ht
+ EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m&Mask >> 32-1
+ ADD m_0,lt_0,lt_0 ; lt = lt+m
+ ADD,L ht_0,tmp_0,ht_0 ; ht += tmp_0
+ ADD,DC ht_0,%r0,ht_0 ; ht++
+
+ STD lt_0,0(r_ptr) ; rp[0] = lt
+ STD ht_0,8(r_ptr) ; rp[1] = ht
+
+bn_sqr_words_exit
+ .EXIT
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = bp
+; arg3 = n
+
+t .reg %r22
+b .reg %r21
+l .reg %r20
+
+bn_add_words
+ .proc
+ .entry
+ .callinfo
+ .EXPORT bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .align 64
+
+ CMPIB,>= 0,n,bn_add_words_exit
+ COPY %r0,%ret0 ; return 0 by default
+
+ ;
+ ; If 2 or more numbers do the loop
+ ;
+ CMPIB,= 1,n,bn_add_words_single_top
+ NOP
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+bn_add_words_unroll2
+ LDD 0(a_ptr),t
+ LDD 0(b_ptr),b
+ ADD t,%ret0,t ; t = t+c;
+ ADD,DC %r0,%r0,%ret0 ; set c to carry
+ ADD t,b,l ; l = t + b[0]
+ ADD,DC %ret0,%r0,%ret0 ; c+= carry
+ STD l,0(r_ptr)
+
+ LDD 8(a_ptr),t
+ LDD 8(b_ptr),b
+ ADD t,%ret0,t ; t = t+c;
+ ADD,DC %r0,%r0,%ret0 ; set c to carry
+ ADD t,b,l ; l = t + b[0]
+ ADD,DC %ret0,%r0,%ret0 ; c+= carry
+ STD l,8(r_ptr)
+
+ LDO -2(n),n
+ LDO 16(a_ptr),a_ptr
+ LDO 16(b_ptr),b_ptr
+
+ CMPIB,<= 2,n,bn_add_words_unroll2
+ LDO 16(r_ptr),r_ptr
+
+ CMPIB,=,N 0,n,bn_add_words_exit ; are we done?
+
+bn_add_words_single_top
+ LDD 0(a_ptr),t
+ LDD 0(b_ptr),b
+
+ ADD t,%ret0,t ; t = t+c;
+ ADD,DC %r0,%r0,%ret0 ; set c to carry (could use CMPCLR??)
+ ADD t,b,l ; l = t + b[0]
+ ADD,DC %ret0,%r0,%ret0 ; c+= carry
+ STD l,0(r_ptr)
+
+bn_add_words_exit
+ .EXIT
+ BVE (%rp)
+ NOP
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+;
+; arg0 = rp
+; arg1 = ap
+; arg2 = bp
+; arg3 = n
+
+t1 .reg %r22
+t2 .reg %r21
+sub_tmp1 .reg %r20
+sub_tmp2 .reg %r19
+
+
+bn_sub_words
+ .proc
+ .callinfo
+ .EXPORT bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+
+ CMPIB,>= 0,n,bn_sub_words_exit
+ COPY %r0,%ret0 ; return 0 by default
+
+ ;
+ ; If 2 or more numbers do the loop
+ ;
+ CMPIB,= 1,n,bn_sub_words_single_top
+ NOP
+
+ ;
+ ; This loop is unrolled 2 times (64-byte aligned as well)
+ ;
+bn_sub_words_unroll2
+ LDD 0(a_ptr),t1
+ LDD 0(b_ptr),t2
+ SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
+ SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c;
+
+ CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
+ LDO 1(%r0),sub_tmp2
+
+ CMPCLR,*= t1,t2,%r0
+ COPY sub_tmp2,%ret0
+ STD sub_tmp1,0(r_ptr)
+
+ LDD 8(a_ptr),t1
+ LDD 8(b_ptr),t2
+ SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
+ SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c;
+ CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
+ LDO 1(%r0),sub_tmp2
+
+ CMPCLR,*= t1,t2,%r0
+ COPY sub_tmp2,%ret0
+ STD sub_tmp1,8(r_ptr)
+
+ LDO -2(n),n
+ LDO 16(a_ptr),a_ptr
+ LDO 16(b_ptr),b_ptr
+
+ CMPIB,<= 2,n,bn_sub_words_unroll2
+ LDO 16(r_ptr),r_ptr
+
+ CMPIB,=,N 0,n,bn_sub_words_exit ; are we done?
+
+bn_sub_words_single_top
+ LDD 0(a_ptr),t1
+ LDD 0(b_ptr),t2
+ SUB t1,t2,sub_tmp1 ; t3 = t1-t2;
+ SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c;
+ CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2
+ LDO 1(%r0),sub_tmp2
+
+ CMPCLR,*= t1,t2,%r0
+ COPY sub_tmp2,%ret0
+
+ STD sub_tmp1,0(r_ptr)
+
+bn_sub_words_exit
+ .EXIT
+ BVE (%rp)
+ NOP
+ .PROCEND ;in=23,24,25,26,29;out=28;
+
+;------------------------------------------------------------------------------
+;
+; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d)
+;
+; arg0 = h
+; arg1 = l
+; arg2 = d
+;
+; This is mainly just modified assembly from the compiler, thus the
+; lack of variable names.
+;
+;------------------------------------------------------------------------------
+bn_div_words
+ .proc
+ .callinfo CALLER,FRAME=272,ENTRY_GR=%r10,SAVE_RP,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .IMPORT BN_num_bits_word,CODE,NO_RELOCATION
+ .IMPORT __iob,DATA
+ .IMPORT fprintf,CODE,NO_RELOCATION
+ .IMPORT abort,CODE,NO_RELOCATION
+ .IMPORT $$div2U,MILLICODE
+ .entry
+ STD %r2,-16(%r30)
+ STD,MA %r3,352(%r30)
+ STD %r4,-344(%r30)
+ STD %r5,-336(%r30)
+ STD %r6,-328(%r30)
+ STD %r7,-320(%r30)
+ STD %r8,-312(%r30)
+ STD %r9,-304(%r30)
+ STD %r10,-296(%r30)
+
+ STD %r27,-288(%r30) ; save gp
+
+ COPY %r24,%r3 ; save d
+ COPY %r26,%r4 ; save h (high 64-bits)
+ LDO -1(%r0),%ret0 ; return -1 by default
+
+ CMPB,*= %r0,%arg2,$D3 ; if (d == 0)
+ COPY %r25,%r5 ; save l (low 64-bits)
+
+ LDO -48(%r30),%r29 ; create ap
+ .CALL ;in=26,29;out=28;
+ B,L BN_num_bits_word,%r2
+ COPY %r3,%r26
+ LDD -288(%r30),%r27 ; restore gp
+ LDI 64,%r21
+
+ CMPB,= %r21,%ret0,$00000012 ;if (i == 64) (forward)
+ COPY %ret0,%r24 ; i
+ MTSARCM %r24
+ DEPDI,Z -1,%sar,1,%r29
+ CMPB,*<<,N %r29,%r4,bn_div_err_case ; if (h > 1<<i) (forward)
+
+$00000012
+ SUBI 64,%r24,%r31 ; i = 64 - i;
+ CMPCLR,*<< %r4,%r3,%r0 ; if (h >= d)
+ SUB %r4,%r3,%r4 ; h -= d
+ CMPB,= %r31,%r0,$0000001A ; if (i)
+ COPY %r0,%r10 ; ret = 0
+ MTSARCM %r31 ; i to shift
+ DEPD,Z %r3,%sar,64,%r3 ; d <<= i;
+ SUBI 64,%r31,%r19 ; 64 - i; redundent
+ MTSAR %r19 ; (64 -i) to shift
+ SHRPD %r4,%r5,%sar,%r4 ; l>> (64-i)
+ MTSARCM %r31 ; i to shift
+ DEPD,Z %r5,%sar,64,%r5 ; l <<= i;
+
+$0000001A
+ DEPDI,Z -1,31,32,%r19
+ EXTRD,U %r3,31,32,%r6 ; dh=(d&0xfff)>>32
+ EXTRD,U %r3,63,32,%r8 ; dl = d&0xffffff
+ LDO 2(%r0),%r9
+ STD %r3,-280(%r30) ; "d" to stack
+
+$0000001C
+ DEPDI,Z -1,63,32,%r29 ;
+ EXTRD,U %r4,31,32,%r31 ; h >> 32
+ CMPB,*=,N %r31,%r6,$D2 ; if ((h>>32) != dh)(forward) div
+ COPY %r4,%r26
+ EXTRD,U %r4,31,32,%r25
+ COPY %r6,%r24
+ .CALL ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL)
+ B,L $$div2U,%r2
+ EXTRD,U %r6,31,32,%r23
+ DEPD %r28,31,32,%r29
+$D2
+ STD %r29,-272(%r30) ; q
+ AND %r5,%r19,%r24 ; t & 0xffffffff00000000;
+ EXTRD,U %r24,31,32,%r24 ; ???
+ FLDD -272(%r30),%fr7 ; q
+ FLDD -280(%r30),%fr8 ; d
+ XMPYU %fr8L,%fr7L,%fr10
+ FSTD %fr10,-256(%r30)
+ XMPYU %fr8L,%fr7R,%fr22
+ FSTD %fr22,-264(%r30)
+ XMPYU %fr8R,%fr7L,%fr11
+ XMPYU %fr8R,%fr7R,%fr23
+ FSTD %fr11,-232(%r30)
+ FSTD %fr23,-240(%r30)
+ LDD -256(%r30),%r28
+ DEPD,Z %r28,31,32,%r2
+ LDD -264(%r30),%r20
+ ADD,L %r20,%r2,%r31
+ LDD -232(%r30),%r22
+ DEPD,Z %r22,31,32,%r22
+ LDD -240(%r30),%r21
+ B $00000024 ; enter loop
+ ADD,L %r21,%r22,%r23
+
+$0000002A
+ LDO -1(%r29),%r29
+ SUB %r23,%r8,%r23
+$00000024
+ SUB %r4,%r31,%r25
+ AND %r25,%r19,%r26
+ CMPB,*<>,N %r0,%r26,$00000046 ; (forward)
+ DEPD,Z %r25,31,32,%r20
+ OR %r20,%r24,%r21
+ CMPB,*<<,N %r21,%r23,$0000002A ;(backward)
+ SUB %r31,%r6,%r31
+;-------------Break path---------------------
+
+$00000046
+ DEPD,Z %r23,31,32,%r25 ;tl
+ EXTRD,U %r23,31,32,%r26 ;t
+ AND %r25,%r19,%r24 ;tl = (tl<<32)&0xfffffff0000000L
+ ADD,L %r31,%r26,%r31 ;th += t;
+ CMPCLR,*>>= %r5,%r24,%r0 ;if (l<tl)
+ LDO 1(%r31),%r31 ; th++;
+ CMPB,*<<=,N %r31,%r4,$00000036 ;if (n < th) (forward)
+ LDO -1(%r29),%r29 ;q--;
+ ADD,L %r4,%r3,%r4 ;h += d;
+$00000036
+ ADDIB,=,N -1,%r9,$D1 ;if (--count == 0) break (forward)
+ SUB %r5,%r24,%r28 ; l -= tl;
+ SUB %r4,%r31,%r24 ; h -= th;
+ SHRPD %r24,%r28,32,%r4 ; h = ((h<<32)|(l>>32));
+ DEPD,Z %r29,31,32,%r10 ; ret = q<<32
+ b $0000001C
+ DEPD,Z %r28,31,32,%r5 ; l = l << 32
+
+$D1
+ OR %r10,%r29,%r28 ; ret |= q
+$D3
+ LDD -368(%r30),%r2
+$D0
+ LDD -296(%r30),%r10
+ LDD -304(%r30),%r9
+ LDD -312(%r30),%r8
+ LDD -320(%r30),%r7
+ LDD -328(%r30),%r6
+ LDD -336(%r30),%r5
+ LDD -344(%r30),%r4
+ BVE (%r2)
+ .EXIT
+ LDD,MB -352(%r30),%r3
+
+bn_div_err_case
+ MFIA %r6
+ ADDIL L'bn_div_words-bn_div_err_case,%r6,%r1
+ LDO R'bn_div_words-bn_div_err_case(%r1),%r6
+ ADDIL LT'__iob,%r27,%r1
+ LDD RT'__iob(%r1),%r26
+ ADDIL L'C$4-bn_div_words,%r6,%r1
+ LDO R'C$4-bn_div_words(%r1),%r25
+ LDO 64(%r26),%r26
+ .CALL ;in=24,25,26,29;out=28;
+ B,L fprintf,%r2
+ LDO -48(%r30),%r29
+ LDD -288(%r30),%r27
+ .CALL ;in=29;
+ B,L abort,%r2
+ LDO -48(%r30),%r29
+ LDD -288(%r30),%r27
+ B $D0
+ LDD -368(%r30),%r2
+ .PROCEND ;in=24,25,26,29;out=28;
+
+;----------------------------------------------------------------------------
+;
+; Registers to hold 64-bit values to manipulate. The "L" part
+; of the register corresponds to the upper 32-bits, while the "R"
+; part corresponds to the lower 32-bits
+;
+; Note, that when using b6 and b7, the code must save these before
+; using them because they are callee save registers
+;
+;
+; Floating point registers to use to save values that
+; are manipulated. These don't collide with ftemp1-6 and
+; are all caller save registers
+;
+a0 .reg %fr22
+a0L .reg %fr22L
+a0R .reg %fr22R
+
+a1 .reg %fr23
+a1L .reg %fr23L
+a1R .reg %fr23R
+
+a2 .reg %fr24
+a2L .reg %fr24L
+a2R .reg %fr24R
+
+a3 .reg %fr25
+a3L .reg %fr25L
+a3R .reg %fr25R
+
+a4 .reg %fr26
+a4L .reg %fr26L
+a4R .reg %fr26R
+
+a5 .reg %fr27
+a5L .reg %fr27L
+a5R .reg %fr27R
+
+a6 .reg %fr28
+a6L .reg %fr28L
+a6R .reg %fr28R
+
+a7 .reg %fr29
+a7L .reg %fr29L
+a7R .reg %fr29R
+
+b0 .reg %fr30
+b0L .reg %fr30L
+b0R .reg %fr30R
+
+b1 .reg %fr31
+b1L .reg %fr31L
+b1R .reg %fr31R
+
+;
+; Temporary floating point variables, these are all caller save
+; registers
+;
+ftemp1 .reg %fr4
+ftemp2 .reg %fr5
+ftemp3 .reg %fr6
+ftemp4 .reg %fr7
+
+;
+; The B set of registers when used.
+;
+
+b2 .reg %fr8
+b2L .reg %fr8L
+b2R .reg %fr8R
+
+b3 .reg %fr9
+b3L .reg %fr9L
+b3R .reg %fr9R
+
+b4 .reg %fr10
+b4L .reg %fr10L
+b4R .reg %fr10R
+
+b5 .reg %fr11
+b5L .reg %fr11L
+b5R .reg %fr11R
+
+b6 .reg %fr12
+b6L .reg %fr12L
+b6R .reg %fr12R
+
+b7 .reg %fr13
+b7L .reg %fr13L
+b7R .reg %fr13R
+
+c1 .reg %r21 ; only reg
+temp1 .reg %r20 ; only reg
+temp2 .reg %r19 ; only reg
+temp3 .reg %r31 ; only reg
+
+m1 .reg %r28
+c2 .reg %r23
+high_one .reg %r1
+ht .reg %r6
+lt .reg %r5
+m .reg %r4
+c3 .reg %r3
+
+SQR_ADD_C .macro A0L,A0R,C1,C2,C3
+ XMPYU A0L,A0R,ftemp1 ; m
+ FSTD ftemp1,-24(%sp) ; store m
+
+ XMPYU A0R,A0R,ftemp2 ; lt
+ FSTD ftemp2,-16(%sp) ; store lt
+
+ XMPYU A0L,A0L,ftemp3 ; ht
+ FSTD ftemp3,-8(%sp) ; store ht
+
+ LDD -24(%sp),m ; load m
+ AND m,high_mask,temp2 ; m & Mask
+ DEPD,Z m,30,31,temp3 ; m << 32+1
+ LDD -16(%sp),lt ; lt
+
+ LDD -8(%sp),ht ; ht
+ EXTRD,U temp2,32,33,temp1 ; temp1 = m&Mask >> 32-1
+ ADD temp3,lt,lt ; lt = lt+m
+ ADD,L ht,temp1,ht ; ht += temp1
+ ADD,DC ht,%r0,ht ; ht++
+
+ ADD C1,lt,C1 ; c1=c1+lt
+ ADD,DC ht,%r0,ht ; ht++
+
+ ADD C2,ht,C2 ; c2=c2+ht
+ ADD,DC C3,%r0,C3 ; c3++
+.endm
+
+SQR_ADD_C2 .macro A0L,A0R,A1L,A1R,C1,C2,C3
+ XMPYU A0L,A1R,ftemp1 ; m1 = bl*ht
+ FSTD ftemp1,-16(%sp) ;
+ XMPYU A0R,A1L,ftemp2 ; m = bh*lt
+ FSTD ftemp2,-8(%sp) ;
+ XMPYU A0R,A1R,ftemp3 ; lt = bl*lt
+ FSTD ftemp3,-32(%sp)
+ XMPYU A0L,A1L,ftemp4 ; ht = bh*ht
+ FSTD ftemp4,-24(%sp) ;
+
+ LDD -8(%sp),m ; r21 = m
+ LDD -16(%sp),m1 ; r19 = m1
+ ADD,L m,m1,m ; m+m1
+
+ DEPD,Z m,31,32,temp3 ; (m+m1<<32)
+ LDD -24(%sp),ht ; r24 = ht
+
+ CMPCLR,*>>= m,m1,%r0 ; if (m < m1)
+ ADD,L ht,high_one,ht ; ht+=high_one
+
+ EXTRD,U m,31,32,temp1 ; m >> 32
+ LDD -32(%sp),lt ; lt
+ ADD,L ht,temp1,ht ; ht+= m>>32
+ ADD lt,temp3,lt ; lt = lt+m1
+ ADD,DC ht,%r0,ht ; ht++
+
+ ADD ht,ht,ht ; ht=ht+ht;
+ ADD,DC C3,%r0,C3 ; add in carry (c3++)
+
+ ADD lt,lt,lt ; lt=lt+lt;
+ ADD,DC ht,%r0,ht ; add in carry (ht++)
+
+ ADD C1,lt,C1 ; c1=c1+lt
+ ADD,DC,*NUV ht,%r0,ht ; add in carry (ht++)
+ LDO 1(C3),C3 ; bump c3 if overflow,nullify otherwise
+
+ ADD C2,ht,C2 ; c2 = c2 + ht
+ ADD,DC C3,%r0,C3 ; add in carry (c3++)
+.endm
+
+;
+;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+; arg0 = r_ptr
+; arg1 = a_ptr
+;
+
+bn_sqr_comba8
+ .PROC
+ .CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .ENTRY
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+
+ ;
+ ; Zero out carries
+ ;
+ COPY %r0,c1
+ COPY %r0,c2
+ COPY %r0,c3
+
+ LDO 128(%sp),%sp ; bump stack
+ DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
+ DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
+
+ ;
+ ; Load up all of the values we are going to use
+ ;
+ FLDD 0(a_ptr),a0
+ FLDD 8(a_ptr),a1
+ FLDD 16(a_ptr),a2
+ FLDD 24(a_ptr),a3
+ FLDD 32(a_ptr),a4
+ FLDD 40(a_ptr),a5
+ FLDD 48(a_ptr),a6
+ FLDD 56(a_ptr),a7
+
+ SQR_ADD_C a0L,a0R,c1,c2,c3
+ STD c1,0(r_ptr) ; r[0] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
+ STD c2,8(r_ptr) ; r[1] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C a1L,a1R,c3,c1,c2
+ SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
+ STD c3,16(r_ptr) ; r[2] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
+ SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
+ STD c1,24(r_ptr) ; r[3] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C a2L,a2R,c2,c3,c1
+ SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
+ SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1
+ STD c2,32(r_ptr) ; r[4] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2
+ SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2
+ SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
+ STD c3,40(r_ptr) ; r[5] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C a3L,a3R,c1,c2,c3
+ SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3
+ SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3
+ SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3
+ STD c1,48(r_ptr) ; r[6] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1
+ SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1
+ SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1
+ SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1
+ STD c2,56(r_ptr) ; r[7] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C a4L,a4R,c3,c1,c2
+ SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2
+ SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2
+ SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2
+ STD c3,64(r_ptr) ; r[8] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3
+ SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3
+ SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3
+ STD c1,72(r_ptr) ; r[9] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C a5L,a5R,c2,c3,c1
+ SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1
+ SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1
+ STD c2,80(r_ptr) ; r[10] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2
+ SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2
+ STD c3,88(r_ptr) ; r[11] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C a6L,a6R,c1,c2,c3
+ SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3
+ STD c1,96(r_ptr) ; r[12] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1
+ STD c2,104(r_ptr) ; r[13] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C a7L,a7R,c3,c1,c2
+ STD c3, 112(r_ptr) ; r[14] = c3
+ STD c1, 120(r_ptr) ; r[15] = c1
+
+ .EXIT
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+
+ .PROCEND
+
+;-----------------------------------------------------------------------------
+;
+;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+; arg0 = r_ptr
+; arg1 = a_ptr
+;
+
+bn_sqr_comba4
+ .proc
+ .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+
+ ;
+ ; Zero out carries
+ ;
+ COPY %r0,c1
+ COPY %r0,c2
+ COPY %r0,c3
+
+ LDO 128(%sp),%sp ; bump stack
+ DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L
+ DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
+
+ ;
+ ; Load up all of the values we are going to use
+ ;
+ FLDD 0(a_ptr),a0
+ FLDD 8(a_ptr),a1
+ FLDD 16(a_ptr),a2
+ FLDD 24(a_ptr),a3
+ FLDD 32(a_ptr),a4
+ FLDD 40(a_ptr),a5
+ FLDD 48(a_ptr),a6
+ FLDD 56(a_ptr),a7
+
+ SQR_ADD_C a0L,a0R,c1,c2,c3
+
+ STD c1,0(r_ptr) ; r[0] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1
+
+ STD c2,8(r_ptr) ; r[1] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C a1L,a1R,c3,c1,c2
+ SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2
+
+ STD c3,16(r_ptr) ; r[2] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3
+ SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3
+
+ STD c1,24(r_ptr) ; r[3] = c1;
+ COPY %r0,c1
+
+ SQR_ADD_C a2L,a2R,c2,c3,c1
+ SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1
+
+ STD c2,32(r_ptr) ; r[4] = c2;
+ COPY %r0,c2
+
+ SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2
+ STD c3,40(r_ptr) ; r[5] = c3;
+ COPY %r0,c3
+
+ SQR_ADD_C a3L,a3R,c1,c2,c3
+ STD c1,48(r_ptr) ; r[6] = c1;
+ STD c2,56(r_ptr) ; r[7] = c2;
+
+ .EXIT
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+
+ .PROCEND
+
+
+;---------------------------------------------------------------------------
+
+MUL_ADD_C .macro A0L,A0R,B0L,B0R,C1,C2,C3
+ XMPYU A0L,B0R,ftemp1 ; m1 = bl*ht
+ FSTD ftemp1,-16(%sp) ;
+ XMPYU A0R,B0L,ftemp2 ; m = bh*lt
+ FSTD ftemp2,-8(%sp) ;
+ XMPYU A0R,B0R,ftemp3 ; lt = bl*lt
+ FSTD ftemp3,-32(%sp)
+ XMPYU A0L,B0L,ftemp4 ; ht = bh*ht
+ FSTD ftemp4,-24(%sp) ;
+
+ LDD -8(%sp),m ; r21 = m
+ LDD -16(%sp),m1 ; r19 = m1
+ ADD,L m,m1,m ; m+m1
+
+ DEPD,Z m,31,32,temp3 ; (m+m1<<32)
+ LDD -24(%sp),ht ; r24 = ht
+
+ CMPCLR,*>>= m,m1,%r0 ; if (m < m1)
+ ADD,L ht,high_one,ht ; ht+=high_one
+
+ EXTRD,U m,31,32,temp1 ; m >> 32
+ LDD -32(%sp),lt ; lt
+ ADD,L ht,temp1,ht ; ht+= m>>32
+ ADD lt,temp3,lt ; lt = lt+m1
+ ADD,DC ht,%r0,ht ; ht++
+
+ ADD C1,lt,C1 ; c1=c1+lt
+ ADD,DC ht,%r0,ht ; bump c3 if overflow,nullify otherwise
+
+ ADD C2,ht,C2 ; c2 = c2 + ht
+ ADD,DC C3,%r0,C3 ; add in carry (c3++)
+.endm
+
+
+;
+;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = b_ptr
+;
+
+bn_mul_comba8
+ .proc
+ .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+ FSTD %fr12,32(%sp) ; save r6
+ FSTD %fr13,40(%sp) ; save r7
+
+ ;
+ ; Zero out carries
+ ;
+ COPY %r0,c1
+ COPY %r0,c2
+ COPY %r0,c3
+
+ LDO 128(%sp),%sp ; bump stack
+ DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
+
+ ;
+ ; Load up all of the values we are going to use
+ ;
+ FLDD 0(a_ptr),a0
+ FLDD 8(a_ptr),a1
+ FLDD 16(a_ptr),a2
+ FLDD 24(a_ptr),a3
+ FLDD 32(a_ptr),a4
+ FLDD 40(a_ptr),a5
+ FLDD 48(a_ptr),a6
+ FLDD 56(a_ptr),a7
+
+ FLDD 0(b_ptr),b0
+ FLDD 8(b_ptr),b1
+ FLDD 16(b_ptr),b2
+ FLDD 24(b_ptr),b3
+ FLDD 32(b_ptr),b4
+ FLDD 40(b_ptr),b5
+ FLDD 48(b_ptr),b6
+ FLDD 56(b_ptr),b7
+
+ MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
+ STD c1,0(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
+ STD c2,8(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
+ MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
+ MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
+ STD c3,16(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
+ MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
+ MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
+ MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
+ STD c1,24(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1
+ MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
+ MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1
+ STD c2,32(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2
+ MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2
+ MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
+ MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
+ MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2
+ MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2
+ STD c3,40(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3
+ MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3
+ MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3
+ MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
+ MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3
+ MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3
+ MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3
+ STD c1,48(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1
+ MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1
+ MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1
+ MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1
+ MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1
+ MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1
+ STD c2,56(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2
+ MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2
+ MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2
+ MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2
+ MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2
+ MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2
+ MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2
+ STD c3,64(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3
+ MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3
+ MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3
+ MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3
+ MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3
+ MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3
+ STD c1,72(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1
+ MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1
+ MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1
+ MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1
+ MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1
+ STD c2,80(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2
+ MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2
+ MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2
+ MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2
+ STD c3,88(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3
+ MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3
+ MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3
+ STD c1,96(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1
+ MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1
+ STD c2,104(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2
+ STD c3,112(r_ptr)
+ STD c1,120(r_ptr)
+
+ .EXIT
+ FLDD -88(%sp),%fr13
+ FLDD -96(%sp),%fr12
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+
+ .PROCEND
+
+;-----------------------------------------------------------------------------
+;
+;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+; arg0 = r_ptr
+; arg1 = a_ptr
+; arg2 = b_ptr
+;
+
+bn_mul_comba4
+ .proc
+ .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE
+ .EXPORT bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN
+ .entry
+ .align 64
+
+ STD %r3,0(%sp) ; save r3
+ STD %r4,8(%sp) ; save r4
+ STD %r5,16(%sp) ; save r5
+ STD %r6,24(%sp) ; save r6
+ FSTD %fr12,32(%sp) ; save r6
+ FSTD %fr13,40(%sp) ; save r7
+
+ ;
+ ; Zero out carries
+ ;
+ COPY %r0,c1
+ COPY %r0,c2
+ COPY %r0,c3
+
+ LDO 128(%sp),%sp ; bump stack
+ DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32
+
+ ;
+ ; Load up all of the values we are going to use
+ ;
+ FLDD 0(a_ptr),a0
+ FLDD 8(a_ptr),a1
+ FLDD 16(a_ptr),a2
+ FLDD 24(a_ptr),a3
+
+ FLDD 0(b_ptr),b0
+ FLDD 8(b_ptr),b1
+ FLDD 16(b_ptr),b2
+ FLDD 24(b_ptr),b3
+
+ MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3
+ STD c1,0(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1
+ STD c2,8(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2
+ MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2
+ MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2
+ STD c3,16(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3
+ MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3
+ MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3
+ MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3
+ STD c1,24(r_ptr)
+ COPY %r0,c1
+
+ MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1
+ MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1
+ MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1
+ STD c2,32(r_ptr)
+ COPY %r0,c2
+
+ MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2
+ MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2
+ STD c3,40(r_ptr)
+ COPY %r0,c3
+
+ MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3
+ STD c1,48(r_ptr)
+ STD c2,56(r_ptr)
+
+ .EXIT
+ FLDD -88(%sp),%fr13
+ FLDD -96(%sp),%fr12
+ LDD -104(%sp),%r6 ; restore r6
+ LDD -112(%sp),%r5 ; restore r5
+ LDD -120(%sp),%r4 ; restore r4
+ BVE (%rp)
+ LDD,MB -128(%sp),%r3
+
+ .PROCEND
+
+
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+ .SPACE $PRIVATE$,SORT=16
+ .IMPORT $global$,DATA
+ .SPACE $TEXT$
+ .SUBSPA $CODE$
+ .SUBSPA $LIT$,ACCESS=0x2c
+C$4
+ .ALIGN 8
+ .STRINGZ "Division would overflow (%d)\n"
+ .END
diff --git a/openssl/trunk/crypto/bn/asm/ppc.pl b/openssl/trunk/crypto/bn/asm/ppc.pl
new file mode 100644
index 00000000..08e00534
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/ppc.pl
@@ -0,0 +1,2078 @@
+#!/usr/bin/env perl
+#
+# Implemented as a Perl wrapper as we want to support several different
+# architectures with single file. We pick up the target based on the
+# file name we are asked to generate.
+#
+# It should be noted though that this perl code is nothing like
+# <openssl>/crypto/perlasm/x86*. In this case perl is used pretty much
+# as pre-processor to cover for platform differences in name decoration,
+# linker tables, 32-/64-bit instruction sets...
+#
+# As you might know there're several PowerPC ABI in use. Most notably
+# Linux and AIX use different 32-bit ABIs. Good news are that these ABIs
+# are similar enough to implement leaf(!) functions, which would be ABI
+# neutral. And that's what you find here: ABI neutral leaf functions.
+# In case you wonder what that is...
+#
+# AIX performance
+#
+# MEASUREMENTS WITH cc ON a 200 MhZ PowerPC 604e.
+#
+# The following is the performance of 32-bit compiler
+# generated code:
+#
+# OpenSSL 0.9.6c 21 dec 2001
+# built on: Tue Jun 11 11:06:51 EDT 2002
+# options:bn(64,32) ...
+#compiler: cc -DTHREADS -DAIX -DB_ENDIAN -DBN_LLONG -O3
+# sign verify sign/s verify/s
+#rsa 512 bits 0.0098s 0.0009s 102.0 1170.6
+#rsa 1024 bits 0.0507s 0.0026s 19.7 387.5
+#rsa 2048 bits 0.3036s 0.0085s 3.3 117.1
+#rsa 4096 bits 2.0040s 0.0299s 0.5 33.4
+#dsa 512 bits 0.0087s 0.0106s 114.3 94.5
+#dsa 1024 bits 0.0256s 0.0313s 39.0 32.0
+#
+# Same bechmark with this assembler code:
+#
+#rsa 512 bits 0.0056s 0.0005s 178.6 2049.2
+#rsa 1024 bits 0.0283s 0.0015s 35.3 674.1
+#rsa 2048 bits 0.1744s 0.0050s 5.7 201.2
+#rsa 4096 bits 1.1644s 0.0179s 0.9 55.7
+#dsa 512 bits 0.0052s 0.0062s 191.6 162.0
+#dsa 1024 bits 0.0149s 0.0180s 67.0 55.5
+#
+# Number of operations increases by at almost 75%
+#
+# Here are performance numbers for 64-bit compiler
+# generated code:
+#
+# OpenSSL 0.9.6g [engine] 9 Aug 2002
+# built on: Fri Apr 18 16:59:20 EDT 2003
+# options:bn(64,64) ...
+# compiler: cc -DTHREADS -D_REENTRANT -q64 -DB_ENDIAN -O3
+# sign verify sign/s verify/s
+#rsa 512 bits 0.0028s 0.0003s 357.1 3844.4
+#rsa 1024 bits 0.0148s 0.0008s 67.5 1239.7
+#rsa 2048 bits 0.0963s 0.0028s 10.4 353.0
+#rsa 4096 bits 0.6538s 0.0102s 1.5 98.1
+#dsa 512 bits 0.0026s 0.0032s 382.5 313.7
+#dsa 1024 bits 0.0081s 0.0099s 122.8 100.6
+#
+# Same benchmark with this assembler code:
+#
+#rsa 512 bits 0.0020s 0.0002s 510.4 6273.7
+#rsa 1024 bits 0.0088s 0.0005s 114.1 2128.3
+#rsa 2048 bits 0.0540s 0.0016s 18.5 622.5
+#rsa 4096 bits 0.3700s 0.0058s 2.7 171.0
+#dsa 512 bits 0.0016s 0.0020s 610.7 507.1
+#dsa 1024 bits 0.0047s 0.0058s 212.5 173.2
+#
+# Again, performance increases by at about 75%
+#
+# Mac OS X, Apple G5 1.8GHz (Note this is 32 bit code)
+# OpenSSL 0.9.7c 30 Sep 2003
+#
+# Original code.
+#
+#rsa 512 bits 0.0011s 0.0001s 906.1 11012.5
+#rsa 1024 bits 0.0060s 0.0003s 166.6 3363.1
+#rsa 2048 bits 0.0370s 0.0010s 27.1 982.4
+#rsa 4096 bits 0.2426s 0.0036s 4.1 280.4
+#dsa 512 bits 0.0010s 0.0012s 1038.1 841.5
+#dsa 1024 bits 0.0030s 0.0037s 329.6 269.7
+#dsa 2048 bits 0.0101s 0.0127s 98.9 78.6
+#
+# Same benchmark with this assembler code:
+#
+#rsa 512 bits 0.0007s 0.0001s 1416.2 16645.9
+#rsa 1024 bits 0.0036s 0.0002s 274.4 5380.6
+#rsa 2048 bits 0.0222s 0.0006s 45.1 1589.5
+#rsa 4096 bits 0.1469s 0.0022s 6.8 449.6
+#dsa 512 bits 0.0006s 0.0007s 1664.2 1376.2
+#dsa 1024 bits 0.0018s 0.0023s 545.0 442.2
+#dsa 2048 bits 0.0061s 0.0075s 163.5 132.8
+#
+# Performance increase of ~60%
+#
+# If you have comments or suggestions to improve code send
+# me a note at schari@us.ibm.com
+#
+
+$opf = shift;
+
+if ($opf =~ /32\.s/) {
+ $BITS= 32;
+ $BNSZ= $BITS/8;
+ $ISA= "\"ppc\"";
+
+ $LD= "lwz"; # load
+ $LDU= "lwzu"; # load and update
+ $ST= "stw"; # store
+ $STU= "stwu"; # store and update
+ $UMULL= "mullw"; # unsigned multiply low
+ $UMULH= "mulhwu"; # unsigned multiply high
+ $UDIV= "divwu"; # unsigned divide
+ $UCMPI= "cmplwi"; # unsigned compare with immediate
+ $UCMP= "cmplw"; # unsigned compare
+ $CNTLZ= "cntlzw"; # count leading zeros
+ $SHL= "slw"; # shift left
+ $SHR= "srw"; # unsigned shift right
+ $SHRI= "srwi"; # unsigned shift right by immediate
+ $SHLI= "slwi"; # shift left by immediate
+ $CLRU= "clrlwi"; # clear upper bits
+ $INSR= "insrwi"; # insert right
+ $ROTL= "rotlwi"; # rotate left by immediate
+ $TR= "tw"; # conditional trap
+} elsif ($opf =~ /64\.s/) {
+ $BITS= 64;
+ $BNSZ= $BITS/8;
+ $ISA= "\"ppc64\"";
+
+ # same as above, but 64-bit mnemonics...
+ $LD= "ld"; # load
+ $LDU= "ldu"; # load and update
+ $ST= "std"; # store
+ $STU= "stdu"; # store and update
+ $UMULL= "mulld"; # unsigned multiply low
+ $UMULH= "mulhdu"; # unsigned multiply high
+ $UDIV= "divdu"; # unsigned divide
+ $UCMPI= "cmpldi"; # unsigned compare with immediate
+ $UCMP= "cmpld"; # unsigned compare
+ $CNTLZ= "cntlzd"; # count leading zeros
+ $SHL= "sld"; # shift left
+ $SHR= "srd"; # unsigned shift right
+ $SHRI= "srdi"; # unsigned shift right by immediate
+ $SHLI= "sldi"; # shift left by immediate
+ $CLRU= "clrldi"; # clear upper bits
+ $INSR= "insrdi"; # insert right
+ $ROTL= "rotldi"; # rotate left by immediate
+ $TR= "td"; # conditional trap
+} else { die "nonsense $opf"; }
+
+( defined shift || open STDOUT,">$opf" ) || die "can't open $opf: $!";
+
+# function entry points from the AIX code
+#
+# There are other, more elegant, ways to handle this. We (IBM) chose
+# this approach as it plays well with scripts we run to 'namespace'
+# OpenSSL .i.e. we add a prefix to all the public symbols so we can
+# co-exist in the same process with other implementations of OpenSSL.
+# 'cleverer' ways of doing these substitutions tend to hide data we
+# need to be obvious.
+#
+my @items = ("bn_sqr_comba4",
+ "bn_sqr_comba8",
+ "bn_mul_comba4",
+ "bn_mul_comba8",
+ "bn_sub_words",
+ "bn_add_words",
+ "bn_div_words",
+ "bn_sqr_words",
+ "bn_mul_words",
+ "bn_mul_add_words");
+
+if ($opf =~ /linux/) { do_linux(); }
+elsif ($opf =~ /aix/) { do_aix(); }
+elsif ($opf =~ /osx/) { do_osx(); }
+else { do_bsd(); }
+
+sub do_linux {
+ $d=&data();
+
+ if ($BITS==64) {
+ foreach $t (@items) {
+ $d =~ s/\.$t:/\
+\t.section\t".opd","aw"\
+\t.align\t3\
+\t.globl\t$t\
+$t:\
+\t.quad\t.$t,.TOC.\@tocbase,0\
+\t.size\t$t,24\
+\t.previous\n\
+\t.type\t.$t,\@function\
+\t.globl\t.$t\
+.$t:/g;
+ }
+ }
+ else {
+ foreach $t (@items) {
+ $d=~s/\.$t/$t/g;
+ }
+ }
+ # hide internal labels to avoid pollution of name table...
+ $d=~s/Lppcasm_/.Lppcasm_/gm;
+ print $d;
+}
+
+sub do_aix {
+ # AIX assembler is smart enough to please the linker without
+ # making us do something special...
+ print &data();
+}
+
+# MacOSX 32 bit
+sub do_osx {
+ $d=&data();
+ # Change the bn symbol prefix from '.' to '_'
+ foreach $t (@items) {
+ $d=~s/\.$t/_$t/g;
+ }
+ # Change .machine to something OS X asm will accept
+ $d=~s/\.machine.*/.text/g;
+ $d=~s/\#/;/g; # change comment from '#' to ';'
+ print $d;
+}
+
+# BSD (Untested)
+sub do_bsd {
+ $d=&data();
+ foreach $t (@items) {
+ $d=~s/\.$t/_$t/g;
+ }
+ print $d;
+}
+
+sub data {
+ local($data)=<<EOF;
+#--------------------------------------------------------------------
+#
+#
+#
+#
+# File: ppc32.s
+#
+# Created by: Suresh Chari
+# IBM Thomas J. Watson Research Library
+# Hawthorne, NY
+#
+#
+# Description: Optimized assembly routines for OpenSSL crypto
+# on the 32 bitPowerPC platform.
+#
+#
+# Version History
+#
+# 2. Fixed bn_add,bn_sub and bn_div_words, added comments,
+# cleaned up code. Also made a single version which can
+# be used for both the AIX and Linux compilers. See NOTE
+# below.
+# 12/05/03 Suresh Chari
+# (with lots of help from) Andy Polyakov
+##
+# 1. Initial version 10/20/02 Suresh Chari
+#
+#
+# The following file works for the xlc,cc
+# and gcc compilers.
+#
+# NOTE: To get the file to link correctly with the gcc compiler
+# you have to change the names of the routines and remove
+# the first .(dot) character. This should automatically
+# be done in the build process.
+#
+# Hand optimized assembly code for the following routines
+#
+# bn_sqr_comba4
+# bn_sqr_comba8
+# bn_mul_comba4
+# bn_mul_comba8
+# bn_sub_words
+# bn_add_words
+# bn_div_words
+# bn_sqr_words
+# bn_mul_words
+# bn_mul_add_words
+#
+# NOTE: It is possible to optimize this code more for
+# specific PowerPC or Power architectures. On the Northstar
+# architecture the optimizations in this file do
+# NOT provide much improvement.
+#
+# If you have comments or suggestions to improve code send
+# me a note at schari\@us.ibm.com
+#
+#--------------------------------------------------------------------------
+#
+# Defines to be used in the assembly code.
+#
+.set r0,0 # we use it as storage for value of 0
+.set SP,1 # preserved
+.set RTOC,2 # preserved
+.set r3,3 # 1st argument/return value
+.set r4,4 # 2nd argument/volatile register
+.set r5,5 # 3rd argument/volatile register
+.set r6,6 # ...
+.set r7,7
+.set r8,8
+.set r9,9
+.set r10,10
+.set r11,11
+.set r12,12
+.set r13,13 # not used, nor any other "below" it...
+
+.set BO_IF_NOT,4
+.set BO_IF,12
+.set BO_dCTR_NZERO,16
+.set BO_dCTR_ZERO,18
+.set BO_ALWAYS,20
+.set CR0_LT,0;
+.set CR0_GT,1;
+.set CR0_EQ,2
+.set CR1_FX,4;
+.set CR1_FEX,5;
+.set CR1_VX,6
+.set LR,8
+
+# Declare function names to be global
+# NOTE: For gcc these names MUST be changed to remove
+# the first . i.e. for example change ".bn_sqr_comba4"
+# to "bn_sqr_comba4". This should be automatically done
+# in the build.
+
+ .globl .bn_sqr_comba4
+ .globl .bn_sqr_comba8
+ .globl .bn_mul_comba4
+ .globl .bn_mul_comba8
+ .globl .bn_sub_words
+ .globl .bn_add_words
+ .globl .bn_div_words
+ .globl .bn_sqr_words
+ .globl .bn_mul_words
+ .globl .bn_mul_add_words
+
+# .text section
+
+ .machine $ISA
+
+#
+# NOTE: The following label name should be changed to
+# "bn_sqr_comba4" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+
+.align 4
+.bn_sqr_comba4:
+#
+# Optimized version of bn_sqr_comba4.
+#
+# void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+# r3 contains r
+# r4 contains a
+#
+# Freely use registers r5,r6,r7,r8,r9,r10,r11 as follows:
+#
+# r5,r6 are the two BN_ULONGs being multiplied.
+# r7,r8 are the results of the 32x32 giving 64 bit multiply.
+# r9,r10, r11 are the equivalents of c1,c2, c3.
+# Here's the assembly
+#
+#
+ xor r0,r0,r0 # set r0 = 0. Used in the addze
+ # instructions below
+
+ #sqr_add_c(a,0,c1,c2,c3)
+ $LD r5,`0*$BNSZ`(r4)
+ $UMULL r9,r5,r5
+ $UMULH r10,r5,r5 #in first iteration. No need
+ #to add since c1=c2=c3=0.
+ # Note c3(r11) is NOT set to 0
+ # but will be.
+
+ $ST r9,`0*$BNSZ`(r3) # r[0]=c1;
+ # sqr_add_c2(a,1,0,c2,c3,c1);
+ $LD r6,`1*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r7,r7,r7 # compute (r7,r8)=2*(r7,r8)
+ adde r8,r8,r8
+ addze r9,r0 # catch carry if any.
+ # r9= r0(=0) and carry
+
+ addc r10,r7,r10 # now add to temp result.
+ addze r11,r8 # r8 added to r11 which is 0
+ addze r9,r9
+
+ $ST r10,`1*$BNSZ`(r3) #r[1]=c2;
+ #sqr_add_c(a,1,c3,c1,c2)
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r0
+ #sqr_add_c2(a,2,0,c3,c1,c2)
+ $LD r6,`2*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r7,r7,r7
+ adde r8,r8,r8
+ addze r10,r10
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ $ST r11,`2*$BNSZ`(r3) #r[2]=c3
+ #sqr_add_c2(a,3,0,c1,c2,c3);
+ $LD r6,`3*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r7,r7,r7
+ adde r8,r8,r8
+ addze r11,r0
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ #sqr_add_c2(a,2,1,c1,c2,c3);
+ $LD r5,`1*$BNSZ`(r4)
+ $LD r6,`2*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r7,r7,r7
+ adde r8,r8,r8
+ addze r11,r11
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ $ST r9,`3*$BNSZ`(r3) #r[3]=c1
+ #sqr_add_c(a,2,c2,c3,c1);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r0
+ #sqr_add_c2(a,3,1,c2,c3,c1);
+ $LD r6,`3*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r7,r7,r7
+ adde r8,r8,r8
+ addze r9,r9
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ $ST r10,`4*$BNSZ`(r3) #r[4]=c2
+ #sqr_add_c2(a,3,2,c3,c1,c2);
+ $LD r5,`2*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r7,r7,r7
+ adde r8,r8,r8
+ addze r10,r0
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ $ST r11,`5*$BNSZ`(r3) #r[5] = c3
+ #sqr_add_c(a,3,c1,c2,c3);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r9,r7,r9
+ adde r10,r8,r10
+
+ $ST r9,`6*$BNSZ`(r3) #r[6]=c1
+ $ST r10,`7*$BNSZ`(r3) #r[7]=c2
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+
+#
+# NOTE: The following label name should be changed to
+# "bn_sqr_comba8" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+
+.align 4
+.bn_sqr_comba8:
+#
+# This is an optimized version of the bn_sqr_comba8 routine.
+# Tightly uses the adde instruction
+#
+#
+# void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+# r3 contains r
+# r4 contains a
+#
+# Freely use registers r5,r6,r7,r8,r9,r10,r11 as follows:
+#
+# r5,r6 are the two BN_ULONGs being multiplied.
+# r7,r8 are the results of the 32x32 giving 64 bit multiply.
+# r9,r10, r11 are the equivalents of c1,c2, c3.
+#
+# Possible optimization of loading all 8 longs of a into registers
+# doesnt provide any speedup
+#
+
+ xor r0,r0,r0 #set r0 = 0.Used in addze
+ #instructions below.
+
+ #sqr_add_c(a,0,c1,c2,c3);
+ $LD r5,`0*$BNSZ`(r4)
+ $UMULL r9,r5,r5 #1st iteration: no carries.
+ $UMULH r10,r5,r5
+ $ST r9,`0*$BNSZ`(r3) # r[0]=c1;
+ #sqr_add_c2(a,1,0,c2,c3,c1);
+ $LD r6,`1*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r10,r7,r10 #add the two register number
+ adde r11,r8,r0 # (r8,r7) to the three register
+ addze r9,r0 # number (r9,r11,r10).NOTE:r0=0
+
+ addc r10,r7,r10 #add the two register number
+ adde r11,r8,r11 # (r8,r7) to the three register
+ addze r9,r9 # number (r9,r11,r10).
+
+ $ST r10,`1*$BNSZ`(r3) # r[1]=c2
+
+ #sqr_add_c(a,1,c3,c1,c2);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r0
+ #sqr_add_c2(a,2,0,c3,c1,c2);
+ $LD r6,`2*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+
+ $ST r11,`2*$BNSZ`(r3) #r[2]=c3
+ #sqr_add_c2(a,3,0,c1,c2,c3);
+ $LD r6,`3*$BNSZ`(r4) #r6 = a[3]. r5 is already a[0].
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r0
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ #sqr_add_c2(a,2,1,c1,c2,c3);
+ $LD r5,`1*$BNSZ`(r4)
+ $LD r6,`2*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+
+ $ST r9,`3*$BNSZ`(r3) #r[3]=c1;
+ #sqr_add_c(a,2,c2,c3,c1);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r0
+ #sqr_add_c2(a,3,1,c2,c3,c1);
+ $LD r6,`3*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ #sqr_add_c2(a,4,0,c2,c3,c1);
+ $LD r5,`0*$BNSZ`(r4)
+ $LD r6,`4*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ $ST r10,`4*$BNSZ`(r3) #r[4]=c2;
+ #sqr_add_c2(a,5,0,c3,c1,c2);
+ $LD r6,`5*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r0
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ #sqr_add_c2(a,4,1,c3,c1,c2);
+ $LD r5,`1*$BNSZ`(r4)
+ $LD r6,`4*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ #sqr_add_c2(a,3,2,c3,c1,c2);
+ $LD r5,`2*$BNSZ`(r4)
+ $LD r6,`3*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ $ST r11,`5*$BNSZ`(r3) #r[5]=c3;
+ #sqr_add_c(a,3,c1,c2,c3);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r0
+ #sqr_add_c2(a,4,2,c1,c2,c3);
+ $LD r6,`4*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ #sqr_add_c2(a,5,1,c1,c2,c3);
+ $LD r5,`1*$BNSZ`(r4)
+ $LD r6,`5*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ #sqr_add_c2(a,6,0,c1,c2,c3);
+ $LD r5,`0*$BNSZ`(r4)
+ $LD r6,`6*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ $ST r9,`6*$BNSZ`(r3) #r[6]=c1;
+ #sqr_add_c2(a,7,0,c2,c3,c1);
+ $LD r6,`7*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r0
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ #sqr_add_c2(a,6,1,c2,c3,c1);
+ $LD r5,`1*$BNSZ`(r4)
+ $LD r6,`6*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ #sqr_add_c2(a,5,2,c2,c3,c1);
+ $LD r5,`2*$BNSZ`(r4)
+ $LD r6,`5*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ #sqr_add_c2(a,4,3,c2,c3,c1);
+ $LD r5,`3*$BNSZ`(r4)
+ $LD r6,`4*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ $ST r10,`7*$BNSZ`(r3) #r[7]=c2;
+ #sqr_add_c(a,4,c3,c1,c2);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r0
+ #sqr_add_c2(a,5,3,c3,c1,c2);
+ $LD r6,`5*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ #sqr_add_c2(a,6,2,c3,c1,c2);
+ $LD r5,`2*$BNSZ`(r4)
+ $LD r6,`6*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ #sqr_add_c2(a,7,1,c3,c1,c2);
+ $LD r5,`1*$BNSZ`(r4)
+ $LD r6,`7*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ $ST r11,`8*$BNSZ`(r3) #r[8]=c3;
+ #sqr_add_c2(a,7,2,c1,c2,c3);
+ $LD r5,`2*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r0
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ #sqr_add_c2(a,6,3,c1,c2,c3);
+ $LD r5,`3*$BNSZ`(r4)
+ $LD r6,`6*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ #sqr_add_c2(a,5,4,c1,c2,c3);
+ $LD r5,`4*$BNSZ`(r4)
+ $LD r6,`5*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ $ST r9,`9*$BNSZ`(r3) #r[9]=c1;
+ #sqr_add_c(a,5,c2,c3,c1);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r0
+ #sqr_add_c2(a,6,4,c2,c3,c1);
+ $LD r6,`6*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ #sqr_add_c2(a,7,3,c2,c3,c1);
+ $LD r5,`3*$BNSZ`(r4)
+ $LD r6,`7*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ $ST r10,`10*$BNSZ`(r3) #r[10]=c2;
+ #sqr_add_c2(a,7,4,c3,c1,c2);
+ $LD r5,`4*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r0
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ #sqr_add_c2(a,6,5,c3,c1,c2);
+ $LD r5,`5*$BNSZ`(r4)
+ $LD r6,`6*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ addc r11,r7,r11
+ adde r9,r8,r9
+ addze r10,r10
+ $ST r11,`11*$BNSZ`(r3) #r[11]=c3;
+ #sqr_add_c(a,6,c1,c2,c3);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r0
+ #sqr_add_c2(a,7,5,c1,c2,c3)
+ $LD r6,`7*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ addc r9,r7,r9
+ adde r10,r8,r10
+ addze r11,r11
+ $ST r9,`12*$BNSZ`(r3) #r[12]=c1;
+
+ #sqr_add_c2(a,7,6,c2,c3,c1)
+ $LD r5,`6*$BNSZ`(r4)
+ $UMULL r7,r5,r6
+ $UMULH r8,r5,r6
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r0
+ addc r10,r7,r10
+ adde r11,r8,r11
+ addze r9,r9
+ $ST r10,`13*$BNSZ`(r3) #r[13]=c2;
+ #sqr_add_c(a,7,c3,c1,c2);
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ addc r11,r7,r11
+ adde r9,r8,r9
+ $ST r11,`14*$BNSZ`(r3) #r[14]=c3;
+ $ST r9, `15*$BNSZ`(r3) #r[15]=c1;
+
+
+ bclr BO_ALWAYS,CR0_LT
+
+ .long 0x00000000
+
+#
+# NOTE: The following label name should be changed to
+# "bn_mul_comba4" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+
+.align 4
+.bn_mul_comba4:
+#
+# This is an optimized version of the bn_mul_comba4 routine.
+#
+# void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+# r3 contains r
+# r4 contains a
+# r5 contains b
+# r6, r7 are the 2 BN_ULONGs being multiplied.
+# r8, r9 are the results of the 32x32 giving 64 multiply.
+# r10, r11, r12 are the equivalents of c1, c2, and c3.
+#
+ xor r0,r0,r0 #r0=0. Used in addze below.
+ #mul_add_c(a[0],b[0],c1,c2,c3);
+ $LD r6,`0*$BNSZ`(r4)
+ $LD r7,`0*$BNSZ`(r5)
+ $UMULL r10,r6,r7
+ $UMULH r11,r6,r7
+ $ST r10,`0*$BNSZ`(r3) #r[0]=c1
+ #mul_add_c(a[0],b[1],c2,c3,c1);
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r8,r11
+ adde r12,r9,r0
+ addze r10,r0
+ #mul_add_c(a[1],b[0],c2,c3,c1);
+ $LD r6, `1*$BNSZ`(r4)
+ $LD r7, `0*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r8,r11
+ adde r12,r9,r12
+ addze r10,r10
+ $ST r11,`1*$BNSZ`(r3) #r[1]=c2
+ #mul_add_c(a[2],b[0],c3,c1,c2);
+ $LD r6,`2*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r8,r12
+ adde r10,r9,r10
+ addze r11,r0
+ #mul_add_c(a[1],b[1],c3,c1,c2);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r8,r12
+ adde r10,r9,r10
+ addze r11,r11
+ #mul_add_c(a[0],b[2],c3,c1,c2);
+ $LD r6,`0*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r8,r12
+ adde r10,r9,r10
+ addze r11,r11
+ $ST r12,`2*$BNSZ`(r3) #r[2]=c3
+ #mul_add_c(a[0],b[3],c1,c2,c3);
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r8,r10
+ adde r11,r9,r11
+ addze r12,r0
+ #mul_add_c(a[1],b[2],c1,c2,c3);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r8,r10
+ adde r11,r9,r11
+ addze r12,r12
+ #mul_add_c(a[2],b[1],c1,c2,c3);
+ $LD r6,`2*$BNSZ`(r4)
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r8,r10
+ adde r11,r9,r11
+ addze r12,r12
+ #mul_add_c(a[3],b[0],c1,c2,c3);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`0*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r8,r10
+ adde r11,r9,r11
+ addze r12,r12
+ $ST r10,`3*$BNSZ`(r3) #r[3]=c1
+ #mul_add_c(a[3],b[1],c2,c3,c1);
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r8,r11
+ adde r12,r9,r12
+ addze r10,r0
+ #mul_add_c(a[2],b[2],c2,c3,c1);
+ $LD r6,`2*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r8,r11
+ adde r12,r9,r12
+ addze r10,r10
+ #mul_add_c(a[1],b[3],c2,c3,c1);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r8,r11
+ adde r12,r9,r12
+ addze r10,r10
+ $ST r11,`4*$BNSZ`(r3) #r[4]=c2
+ #mul_add_c(a[2],b[3],c3,c1,c2);
+ $LD r6,`2*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r8,r12
+ adde r10,r9,r10
+ addze r11,r0
+ #mul_add_c(a[3],b[2],c3,c1,c2);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r8,r12
+ adde r10,r9,r10
+ addze r11,r11
+ $ST r12,`5*$BNSZ`(r3) #r[5]=c3
+ #mul_add_c(a[3],b[3],c1,c2,c3);
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r8,r10
+ adde r11,r9,r11
+
+ $ST r10,`6*$BNSZ`(r3) #r[6]=c1
+ $ST r11,`7*$BNSZ`(r3) #r[7]=c2
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+
+#
+# NOTE: The following label name should be changed to
+# "bn_mul_comba8" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+
+.align 4
+.bn_mul_comba8:
+#
+# Optimized version of the bn_mul_comba8 routine.
+#
+# void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+# r3 contains r
+# r4 contains a
+# r5 contains b
+# r6, r7 are the 2 BN_ULONGs being multiplied.
+# r8, r9 are the results of the 32x32 giving 64 multiply.
+# r10, r11, r12 are the equivalents of c1, c2, and c3.
+#
+ xor r0,r0,r0 #r0=0. Used in addze below.
+
+ #mul_add_c(a[0],b[0],c1,c2,c3);
+ $LD r6,`0*$BNSZ`(r4) #a[0]
+ $LD r7,`0*$BNSZ`(r5) #b[0]
+ $UMULL r10,r6,r7
+ $UMULH r11,r6,r7
+ $ST r10,`0*$BNSZ`(r3) #r[0]=c1;
+ #mul_add_c(a[0],b[1],c2,c3,c1);
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ addze r12,r9 # since we didnt set r12 to zero before.
+ addze r10,r0
+ #mul_add_c(a[1],b[0],c2,c3,c1);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`0*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ $ST r11,`1*$BNSZ`(r3) #r[1]=c2;
+ #mul_add_c(a[2],b[0],c3,c1,c2);
+ $LD r6,`2*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r0
+ #mul_add_c(a[1],b[1],c3,c1,c2);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[0],b[2],c3,c1,c2);
+ $LD r6,`0*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ $ST r12,`2*$BNSZ`(r3) #r[2]=c3;
+ #mul_add_c(a[0],b[3],c1,c2,c3);
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r0
+ #mul_add_c(a[1],b[2],c1,c2,c3);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+
+ #mul_add_c(a[2],b[1],c1,c2,c3);
+ $LD r6,`2*$BNSZ`(r4)
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[3],b[0],c1,c2,c3);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`0*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ $ST r10,`3*$BNSZ`(r3) #r[3]=c1;
+ #mul_add_c(a[4],b[0],c2,c3,c1);
+ $LD r6,`4*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r0
+ #mul_add_c(a[3],b[1],c2,c3,c1);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[2],b[2],c2,c3,c1);
+ $LD r6,`2*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[1],b[3],c2,c3,c1);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[0],b[4],c2,c3,c1);
+ $LD r6,`0*$BNSZ`(r4)
+ $LD r7,`4*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ $ST r11,`4*$BNSZ`(r3) #r[4]=c2;
+ #mul_add_c(a[0],b[5],c3,c1,c2);
+ $LD r7,`5*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r0
+ #mul_add_c(a[1],b[4],c3,c1,c2);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`4*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[2],b[3],c3,c1,c2);
+ $LD r6,`2*$BNSZ`(r4)
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[3],b[2],c3,c1,c2);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[4],b[1],c3,c1,c2);
+ $LD r6,`4*$BNSZ`(r4)
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[5],b[0],c3,c1,c2);
+ $LD r6,`5*$BNSZ`(r4)
+ $LD r7,`0*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ $ST r12,`5*$BNSZ`(r3) #r[5]=c3;
+ #mul_add_c(a[6],b[0],c1,c2,c3);
+ $LD r6,`6*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r0
+ #mul_add_c(a[5],b[1],c1,c2,c3);
+ $LD r6,`5*$BNSZ`(r4)
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[4],b[2],c1,c2,c3);
+ $LD r6,`4*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[3],b[3],c1,c2,c3);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[2],b[4],c1,c2,c3);
+ $LD r6,`2*$BNSZ`(r4)
+ $LD r7,`4*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[1],b[5],c1,c2,c3);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`5*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[0],b[6],c1,c2,c3);
+ $LD r6,`0*$BNSZ`(r4)
+ $LD r7,`6*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ $ST r10,`6*$BNSZ`(r3) #r[6]=c1;
+ #mul_add_c(a[0],b[7],c2,c3,c1);
+ $LD r7,`7*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r0
+ #mul_add_c(a[1],b[6],c2,c3,c1);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`6*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[2],b[5],c2,c3,c1);
+ $LD r6,`2*$BNSZ`(r4)
+ $LD r7,`5*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[3],b[4],c2,c3,c1);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`4*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[4],b[3],c2,c3,c1);
+ $LD r6,`4*$BNSZ`(r4)
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[5],b[2],c2,c3,c1);
+ $LD r6,`5*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[6],b[1],c2,c3,c1);
+ $LD r6,`6*$BNSZ`(r4)
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[7],b[0],c2,c3,c1);
+ $LD r6,`7*$BNSZ`(r4)
+ $LD r7,`0*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ $ST r11,`7*$BNSZ`(r3) #r[7]=c2;
+ #mul_add_c(a[7],b[1],c3,c1,c2);
+ $LD r7,`1*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r0
+ #mul_add_c(a[6],b[2],c3,c1,c2);
+ $LD r6,`6*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[5],b[3],c3,c1,c2);
+ $LD r6,`5*$BNSZ`(r4)
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[4],b[4],c3,c1,c2);
+ $LD r6,`4*$BNSZ`(r4)
+ $LD r7,`4*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[3],b[5],c3,c1,c2);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`5*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[2],b[6],c3,c1,c2);
+ $LD r6,`2*$BNSZ`(r4)
+ $LD r7,`6*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[1],b[7],c3,c1,c2);
+ $LD r6,`1*$BNSZ`(r4)
+ $LD r7,`7*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ $ST r12,`8*$BNSZ`(r3) #r[8]=c3;
+ #mul_add_c(a[2],b[7],c1,c2,c3);
+ $LD r6,`2*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r0
+ #mul_add_c(a[3],b[6],c1,c2,c3);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`6*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[4],b[5],c1,c2,c3);
+ $LD r6,`4*$BNSZ`(r4)
+ $LD r7,`5*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[5],b[4],c1,c2,c3);
+ $LD r6,`5*$BNSZ`(r4)
+ $LD r7,`4*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[6],b[3],c1,c2,c3);
+ $LD r6,`6*$BNSZ`(r4)
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[7],b[2],c1,c2,c3);
+ $LD r6,`7*$BNSZ`(r4)
+ $LD r7,`2*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ $ST r10,`9*$BNSZ`(r3) #r[9]=c1;
+ #mul_add_c(a[7],b[3],c2,c3,c1);
+ $LD r7,`3*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r0
+ #mul_add_c(a[6],b[4],c2,c3,c1);
+ $LD r6,`6*$BNSZ`(r4)
+ $LD r7,`4*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[5],b[5],c2,c3,c1);
+ $LD r6,`5*$BNSZ`(r4)
+ $LD r7,`5*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[4],b[6],c2,c3,c1);
+ $LD r6,`4*$BNSZ`(r4)
+ $LD r7,`6*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ #mul_add_c(a[3],b[7],c2,c3,c1);
+ $LD r6,`3*$BNSZ`(r4)
+ $LD r7,`7*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ $ST r11,`10*$BNSZ`(r3) #r[10]=c2;
+ #mul_add_c(a[4],b[7],c3,c1,c2);
+ $LD r6,`4*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r0
+ #mul_add_c(a[5],b[6],c3,c1,c2);
+ $LD r6,`5*$BNSZ`(r4)
+ $LD r7,`6*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[6],b[5],c3,c1,c2);
+ $LD r6,`6*$BNSZ`(r4)
+ $LD r7,`5*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ #mul_add_c(a[7],b[4],c3,c1,c2);
+ $LD r6,`7*$BNSZ`(r4)
+ $LD r7,`4*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ addze r11,r11
+ $ST r12,`11*$BNSZ`(r3) #r[11]=c3;
+ #mul_add_c(a[7],b[5],c1,c2,c3);
+ $LD r7,`5*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r0
+ #mul_add_c(a[6],b[6],c1,c2,c3);
+ $LD r6,`6*$BNSZ`(r4)
+ $LD r7,`6*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ #mul_add_c(a[5],b[7],c1,c2,c3);
+ $LD r6,`5*$BNSZ`(r4)
+ $LD r7,`7*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r10,r10,r8
+ adde r11,r11,r9
+ addze r12,r12
+ $ST r10,`12*$BNSZ`(r3) #r[12]=c1;
+ #mul_add_c(a[6],b[7],c2,c3,c1);
+ $LD r6,`6*$BNSZ`(r4)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r0
+ #mul_add_c(a[7],b[6],c2,c3,c1);
+ $LD r6,`7*$BNSZ`(r4)
+ $LD r7,`6*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r11,r11,r8
+ adde r12,r12,r9
+ addze r10,r10
+ $ST r11,`13*$BNSZ`(r3) #r[13]=c2;
+ #mul_add_c(a[7],b[7],c3,c1,c2);
+ $LD r7,`7*$BNSZ`(r5)
+ $UMULL r8,r6,r7
+ $UMULH r9,r6,r7
+ addc r12,r12,r8
+ adde r10,r10,r9
+ $ST r12,`14*$BNSZ`(r3) #r[14]=c3;
+ $ST r10,`15*$BNSZ`(r3) #r[15]=c1;
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+
+#
+# NOTE: The following label name should be changed to
+# "bn_sub_words" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+#
+.align 4
+.bn_sub_words:
+#
+# Handcoded version of bn_sub_words
+#
+#BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+#
+# r3 = r
+# r4 = a
+# r5 = b
+# r6 = n
+#
+# Note: No loop unrolling done since this is not a performance
+# critical loop.
+
+ xor r0,r0,r0 #set r0 = 0
+#
+# check for r6 = 0 AND set carry bit.
+#
+ subfc. r7,r0,r6 # If r6 is 0 then result is 0.
+ # if r6 > 0 then result !=0
+ # In either case carry bit is set.
+ bc BO_IF,CR0_EQ,Lppcasm_sub_adios
+ addi r4,r4,-$BNSZ
+ addi r3,r3,-$BNSZ
+ addi r5,r5,-$BNSZ
+ mtctr r6
+Lppcasm_sub_mainloop:
+ $LDU r7,$BNSZ(r4)
+ $LDU r8,$BNSZ(r5)
+ subfe r6,r8,r7 # r6 = r7+carry bit + onescomplement(r8)
+ # if carry = 1 this is r7-r8. Else it
+ # is r7-r8 -1 as we need.
+ $STU r6,$BNSZ(r3)
+ bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_sub_mainloop
+Lppcasm_sub_adios:
+ subfze r3,r0 # if carry bit is set then r3 = 0 else -1
+ andi. r3,r3,1 # keep only last bit.
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+
+
+#
+# NOTE: The following label name should be changed to
+# "bn_add_words" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+
+.align 4
+.bn_add_words:
+#
+# Handcoded version of bn_add_words
+#
+#BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+#
+# r3 = r
+# r4 = a
+# r5 = b
+# r6 = n
+#
+# Note: No loop unrolling done since this is not a performance
+# critical loop.
+
+ xor r0,r0,r0
+#
+# check for r6 = 0. Is this needed?
+#
+ addic. r6,r6,0 #test r6 and clear carry bit.
+ bc BO_IF,CR0_EQ,Lppcasm_add_adios
+ addi r4,r4,-$BNSZ
+ addi r3,r3,-$BNSZ
+ addi r5,r5,-$BNSZ
+ mtctr r6
+Lppcasm_add_mainloop:
+ $LDU r7,$BNSZ(r4)
+ $LDU r8,$BNSZ(r5)
+ adde r8,r7,r8
+ $STU r8,$BNSZ(r3)
+ bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_add_mainloop
+Lppcasm_add_adios:
+ addze r3,r0 #return carry bit.
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+
+#
+# NOTE: The following label name should be changed to
+# "bn_div_words" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+
+.align 4
+.bn_div_words:
+#
+# This is a cleaned up version of code generated by
+# the AIX compiler. The only optimization is to use
+# the PPC instruction to count leading zeros instead
+# of call to num_bits_word. Since this was compiled
+# only at level -O2 we can possibly squeeze it more?
+#
+# r3 = h
+# r4 = l
+# r5 = d
+
+ $UCMPI 0,r5,0 # compare r5 and 0
+ bc BO_IF_NOT,CR0_EQ,Lppcasm_div1 # proceed if d!=0
+ li r3,-1 # d=0 return -1
+ bclr BO_ALWAYS,CR0_LT
+Lppcasm_div1:
+ xor r0,r0,r0 #r0=0
+ li r8,$BITS
+ $CNTLZ. r7,r5 #r7 = num leading 0s in d.
+ bc BO_IF,CR0_EQ,Lppcasm_div2 #proceed if no leading zeros
+ subf r8,r7,r8 #r8 = BN_num_bits_word(d)
+ $SHR. r9,r3,r8 #are there any bits above r8'th?
+ $TR 16,r9,r0 #if there're, signal to dump core...
+Lppcasm_div2:
+ $UCMP 0,r3,r5 #h>=d?
+ bc BO_IF,CR0_LT,Lppcasm_div3 #goto Lppcasm_div3 if not
+ subf r3,r5,r3 #h-=d ;
+Lppcasm_div3: #r7 = BN_BITS2-i. so r7=i
+ cmpi 0,0,r7,0 # is (i == 0)?
+ bc BO_IF,CR0_EQ,Lppcasm_div4
+ $SHL r3,r3,r7 # h = (h<< i)
+ $SHR r8,r4,r8 # r8 = (l >> BN_BITS2 -i)
+ $SHL r5,r5,r7 # d<<=i
+ or r3,r3,r8 # h = (h<<i)|(l>>(BN_BITS2-i))
+ $SHL r4,r4,r7 # l <<=i
+Lppcasm_div4:
+ $SHRI r9,r5,`$BITS/2` # r9 = dh
+ # dl will be computed when needed
+ # as it saves registers.
+ li r6,2 #r6=2
+ mtctr r6 #counter will be in count.
+Lppcasm_divouterloop:
+ $SHRI r8,r3,`$BITS/2` #r8 = (h>>BN_BITS4)
+ $SHRI r11,r4,`$BITS/2` #r11= (l&BN_MASK2h)>>BN_BITS4
+ # compute here for innerloop.
+ $UCMP 0,r8,r9 # is (h>>BN_BITS4)==dh
+ bc BO_IF_NOT,CR0_EQ,Lppcasm_div5 # goto Lppcasm_div5 if not
+
+ li r8,-1
+ $CLRU r8,r8,`$BITS/2` #q = BN_MASK2l
+ b Lppcasm_div6
+Lppcasm_div5:
+ $UDIV r8,r3,r9 #q = h/dh
+Lppcasm_div6:
+ $UMULL r12,r9,r8 #th = q*dh
+ $CLRU r10,r5,`$BITS/2` #r10=dl
+ $UMULL r6,r8,r10 #tl = q*dl
+
+Lppcasm_divinnerloop:
+ subf r10,r12,r3 #t = h -th
+ $SHRI r7,r10,`$BITS/2` #r7= (t &BN_MASK2H), sort of...
+ addic. r7,r7,0 #test if r7 == 0. used below.
+ # now want to compute
+ # r7 = (t<<BN_BITS4)|((l&BN_MASK2h)>>BN_BITS4)
+ # the following 2 instructions do that
+ $SHLI r7,r10,`$BITS/2` # r7 = (t<<BN_BITS4)
+ or r7,r7,r11 # r7|=((l&BN_MASK2h)>>BN_BITS4)
+ $UCMP 1,r6,r7 # compare (tl <= r7)
+ bc BO_IF_NOT,CR0_EQ,Lppcasm_divinnerexit
+ bc BO_IF_NOT,CR1_FEX,Lppcasm_divinnerexit
+ addi r8,r8,-1 #q--
+ subf r12,r9,r12 #th -=dh
+ $CLRU r10,r5,`$BITS/2` #r10=dl. t is no longer needed in loop.
+ subf r6,r10,r6 #tl -=dl
+ b Lppcasm_divinnerloop
+Lppcasm_divinnerexit:
+ $SHRI r10,r6,`$BITS/2` #t=(tl>>BN_BITS4)
+ $SHLI r11,r6,`$BITS/2` #tl=(tl<<BN_BITS4)&BN_MASK2h;
+ $UCMP 1,r4,r11 # compare l and tl
+ add r12,r12,r10 # th+=t
+ bc BO_IF_NOT,CR1_FX,Lppcasm_div7 # if (l>=tl) goto Lppcasm_div7
+ addi r12,r12,1 # th++
+Lppcasm_div7:
+ subf r11,r11,r4 #r11=l-tl
+ $UCMP 1,r3,r12 #compare h and th
+ bc BO_IF_NOT,CR1_FX,Lppcasm_div8 #if (h>=th) goto Lppcasm_div8
+ addi r8,r8,-1 # q--
+ add r3,r5,r3 # h+=d
+Lppcasm_div8:
+ subf r12,r12,r3 #r12 = h-th
+ $SHLI r4,r11,`$BITS/2` #l=(l&BN_MASK2l)<<BN_BITS4
+ # want to compute
+ # h = ((h<<BN_BITS4)|(l>>BN_BITS4))&BN_MASK2
+ # the following 2 instructions will do this.
+ $INSR r11,r12,`$BITS/2`,`$BITS/2` # r11 is the value we want rotated $BITS/2.
+ $ROTL r3,r11,`$BITS/2` # rotate by $BITS/2 and store in r3
+ bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_div9#if (count==0) break ;
+ $SHLI r0,r8,`$BITS/2` #ret =q<<BN_BITS4
+ b Lppcasm_divouterloop
+Lppcasm_div9:
+ or r3,r8,r0
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+
+#
+# NOTE: The following label name should be changed to
+# "bn_sqr_words" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+.align 4
+.bn_sqr_words:
+#
+# Optimized version of bn_sqr_words
+#
+# void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+#
+# r3 = r
+# r4 = a
+# r5 = n
+#
+# r6 = a[i].
+# r7,r8 = product.
+#
+# No unrolling done here. Not performance critical.
+
+ addic. r5,r5,0 #test r5.
+ bc BO_IF,CR0_EQ,Lppcasm_sqr_adios
+ addi r4,r4,-$BNSZ
+ addi r3,r3,-$BNSZ
+ mtctr r5
+Lppcasm_sqr_mainloop:
+ #sqr(r[0],r[1],a[0]);
+ $LDU r6,$BNSZ(r4)
+ $UMULL r7,r6,r6
+ $UMULH r8,r6,r6
+ $STU r7,$BNSZ(r3)
+ $STU r8,$BNSZ(r3)
+ bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_sqr_mainloop
+Lppcasm_sqr_adios:
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+
+
+#
+# NOTE: The following label name should be changed to
+# "bn_mul_words" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+
+.align 4
+.bn_mul_words:
+#
+# BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+#
+# r3 = rp
+# r4 = ap
+# r5 = num
+# r6 = w
+ xor r0,r0,r0
+ xor r12,r12,r12 # used for carry
+ rlwinm. r7,r5,30,2,31 # num >> 2
+ bc BO_IF,CR0_EQ,Lppcasm_mw_REM
+ mtctr r7
+Lppcasm_mw_LOOP:
+ #mul(rp[0],ap[0],w,c1);
+ $LD r8,`0*$BNSZ`(r4)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ addc r9,r9,r12
+ #addze r10,r10 #carry is NOT ignored.
+ #will be taken care of
+ #in second spin below
+ #using adde.
+ $ST r9,`0*$BNSZ`(r3)
+ #mul(rp[1],ap[1],w,c1);
+ $LD r8,`1*$BNSZ`(r4)
+ $UMULL r11,r6,r8
+ $UMULH r12,r6,r8
+ adde r11,r11,r10
+ #addze r12,r12
+ $ST r11,`1*$BNSZ`(r3)
+ #mul(rp[2],ap[2],w,c1);
+ $LD r8,`2*$BNSZ`(r4)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ adde r9,r9,r12
+ #addze r10,r10
+ $ST r9,`2*$BNSZ`(r3)
+ #mul_add(rp[3],ap[3],w,c1);
+ $LD r8,`3*$BNSZ`(r4)
+ $UMULL r11,r6,r8
+ $UMULH r12,r6,r8
+ adde r11,r11,r10
+ addze r12,r12 #this spin we collect carry into
+ #r12
+ $ST r11,`3*$BNSZ`(r3)
+
+ addi r3,r3,`4*$BNSZ`
+ addi r4,r4,`4*$BNSZ`
+ bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_mw_LOOP
+
+Lppcasm_mw_REM:
+ andi. r5,r5,0x3
+ bc BO_IF,CR0_EQ,Lppcasm_mw_OVER
+ #mul(rp[0],ap[0],w,c1);
+ $LD r8,`0*$BNSZ`(r4)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ addc r9,r9,r12
+ addze r10,r10
+ $ST r9,`0*$BNSZ`(r3)
+ addi r12,r10,0
+
+ addi r5,r5,-1
+ cmpli 0,0,r5,0
+ bc BO_IF,CR0_EQ,Lppcasm_mw_OVER
+
+
+ #mul(rp[1],ap[1],w,c1);
+ $LD r8,`1*$BNSZ`(r4)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ addc r9,r9,r12
+ addze r10,r10
+ $ST r9,`1*$BNSZ`(r3)
+ addi r12,r10,0
+
+ addi r5,r5,-1
+ cmpli 0,0,r5,0
+ bc BO_IF,CR0_EQ,Lppcasm_mw_OVER
+
+ #mul_add(rp[2],ap[2],w,c1);
+ $LD r8,`2*$BNSZ`(r4)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ addc r9,r9,r12
+ addze r10,r10
+ $ST r9,`2*$BNSZ`(r3)
+ addi r12,r10,0
+
+Lppcasm_mw_OVER:
+ addi r3,r12,0
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+
+#
+# NOTE: The following label name should be changed to
+# "bn_mul_add_words" i.e. remove the first dot
+# for the gcc compiler. This should be automatically
+# done in the build
+#
+
+.align 4
+.bn_mul_add_words:
+#
+# BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+#
+# r3 = rp
+# r4 = ap
+# r5 = num
+# r6 = w
+#
+# empirical evidence suggests that unrolled version performs best!!
+#
+ xor r0,r0,r0 #r0 = 0
+ xor r12,r12,r12 #r12 = 0 . used for carry
+ rlwinm. r7,r5,30,2,31 # num >> 2
+ bc BO_IF,CR0_EQ,Lppcasm_maw_leftover # if (num < 4) go LPPCASM_maw_leftover
+ mtctr r7
+Lppcasm_maw_mainloop:
+ #mul_add(rp[0],ap[0],w,c1);
+ $LD r8,`0*$BNSZ`(r4)
+ $LD r11,`0*$BNSZ`(r3)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ addc r9,r9,r12 #r12 is carry.
+ addze r10,r10
+ addc r9,r9,r11
+ #addze r10,r10
+ #the above instruction addze
+ #is NOT needed. Carry will NOT
+ #be ignored. It's not affected
+ #by multiply and will be collected
+ #in the next spin
+ $ST r9,`0*$BNSZ`(r3)
+
+ #mul_add(rp[1],ap[1],w,c1);
+ $LD r8,`1*$BNSZ`(r4)
+ $LD r9,`1*$BNSZ`(r3)
+ $UMULL r11,r6,r8
+ $UMULH r12,r6,r8
+ adde r11,r11,r10 #r10 is carry.
+ addze r12,r12
+ addc r11,r11,r9
+ #addze r12,r12
+ $ST r11,`1*$BNSZ`(r3)
+
+ #mul_add(rp[2],ap[2],w,c1);
+ $LD r8,`2*$BNSZ`(r4)
+ $UMULL r9,r6,r8
+ $LD r11,`2*$BNSZ`(r3)
+ $UMULH r10,r6,r8
+ adde r9,r9,r12
+ addze r10,r10
+ addc r9,r9,r11
+ #addze r10,r10
+ $ST r9,`2*$BNSZ`(r3)
+
+ #mul_add(rp[3],ap[3],w,c1);
+ $LD r8,`3*$BNSZ`(r4)
+ $UMULL r11,r6,r8
+ $LD r9,`3*$BNSZ`(r3)
+ $UMULH r12,r6,r8
+ adde r11,r11,r10
+ addze r12,r12
+ addc r11,r11,r9
+ addze r12,r12
+ $ST r11,`3*$BNSZ`(r3)
+ addi r3,r3,`4*$BNSZ`
+ addi r4,r4,`4*$BNSZ`
+ bc BO_dCTR_NZERO,CR0_EQ,Lppcasm_maw_mainloop
+
+Lppcasm_maw_leftover:
+ andi. r5,r5,0x3
+ bc BO_IF,CR0_EQ,Lppcasm_maw_adios
+ addi r3,r3,-$BNSZ
+ addi r4,r4,-$BNSZ
+ #mul_add(rp[0],ap[0],w,c1);
+ mtctr r5
+ $LDU r8,$BNSZ(r4)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ $LDU r11,$BNSZ(r3)
+ addc r9,r9,r11
+ addze r10,r10
+ addc r9,r9,r12
+ addze r12,r10
+ $ST r9,0(r3)
+
+ bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_maw_adios
+ #mul_add(rp[1],ap[1],w,c1);
+ $LDU r8,$BNSZ(r4)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ $LDU r11,$BNSZ(r3)
+ addc r9,r9,r11
+ addze r10,r10
+ addc r9,r9,r12
+ addze r12,r10
+ $ST r9,0(r3)
+
+ bc BO_dCTR_ZERO,CR0_EQ,Lppcasm_maw_adios
+ #mul_add(rp[2],ap[2],w,c1);
+ $LDU r8,$BNSZ(r4)
+ $UMULL r9,r6,r8
+ $UMULH r10,r6,r8
+ $LDU r11,$BNSZ(r3)
+ addc r9,r9,r11
+ addze r10,r10
+ addc r9,r9,r12
+ addze r12,r10
+ $ST r9,0(r3)
+
+Lppcasm_maw_adios:
+ addi r3,r12,0
+ bclr BO_ALWAYS,CR0_LT
+ .long 0x00000000
+ .align 4
+EOF
+ $data =~ s/\`([^\`]*)\`/eval $1/gem;
+
+ # if some assembler chokes on some simplified mnemonic,
+ # this is the spot to fix it up, e.g.:
+ # GNU as doesn't seem to accept cmplw, 32-bit unsigned compare
+ $data =~ s/^(\s*)cmplw(\s+)([^,]+),(.*)/$1cmpl$2$3,0,$4/gm;
+ # assembler X doesn't accept li, load immediate value
+ #$data =~ s/^(\s*)li(\s+)([^,]+),(.*)/$1addi$2$3,0,$4/gm;
+ return($data);
+}
diff --git a/openssl/trunk/crypto/bn/asm/sparcv8.S b/openssl/trunk/crypto/bn/asm/sparcv8.S
new file mode 100644
index 00000000..88c5dc48
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/sparcv8.S
@@ -0,0 +1,1458 @@
+.ident "sparcv8.s, Version 1.4"
+.ident "SPARC v8 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+/*
+ * ====================================================================
+ * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+ * project.
+ *
+ * Rights for redistribution and usage in source and binary forms are
+ * granted according to the OpenSSL license. Warranty of any kind is
+ * disclaimed.
+ * ====================================================================
+ */
+
+/*
+ * This is my modest contributon to OpenSSL project (see
+ * http://www.openssl.org/ for more information about it) and is
+ * a drop-in SuperSPARC ISA replacement for crypto/bn/bn_asm.c
+ * module. For updates see http://fy.chalmers.se/~appro/hpe/.
+ *
+ * See bn_asm.sparc.v8plus.S for more details.
+ */
+
+/*
+ * Revision history.
+ *
+ * 1.1 - new loop unrolling model(*);
+ * 1.2 - made gas friendly;
+ * 1.3 - fixed problem with /usr/ccs/lib/cpp;
+ * 1.4 - some retunes;
+ *
+ * (*) see bn_asm.sparc.v8plus.S for details
+ */
+
+.section ".text",#alloc,#execinstr
+.file "bn_asm.sparc.v8.S"
+
+.align 32
+
+.global bn_mul_add_words
+/*
+ * BN_ULONG bn_mul_add_words(rp,ap,num,w)
+ * BN_ULONG *rp,*ap;
+ * int num;
+ * BN_ULONG w;
+ */
+bn_mul_add_words:
+ cmp %o2,0
+ bg,a .L_bn_mul_add_words_proceed
+ ld [%o1],%g2
+ retl
+ clr %o0
+
+.L_bn_mul_add_words_proceed:
+ andcc %o2,-4,%g0
+ bz .L_bn_mul_add_words_tail
+ clr %o5
+
+.L_bn_mul_add_words_loop:
+ ld [%o0],%o4
+ ld [%o1+4],%g3
+ umul %o3,%g2,%g2
+ rd %y,%g1
+ addcc %o4,%o5,%o4
+ addx %g1,0,%g1
+ addcc %o4,%g2,%o4
+ st %o4,[%o0]
+ addx %g1,0,%o5
+
+ ld [%o0+4],%o4
+ ld [%o1+8],%g2
+ umul %o3,%g3,%g3
+ dec 4,%o2
+ rd %y,%g1
+ addcc %o4,%o5,%o4
+ addx %g1,0,%g1
+ addcc %o4,%g3,%o4
+ st %o4,[%o0+4]
+ addx %g1,0,%o5
+
+ ld [%o0+8],%o4
+ ld [%o1+12],%g3
+ umul %o3,%g2,%g2
+ inc 16,%o1
+ rd %y,%g1
+ addcc %o4,%o5,%o4
+ addx %g1,0,%g1
+ addcc %o4,%g2,%o4
+ st %o4,[%o0+8]
+ addx %g1,0,%o5
+
+ ld [%o0+12],%o4
+ umul %o3,%g3,%g3
+ inc 16,%o0
+ rd %y,%g1
+ addcc %o4,%o5,%o4
+ addx %g1,0,%g1
+ addcc %o4,%g3,%o4
+ st %o4,[%o0-4]
+ addx %g1,0,%o5
+ andcc %o2,-4,%g0
+ bnz,a .L_bn_mul_add_words_loop
+ ld [%o1],%g2
+
+ tst %o2
+ bnz,a .L_bn_mul_add_words_tail
+ ld [%o1],%g2
+.L_bn_mul_add_words_return:
+ retl
+ mov %o5,%o0
+ nop
+
+.L_bn_mul_add_words_tail:
+ ld [%o0],%o4
+ umul %o3,%g2,%g2
+ addcc %o4,%o5,%o4
+ rd %y,%g1
+ addx %g1,0,%g1
+ addcc %o4,%g2,%o4
+ addx %g1,0,%o5
+ deccc %o2
+ bz .L_bn_mul_add_words_return
+ st %o4,[%o0]
+
+ ld [%o1+4],%g2
+ ld [%o0+4],%o4
+ umul %o3,%g2,%g2
+ rd %y,%g1
+ addcc %o4,%o5,%o4
+ addx %g1,0,%g1
+ addcc %o4,%g2,%o4
+ addx %g1,0,%o5
+ deccc %o2
+ bz .L_bn_mul_add_words_return
+ st %o4,[%o0+4]
+
+ ld [%o1+8],%g2
+ ld [%o0+8],%o4
+ umul %o3,%g2,%g2
+ rd %y,%g1
+ addcc %o4,%o5,%o4
+ addx %g1,0,%g1
+ addcc %o4,%g2,%o4
+ st %o4,[%o0+8]
+ retl
+ addx %g1,0,%o0
+
+.type bn_mul_add_words,#function
+.size bn_mul_add_words,(.-bn_mul_add_words)
+
+.align 32
+
+.global bn_mul_words
+/*
+ * BN_ULONG bn_mul_words(rp,ap,num,w)
+ * BN_ULONG *rp,*ap;
+ * int num;
+ * BN_ULONG w;
+ */
+bn_mul_words:
+ cmp %o2,0
+ bg,a .L_bn_mul_words_proceeed
+ ld [%o1],%g2
+ retl
+ clr %o0
+
+.L_bn_mul_words_proceeed:
+ andcc %o2,-4,%g0
+ bz .L_bn_mul_words_tail
+ clr %o5
+
+.L_bn_mul_words_loop:
+ ld [%o1+4],%g3
+ umul %o3,%g2,%g2
+ addcc %g2,%o5,%g2
+ rd %y,%g1
+ addx %g1,0,%o5
+ st %g2,[%o0]
+
+ ld [%o1+8],%g2
+ umul %o3,%g3,%g3
+ addcc %g3,%o5,%g3
+ rd %y,%g1
+ dec 4,%o2
+ addx %g1,0,%o5
+ st %g3,[%o0+4]
+
+ ld [%o1+12],%g3
+ umul %o3,%g2,%g2
+ addcc %g2,%o5,%g2
+ rd %y,%g1
+ inc 16,%o1
+ st %g2,[%o0+8]
+ addx %g1,0,%o5
+
+ umul %o3,%g3,%g3
+ addcc %g3,%o5,%g3
+ rd %y,%g1
+ inc 16,%o0
+ addx %g1,0,%o5
+ st %g3,[%o0-4]
+ andcc %o2,-4,%g0
+ nop
+ bnz,a .L_bn_mul_words_loop
+ ld [%o1],%g2
+
+ tst %o2
+ bnz,a .L_bn_mul_words_tail
+ ld [%o1],%g2
+.L_bn_mul_words_return:
+ retl
+ mov %o5,%o0
+ nop
+
+.L_bn_mul_words_tail:
+ umul %o3,%g2,%g2
+ addcc %g2,%o5,%g2
+ rd %y,%g1
+ addx %g1,0,%o5
+ deccc %o2
+ bz .L_bn_mul_words_return
+ st %g2,[%o0]
+ nop
+
+ ld [%o1+4],%g2
+ umul %o3,%g2,%g2
+ addcc %g2,%o5,%g2
+ rd %y,%g1
+ addx %g1,0,%o5
+ deccc %o2
+ bz .L_bn_mul_words_return
+ st %g2,[%o0+4]
+
+ ld [%o1+8],%g2
+ umul %o3,%g2,%g2
+ addcc %g2,%o5,%g2
+ rd %y,%g1
+ st %g2,[%o0+8]
+ retl
+ addx %g1,0,%o0
+
+.type bn_mul_words,#function
+.size bn_mul_words,(.-bn_mul_words)
+
+.align 32
+.global bn_sqr_words
+/*
+ * void bn_sqr_words(r,a,n)
+ * BN_ULONG *r,*a;
+ * int n;
+ */
+bn_sqr_words:
+ cmp %o2,0
+ bg,a .L_bn_sqr_words_proceeed
+ ld [%o1],%g2
+ retl
+ clr %o0
+
+.L_bn_sqr_words_proceeed:
+ andcc %o2,-4,%g0
+ bz .L_bn_sqr_words_tail
+ clr %o5
+
+.L_bn_sqr_words_loop:
+ ld [%o1+4],%g3
+ umul %g2,%g2,%o4
+ st %o4,[%o0]
+ rd %y,%o5
+ st %o5,[%o0+4]
+
+ ld [%o1+8],%g2
+ umul %g3,%g3,%o4
+ dec 4,%o2
+ st %o4,[%o0+8]
+ rd %y,%o5
+ st %o5,[%o0+12]
+ nop
+
+ ld [%o1+12],%g3
+ umul %g2,%g2,%o4
+ st %o4,[%o0+16]
+ rd %y,%o5
+ inc 16,%o1
+ st %o5,[%o0+20]
+
+ umul %g3,%g3,%o4
+ inc 32,%o0
+ st %o4,[%o0-8]
+ rd %y,%o5
+ st %o5,[%o0-4]
+ andcc %o2,-4,%g2
+ bnz,a .L_bn_sqr_words_loop
+ ld [%o1],%g2
+
+ tst %o2
+ nop
+ bnz,a .L_bn_sqr_words_tail
+ ld [%o1],%g2
+.L_bn_sqr_words_return:
+ retl
+ clr %o0
+
+.L_bn_sqr_words_tail:
+ umul %g2,%g2,%o4
+ st %o4,[%o0]
+ deccc %o2
+ rd %y,%o5
+ bz .L_bn_sqr_words_return
+ st %o5,[%o0+4]
+
+ ld [%o1+4],%g2
+ umul %g2,%g2,%o4
+ st %o4,[%o0+8]
+ deccc %o2
+ rd %y,%o5
+ nop
+ bz .L_bn_sqr_words_return
+ st %o5,[%o0+12]
+
+ ld [%o1+8],%g2
+ umul %g2,%g2,%o4
+ st %o4,[%o0+16]
+ rd %y,%o5
+ st %o5,[%o0+20]
+ retl
+ clr %o0
+
+.type bn_sqr_words,#function
+.size bn_sqr_words,(.-bn_sqr_words)
+
+.align 32
+
+.global bn_div_words
+/*
+ * BN_ULONG bn_div_words(h,l,d)
+ * BN_ULONG h,l,d;
+ */
+bn_div_words:
+ wr %o0,%y
+ udiv %o1,%o2,%o0
+ retl
+ nop
+
+.type bn_div_words,#function
+.size bn_div_words,(.-bn_div_words)
+
+.align 32
+
+.global bn_add_words
+/*
+ * BN_ULONG bn_add_words(rp,ap,bp,n)
+ * BN_ULONG *rp,*ap,*bp;
+ * int n;
+ */
+bn_add_words:
+ cmp %o3,0
+ bg,a .L_bn_add_words_proceed
+ ld [%o1],%o4
+ retl
+ clr %o0
+
+.L_bn_add_words_proceed:
+ andcc %o3,-4,%g0
+ bz .L_bn_add_words_tail
+ clr %g1
+ ba .L_bn_add_words_warn_loop
+ addcc %g0,0,%g0 ! clear carry flag
+
+.L_bn_add_words_loop:
+ ld [%o1],%o4
+.L_bn_add_words_warn_loop:
+ ld [%o2],%o5
+ ld [%o1+4],%g3
+ ld [%o2+4],%g4
+ dec 4,%o3
+ addxcc %o5,%o4,%o5
+ st %o5,[%o0]
+
+ ld [%o1+8],%o4
+ ld [%o2+8],%o5
+ inc 16,%o1
+ addxcc %g3,%g4,%g3
+ st %g3,[%o0+4]
+
+ ld [%o1-4],%g3
+ ld [%o2+12],%g4
+ inc 16,%o2
+ addxcc %o5,%o4,%o5
+ st %o5,[%o0+8]
+
+ inc 16,%o0
+ addxcc %g3,%g4,%g3
+ st %g3,[%o0-4]
+ addx %g0,0,%g1
+ andcc %o3,-4,%g0
+ bnz,a .L_bn_add_words_loop
+ addcc %g1,-1,%g0
+
+ tst %o3
+ bnz,a .L_bn_add_words_tail
+ ld [%o1],%o4
+.L_bn_add_words_return:
+ retl
+ mov %g1,%o0
+
+.L_bn_add_words_tail:
+ addcc %g1,-1,%g0
+ ld [%o2],%o5
+ addxcc %o5,%o4,%o5
+ addx %g0,0,%g1
+ deccc %o3
+ bz .L_bn_add_words_return
+ st %o5,[%o0]
+
+ ld [%o1+4],%o4
+ addcc %g1,-1,%g0
+ ld [%o2+4],%o5
+ addxcc %o5,%o4,%o5
+ addx %g0,0,%g1
+ deccc %o3
+ bz .L_bn_add_words_return
+ st %o5,[%o0+4]
+
+ ld [%o1+8],%o4
+ addcc %g1,-1,%g0
+ ld [%o2+8],%o5
+ addxcc %o5,%o4,%o5
+ st %o5,[%o0+8]
+ retl
+ addx %g0,0,%o0
+
+.type bn_add_words,#function
+.size bn_add_words,(.-bn_add_words)
+
+.align 32
+
+.global bn_sub_words
+/*
+ * BN_ULONG bn_sub_words(rp,ap,bp,n)
+ * BN_ULONG *rp,*ap,*bp;
+ * int n;
+ */
+bn_sub_words:
+ cmp %o3,0
+ bg,a .L_bn_sub_words_proceed
+ ld [%o1],%o4
+ retl
+ clr %o0
+
+.L_bn_sub_words_proceed:
+ andcc %o3,-4,%g0
+ bz .L_bn_sub_words_tail
+ clr %g1
+ ba .L_bn_sub_words_warm_loop
+ addcc %g0,0,%g0 ! clear carry flag
+
+.L_bn_sub_words_loop:
+ ld [%o1],%o4
+.L_bn_sub_words_warm_loop:
+ ld [%o2],%o5
+ ld [%o1+4],%g3
+ ld [%o2+4],%g4
+ dec 4,%o3
+ subxcc %o4,%o5,%o5
+ st %o5,[%o0]
+
+ ld [%o1+8],%o4
+ ld [%o2+8],%o5
+ inc 16,%o1
+ subxcc %g3,%g4,%g4
+ st %g4,[%o0+4]
+
+ ld [%o1-4],%g3
+ ld [%o2+12],%g4
+ inc 16,%o2
+ subxcc %o4,%o5,%o5
+ st %o5,[%o0+8]
+
+ inc 16,%o0
+ subxcc %g3,%g4,%g4
+ st %g4,[%o0-4]
+ addx %g0,0,%g1
+ andcc %o3,-4,%g0
+ bnz,a .L_bn_sub_words_loop
+ addcc %g1,-1,%g0
+
+ tst %o3
+ nop
+ bnz,a .L_bn_sub_words_tail
+ ld [%o1],%o4
+.L_bn_sub_words_return:
+ retl
+ mov %g1,%o0
+
+.L_bn_sub_words_tail:
+ addcc %g1,-1,%g0
+ ld [%o2],%o5
+ subxcc %o4,%o5,%o5
+ addx %g0,0,%g1
+ deccc %o3
+ bz .L_bn_sub_words_return
+ st %o5,[%o0]
+ nop
+
+ ld [%o1+4],%o4
+ addcc %g1,-1,%g0
+ ld [%o2+4],%o5
+ subxcc %o4,%o5,%o5
+ addx %g0,0,%g1
+ deccc %o3
+ bz .L_bn_sub_words_return
+ st %o5,[%o0+4]
+
+ ld [%o1+8],%o4
+ addcc %g1,-1,%g0
+ ld [%o2+8],%o5
+ subxcc %o4,%o5,%o5
+ st %o5,[%o0+8]
+ retl
+ addx %g0,0,%o0
+
+.type bn_sub_words,#function
+.size bn_sub_words,(.-bn_sub_words)
+
+#define FRAME_SIZE -96
+
+/*
+ * Here is register usage map for *all* routines below.
+ */
+#define t_1 %o0
+#define t_2 %o1
+#define c_1 %o2
+#define c_2 %o3
+#define c_3 %o4
+
+#define ap(I) [%i1+4*I]
+#define bp(I) [%i2+4*I]
+#define rp(I) [%i0+4*I]
+
+#define a_0 %l0
+#define a_1 %l1
+#define a_2 %l2
+#define a_3 %l3
+#define a_4 %l4
+#define a_5 %l5
+#define a_6 %l6
+#define a_7 %l7
+
+#define b_0 %i3
+#define b_1 %i4
+#define b_2 %i5
+#define b_3 %o5
+#define b_4 %g1
+#define b_5 %g2
+#define b_6 %g3
+#define b_7 %g4
+
+.align 32
+.global bn_mul_comba8
+/*
+ * void bn_mul_comba8(r,a,b)
+ * BN_ULONG *r,*a,*b;
+ */
+bn_mul_comba8:
+ save %sp,FRAME_SIZE,%sp
+ ld ap(0),a_0
+ ld bp(0),b_0
+ umul a_0,b_0,c_1 !=!mul_add_c(a[0],b[0],c1,c2,c3);
+ ld bp(1),b_1
+ rd %y,c_2
+ st c_1,rp(0) !r[0]=c1;
+
+ umul a_0,b_1,t_1 !=!mul_add_c(a[0],b[1],c2,c3,c1);
+ ld ap(1),a_1
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc %g0,t_2,c_3 !=
+ addx %g0,%g0,c_1
+ ld ap(2),a_2
+ umul a_1,b_0,t_1 !mul_add_c(a[1],b[0],c2,c3,c1);
+ addcc c_2,t_1,c_2 !=
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ st c_2,rp(1) !r[1]=c2;
+ addx c_1,%g0,c_1 !=
+
+ umul a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx %g0,%g0,c_2
+ ld bp(2),b_2
+ umul a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ ld bp(3),b_3
+ addx c_2,%g0,c_2 !=
+ umul a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx c_2,%g0,c_2
+ st c_3,rp(2) !r[2]=c3;
+
+ umul a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx %g0,%g0,c_3
+ umul a_1,b_2,t_1 !=!mul_add_c(a[1],b[2],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ ld ap(3),a_3
+ umul a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2 !=
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ ld ap(4),a_4
+ umul a_3,b_0,t_1 !mul_add_c(a[3],b[0],c1,c2,c3);!=
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ st c_1,rp(3) !r[3]=c1;
+
+ umul a_4,b_0,t_1 !mul_add_c(a[4],b[0],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx %g0,%g0,c_1
+ umul a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1);
+ addcc c_2,t_1,c_2 !=
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ umul a_2,b_2,t_1 !=!mul_add_c(a[2],b[2],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1 !=
+ ld bp(4),b_4
+ umul a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ ld bp(5),b_5
+ umul a_0,b_4,t_1 !=!mul_add_c(a[0],b[4],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1 !=
+ st c_2,rp(4) !r[4]=c2;
+
+ umul a_0,b_5,t_1 !mul_add_c(a[0],b[5],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2
+ umul a_1,b_4,t_1 !mul_add_c(a[1],b[4],c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ umul a_2,b_3,t_1 !=!mul_add_c(a[2],b[3],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2 !=
+ umul a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx c_2,%g0,c_2
+ ld ap(5),a_5
+ umul a_4,b_1,t_1 !mul_add_c(a[4],b[1],c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ ld ap(6),a_6
+ addx c_2,%g0,c_2 !=
+ umul a_5,b_0,t_1 !mul_add_c(a[5],b[0],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx c_2,%g0,c_2
+ st c_3,rp(5) !r[5]=c3;
+
+ umul a_6,b_0,t_1 !mul_add_c(a[6],b[0],c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx %g0,%g0,c_3
+ umul a_5,b_1,t_1 !=!mul_add_c(a[5],b[1],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ umul a_4,b_2,t_1 !mul_add_c(a[4],b[2],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ umul a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2 !=
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ umul a_2,b_4,t_1 !mul_add_c(a[2],b[4],c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ ld bp(6),b_6
+ addx c_3,%g0,c_3 !=
+ umul a_1,b_5,t_1 !mul_add_c(a[1],b[5],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ ld bp(7),b_7
+ umul a_0,b_6,t_1 !mul_add_c(a[0],b[6],c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ st c_1,rp(6) !r[6]=c1;
+ addx c_3,%g0,c_3 !=
+
+ umul a_0,b_7,t_1 !mul_add_c(a[0],b[7],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3 !=
+ addx %g0,%g0,c_1
+ umul a_1,b_6,t_1 !mul_add_c(a[1],b[6],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ umul a_2,b_5,t_1 !mul_add_c(a[2],b[5],c2,c3,c1);
+ addcc c_2,t_1,c_2 !=
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ umul a_3,b_4,t_1 !=!mul_add_c(a[3],b[4],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1 !=
+ umul a_4,b_3,t_1 !mul_add_c(a[4],b[3],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_5,b_2,t_1 !mul_add_c(a[5],b[2],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ ld ap(7),a_7
+ umul a_6,b_1,t_1 !=!mul_add_c(a[6],b[1],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1 !=
+ umul a_7,b_0,t_1 !mul_add_c(a[7],b[0],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ st c_2,rp(7) !r[7]=c2;
+
+ umul a_7,b_1,t_1 !mul_add_c(a[7],b[1],c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2
+ umul a_6,b_2,t_1 !=!mul_add_c(a[6],b[2],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2 !=
+ umul a_5,b_3,t_1 !mul_add_c(a[5],b[3],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx c_2,%g0,c_2
+ umul a_4,b_4,t_1 !mul_add_c(a[4],b[4],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ umul a_3,b_5,t_1 !mul_add_c(a[3],b[5],c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ umul a_2,b_6,t_1 !=!mul_add_c(a[2],b[6],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2 !=
+ umul a_1,b_7,t_1 !mul_add_c(a[1],b[7],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !
+ addx c_2,%g0,c_2
+ st c_3,rp(8) !r[8]=c3;
+
+ umul a_2,b_7,t_1 !mul_add_c(a[2],b[7],c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx %g0,%g0,c_3
+ umul a_3,b_6,t_1 !=!mul_add_c(a[3],b[6],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ umul a_4,b_5,t_1 !mul_add_c(a[4],b[5],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ umul a_5,b_4,t_1 !mul_add_c(a[5],b[4],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2 !=
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ umul a_6,b_3,t_1 !mul_add_c(a[6],b[3],c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ umul a_7,b_2,t_1 !=!mul_add_c(a[7],b[2],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ st c_1,rp(9) !r[9]=c1;
+
+ umul a_7,b_3,t_1 !mul_add_c(a[7],b[3],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx %g0,%g0,c_1
+ umul a_6,b_4,t_1 !mul_add_c(a[6],b[4],c2,c3,c1);
+ addcc c_2,t_1,c_2 !=
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ umul a_5,b_5,t_1 !=!mul_add_c(a[5],b[5],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1 !=
+ umul a_4,b_6,t_1 !mul_add_c(a[4],b[6],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_3,b_7,t_1 !mul_add_c(a[3],b[7],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ st c_2,rp(10) !r[10]=c2;
+
+ umul a_4,b_7,t_1 !=!mul_add_c(a[4],b[7],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2 !=
+ umul a_5,b_6,t_1 !mul_add_c(a[5],b[6],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx c_2,%g0,c_2
+ umul a_6,b_5,t_1 !mul_add_c(a[6],b[5],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ umul a_7,b_4,t_1 !mul_add_c(a[7],b[4],c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ st c_3,rp(11) !r[11]=c3;
+ addx c_2,%g0,c_2 !=
+
+ umul a_7,b_5,t_1 !mul_add_c(a[7],b[5],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx %g0,%g0,c_3
+ umul a_6,b_6,t_1 !mul_add_c(a[6],b[6],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2 !=
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ umul a_5,b_7,t_1 !mul_add_c(a[5],b[7],c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ st c_1,rp(12) !r[12]=c1;
+ addx c_3,%g0,c_3 !=
+
+ umul a_6,b_7,t_1 !mul_add_c(a[6],b[7],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3 !=
+ addx %g0,%g0,c_1
+ umul a_7,b_6,t_1 !mul_add_c(a[7],b[6],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ st c_2,rp(13) !r[13]=c2;
+
+ umul a_7,b_7,t_1 !=!mul_add_c(a[7],b[7],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ nop !=
+ st c_3,rp(14) !r[14]=c3;
+ st c_1,rp(15) !r[15]=c1;
+
+ ret
+ restore %g0,%g0,%o0
+
+.type bn_mul_comba8,#function
+.size bn_mul_comba8,(.-bn_mul_comba8)
+
+.align 32
+
+.global bn_mul_comba4
+/*
+ * void bn_mul_comba4(r,a,b)
+ * BN_ULONG *r,*a,*b;
+ */
+bn_mul_comba4:
+ save %sp,FRAME_SIZE,%sp
+ ld ap(0),a_0
+ ld bp(0),b_0
+ umul a_0,b_0,c_1 !=!mul_add_c(a[0],b[0],c1,c2,c3);
+ ld bp(1),b_1
+ rd %y,c_2
+ st c_1,rp(0) !r[0]=c1;
+
+ umul a_0,b_1,t_1 !=!mul_add_c(a[0],b[1],c2,c3,c1);
+ ld ap(1),a_1
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc %g0,t_2,c_3
+ addx %g0,%g0,c_1
+ ld ap(2),a_2
+ umul a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1 !=
+ st c_2,rp(1) !r[1]=c2;
+
+ umul a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2
+ ld bp(2),b_2
+ umul a_1,b_1,t_1 !=!mul_add_c(a[1],b[1],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2 !=
+ ld bp(3),b_3
+ umul a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ st c_3,rp(2) !r[2]=c3;
+
+ umul a_0,b_3,t_1 !=!mul_add_c(a[0],b[3],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx %g0,%g0,c_3 !=
+ umul a_1,b_2,t_1 !mul_add_c(a[1],b[2],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ ld ap(3),a_3
+ umul a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ umul a_3,b_0,t_1 !=!mul_add_c(a[3],b[0],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ st c_1,rp(3) !r[3]=c1;
+
+ umul a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx %g0,%g0,c_1
+ umul a_2,b_2,t_1 !mul_add_c(a[2],b[2],c2,c3,c1);
+ addcc c_2,t_1,c_2 !=
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ umul a_1,b_3,t_1 !=!mul_add_c(a[1],b[3],c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1 !=
+ st c_2,rp(4) !r[4]=c2;
+
+ umul a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2
+ umul a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ st c_3,rp(5) !r[5]=c3;
+ addx c_2,%g0,c_2 !=
+
+ umul a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ st c_1,rp(6) !r[6]=c1;
+ st c_2,rp(7) !r[7]=c2;
+
+ ret
+ restore %g0,%g0,%o0
+
+.type bn_mul_comba4,#function
+.size bn_mul_comba4,(.-bn_mul_comba4)
+
+.align 32
+
+.global bn_sqr_comba8
+bn_sqr_comba8:
+ save %sp,FRAME_SIZE,%sp
+ ld ap(0),a_0
+ ld ap(1),a_1
+ umul a_0,a_0,c_1 !=!sqr_add_c(a,0,c1,c2,c3);
+ rd %y,c_2
+ st c_1,rp(0) !r[0]=c1;
+
+ ld ap(2),a_2
+ umul a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc %g0,t_2,c_3
+ addx %g0,%g0,c_1 !=
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3
+ st c_2,rp(1) !r[1]=c2;
+ addx c_1,%g0,c_1 !=
+
+ umul a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx %g0,%g0,c_2
+ addcc c_3,t_1,c_3
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2 !=
+ ld ap(3),a_3
+ umul a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ st c_3,rp(2) !r[2]=c3;
+
+ umul a_0,a_3,t_1 !=!sqr_add_c2(a,3,0,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx %g0,%g0,c_3 !=
+ addcc c_1,t_1,c_1
+ addxcc c_2,t_2,c_2
+ ld ap(4),a_4
+ addx c_3,%g0,c_3 !=
+ umul a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ addcc c_1,t_1,c_1
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ st c_1,rp(3) !r[3]=c1;
+
+ umul a_4,a_0,t_1 !sqr_add_c2(a,4,0,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx %g0,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ ld ap(5),a_5
+ umul a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1);
+ addcc c_2,t_1,c_2 !=
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ st c_2,rp(4) !r[4]=c2;
+ addx c_1,%g0,c_1 !=
+
+ umul a_0,a_5,t_1 !sqr_add_c2(a,5,0,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx %g0,%g0,c_2
+ addcc c_3,t_1,c_3
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2 !=
+ umul a_1,a_4,t_1 !sqr_add_c2(a,4,1,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ addx c_2,%g0,c_2
+ addcc c_3,t_1,c_3
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2 !=
+ ld ap(6),a_6
+ umul a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ addcc c_3,t_1,c_3
+ addxcc c_1,t_2,c_1 !=
+ addx c_2,%g0,c_2
+ st c_3,rp(5) !r[5]=c3;
+
+ umul a_6,a_0,t_1 !sqr_add_c2(a,6,0,c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx %g0,%g0,c_3
+ addcc c_1,t_1,c_1 !=
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ umul a_5,a_1,t_1 !sqr_add_c2(a,5,1,c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ addcc c_1,t_1,c_1 !=
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ umul a_4,a_2,t_1 !sqr_add_c2(a,4,2,c1,c2,c3);
+ addcc c_1,t_1,c_1 !=
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ addcc c_1,t_1,c_1 !=
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3
+ ld ap(7),a_7
+ umul a_3,a_3,t_1 !=!sqr_add_c(a,3,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ st c_1,rp(6) !r[6]=c1;
+
+ umul a_0,a_7,t_1 !sqr_add_c2(a,7,0,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx %g0,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_1,a_6,t_1 !sqr_add_c2(a,6,1,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_2,a_5,t_1 !sqr_add_c2(a,5,2,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_3,a_4,t_1 !sqr_add_c2(a,4,3,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ st c_2,rp(7) !r[7]=c2;
+
+ umul a_7,a_1,t_1 !sqr_add_c2(a,7,1,c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2
+ addcc c_3,t_1,c_3 !=
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ umul a_6,a_2,t_1 !sqr_add_c2(a,6,2,c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ addcc c_3,t_1,c_3 !=
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ umul a_5,a_3,t_1 !sqr_add_c2(a,5,3,c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ addcc c_3,t_1,c_3 !=
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ umul a_4,a_4,t_1 !sqr_add_c(a,4,c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ st c_3,rp(8) !r[8]=c3;
+ addx c_2,%g0,c_2 !=
+
+ umul a_2,a_7,t_1 !sqr_add_c2(a,7,2,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx %g0,%g0,c_3
+ addcc c_1,t_1,c_1
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ umul a_3,a_6,t_1 !sqr_add_c2(a,6,3,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ addcc c_1,t_1,c_1
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ umul a_4,a_5,t_1 !sqr_add_c2(a,5,4,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ addcc c_1,t_1,c_1
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ st c_1,rp(9) !r[9]=c1;
+
+ umul a_7,a_3,t_1 !sqr_add_c2(a,7,3,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx %g0,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_6,a_4,t_1 !sqr_add_c2(a,6,4,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_5,a_5,t_1 !sqr_add_c(a,5,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ st c_2,rp(10) !r[10]=c2;
+
+ umul a_4,a_7,t_1 !=!sqr_add_c2(a,7,4,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2 !=
+ addcc c_3,t_1,c_3
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2
+ umul a_5,a_6,t_1 !=!sqr_add_c2(a,6,5,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx c_2,%g0,c_2 !=
+ addcc c_3,t_1,c_3
+ addxcc c_1,t_2,c_1
+ st c_3,rp(11) !r[11]=c3;
+ addx c_2,%g0,c_2 !=
+
+ umul a_7,a_5,t_1 !sqr_add_c2(a,7,5,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx %g0,%g0,c_3
+ addcc c_1,t_1,c_1
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ umul a_6,a_6,t_1 !sqr_add_c(a,6,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ st c_1,rp(12) !r[12]=c1;
+
+ umul a_6,a_7,t_1 !sqr_add_c2(a,7,6,c2,c3,c1);
+ addcc c_2,t_1,c_2 !=
+ rd %y,t_2
+ addxcc c_3,t_2,c_3
+ addx %g0,%g0,c_1
+ addcc c_2,t_1,c_2 !=
+ addxcc c_3,t_2,c_3
+ st c_2,rp(13) !r[13]=c2;
+ addx c_1,%g0,c_1 !=
+
+ umul a_7,a_7,t_1 !sqr_add_c(a,7,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1 !=
+ st c_3,rp(14) !r[14]=c3;
+ st c_1,rp(15) !r[15]=c1;
+
+ ret
+ restore %g0,%g0,%o0
+
+.type bn_sqr_comba8,#function
+.size bn_sqr_comba8,(.-bn_sqr_comba8)
+
+.align 32
+
+.global bn_sqr_comba4
+/*
+ * void bn_sqr_comba4(r,a)
+ * BN_ULONG *r,*a;
+ */
+bn_sqr_comba4:
+ save %sp,FRAME_SIZE,%sp
+ ld ap(0),a_0
+ umul a_0,a_0,c_1 !sqr_add_c(a,0,c1,c2,c3);
+ ld ap(1),a_1 !=
+ rd %y,c_2
+ st c_1,rp(0) !r[0]=c1;
+
+ ld ap(2),a_2
+ umul a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2
+ addxcc %g0,t_2,c_3
+ addx %g0,%g0,c_1 !=
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1 !=
+ st c_2,rp(1) !r[1]=c2;
+
+ umul a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2 !=
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2
+ addcc c_3,t_1,c_3
+ addxcc c_1,t_2,c_1 !=
+ addx c_2,%g0,c_2
+ ld ap(3),a_3
+ umul a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2);
+ addcc c_3,t_1,c_3 !=
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ st c_3,rp(2) !r[2]=c3;
+ addx c_2,%g0,c_2 !=
+
+ umul a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx %g0,%g0,c_3
+ addcc c_1,t_1,c_1
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ umul a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ addx c_3,%g0,c_3
+ addcc c_1,t_1,c_1
+ addxcc c_2,t_2,c_2
+ addx c_3,%g0,c_3 !=
+ st c_1,rp(3) !r[3]=c1;
+
+ umul a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx %g0,%g0,c_1
+ addcc c_2,t_1,c_2
+ addxcc c_3,t_2,c_3 !=
+ addx c_1,%g0,c_1
+ umul a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1);
+ addcc c_2,t_1,c_2
+ rd %y,t_2 !=
+ addxcc c_3,t_2,c_3
+ addx c_1,%g0,c_1
+ st c_2,rp(4) !r[4]=c2;
+
+ umul a_2,a_3,t_1 !=!sqr_add_c2(a,3,2,c3,c1,c2);
+ addcc c_3,t_1,c_3
+ rd %y,t_2
+ addxcc c_1,t_2,c_1
+ addx %g0,%g0,c_2 !=
+ addcc c_3,t_1,c_3
+ addxcc c_1,t_2,c_1
+ st c_3,rp(5) !r[5]=c3;
+ addx c_2,%g0,c_2 !=
+
+ umul a_3,a_3,t_1 !sqr_add_c(a,3,c1,c2,c3);
+ addcc c_1,t_1,c_1
+ rd %y,t_2
+ addxcc c_2,t_2,c_2 !=
+ st c_1,rp(6) !r[6]=c1;
+ st c_2,rp(7) !r[7]=c2;
+
+ ret
+ restore %g0,%g0,%o0
+
+.type bn_sqr_comba4,#function
+.size bn_sqr_comba4,(.-bn_sqr_comba4)
+
+.align 32
diff --git a/openssl/trunk/crypto/bn/asm/sparcv8plus.S b/openssl/trunk/crypto/bn/asm/sparcv8plus.S
new file mode 100644
index 00000000..8c56e2e7
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/sparcv8plus.S
@@ -0,0 +1,1547 @@
+.ident "sparcv8plus.s, Version 1.4"
+.ident "SPARC v9 ISA artwork by Andy Polyakov <appro@fy.chalmers.se>"
+
+/*
+ * ====================================================================
+ * Written by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+ * project.
+ *
+ * Rights for redistribution and usage in source and binary forms are
+ * granted according to the OpenSSL license. Warranty of any kind is
+ * disclaimed.
+ * ====================================================================
+ */
+
+/*
+ * This is my modest contributon to OpenSSL project (see
+ * http://www.openssl.org/ for more information about it) and is
+ * a drop-in UltraSPARC ISA replacement for crypto/bn/bn_asm.c
+ * module. For updates see http://fy.chalmers.se/~appro/hpe/.
+ *
+ * Questions-n-answers.
+ *
+ * Q. How to compile?
+ * A. With SC4.x/SC5.x:
+ *
+ * cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
+ *
+ * and with gcc:
+ *
+ * gcc -mcpu=ultrasparc -c bn_asm.sparc.v8plus.S -o bn_asm.o
+ *
+ * or if above fails (it does if you have gas installed):
+ *
+ * gcc -E bn_asm.sparc.v8plus.S | as -xarch=v8plus /dev/fd/0 -o bn_asm.o
+ *
+ * Quick-n-dirty way to fuse the module into the library.
+ * Provided that the library is already configured and built
+ * (in 0.9.2 case with no-asm option):
+ *
+ * # cd crypto/bn
+ * # cp /some/place/bn_asm.sparc.v8plus.S .
+ * # cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o
+ * # make
+ * # cd ../..
+ * # make; make test
+ *
+ * Quick-n-dirty way to get rid of it:
+ *
+ * # cd crypto/bn
+ * # touch bn_asm.c
+ * # make
+ * # cd ../..
+ * # make; make test
+ *
+ * Q. V8plus achitecture? What kind of beast is that?
+ * A. Well, it's rather a programming model than an architecture...
+ * It's actually v9-compliant, i.e. *any* UltraSPARC, CPU under
+ * special conditions, namely when kernel doesn't preserve upper
+ * 32 bits of otherwise 64-bit registers during a context switch.
+ *
+ * Q. Why just UltraSPARC? What about SuperSPARC?
+ * A. Original release did target UltraSPARC only. Now SuperSPARC
+ * version is provided along. Both version share bn_*comba[48]
+ * implementations (see comment later in code for explanation).
+ * But what's so special about this UltraSPARC implementation?
+ * Why didn't I let compiler do the job? Trouble is that most of
+ * available compilers (well, SC5.0 is the only exception) don't
+ * attempt to take advantage of UltraSPARC's 64-bitness under
+ * 32-bit kernels even though it's perfectly possible (see next
+ * question).
+ *
+ * Q. 64-bit registers under 32-bit kernels? Didn't you just say it
+ * doesn't work?
+ * A. You can't adress *all* registers as 64-bit wide:-( The catch is
+ * that you actually may rely upon %o0-%o5 and %g1-%g4 being fully
+ * preserved if you're in a leaf function, i.e. such never calling
+ * any other functions. All functions in this module are leaf and
+ * 10 registers is a handful. And as a matter of fact none-"comba"
+ * routines don't require even that much and I could even afford to
+ * not allocate own stack frame for 'em:-)
+ *
+ * Q. What about 64-bit kernels?
+ * A. What about 'em? Just kidding:-) Pure 64-bit version is currently
+ * under evaluation and development...
+ *
+ * Q. What about shared libraries?
+ * A. What about 'em? Kidding again:-) Code does *not* contain any
+ * code position dependencies and it's safe to include it into
+ * shared library as is.
+ *
+ * Q. How much faster does it go?
+ * A. Do you have a good benchmark? In either case below is what I
+ * experience with crypto/bn/expspeed.c test program:
+ *
+ * v8plus module on U10/300MHz against bn_asm.c compiled with:
+ *
+ * cc-5.0 -xarch=v8plus -xO5 -xdepend +7-12%
+ * cc-4.2 -xarch=v8plus -xO5 -xdepend +25-35%
+ * egcs-1.1.2 -mcpu=ultrasparc -O3 +35-45%
+ *
+ * v8 module on SS10/60MHz against bn_asm.c compiled with:
+ *
+ * cc-5.0 -xarch=v8 -xO5 -xdepend +7-10%
+ * cc-4.2 -xarch=v8 -xO5 -xdepend +10%
+ * egcs-1.1.2 -mv8 -O3 +35-45%
+ *
+ * As you can see it's damn hard to beat the new Sun C compiler
+ * and it's in first place GNU C users who will appreciate this
+ * assembler implementation:-)
+ */
+
+/*
+ * Revision history.
+ *
+ * 1.0 - initial release;
+ * 1.1 - new loop unrolling model(*);
+ * - some more fine tuning;
+ * 1.2 - made gas friendly;
+ * - updates to documentation concerning v9;
+ * - new performance comparison matrix;
+ * 1.3 - fixed problem with /usr/ccs/lib/cpp;
+ * 1.4 - native V9 bn_*_comba[48] implementation (15% more efficient)
+ * resulting in slight overall performance kick;
+ * - some retunes;
+ * - support for GNU as added;
+ *
+ * (*) Originally unrolled loop looked like this:
+ * for (;;) {
+ * op(p+0); if (--n==0) break;
+ * op(p+1); if (--n==0) break;
+ * op(p+2); if (--n==0) break;
+ * op(p+3); if (--n==0) break;
+ * p+=4;
+ * }
+ * I unroll according to following:
+ * while (n&~3) {
+ * op(p+0); op(p+1); op(p+2); op(p+3);
+ * p+=4; n=-4;
+ * }
+ * if (n) {
+ * op(p+0); if (--n==0) return;
+ * op(p+2); if (--n==0) return;
+ * op(p+3); return;
+ * }
+ */
+
+/*
+ * GNU assembler can't stand stuw:-(
+ */
+#define stuw st
+
+.section ".text",#alloc,#execinstr
+.file "bn_asm.sparc.v8plus.S"
+
+.align 32
+
+.global bn_mul_add_words
+/*
+ * BN_ULONG bn_mul_add_words(rp,ap,num,w)
+ * BN_ULONG *rp,*ap;
+ * int num;
+ * BN_ULONG w;
+ */
+bn_mul_add_words:
+ sra %o2,%g0,%o2 ! signx %o2
+ brgz,a %o2,.L_bn_mul_add_words_proceed
+ lduw [%o1],%g2
+ retl
+ clr %o0
+ nop
+ nop
+ nop
+
+.L_bn_mul_add_words_proceed:
+ srl %o3,%g0,%o3 ! clruw %o3
+ andcc %o2,-4,%g0
+ bz,pn %icc,.L_bn_mul_add_words_tail
+ clr %o5
+
+.L_bn_mul_add_words_loop: ! wow! 32 aligned!
+ lduw [%o0],%g1
+ lduw [%o1+4],%g3
+ mulx %o3,%g2,%g2
+ add %g1,%o5,%o4
+ nop
+ add %o4,%g2,%o4
+ stuw %o4,[%o0]
+ srlx %o4,32,%o5
+
+ lduw [%o0+4],%g1
+ lduw [%o1+8],%g2
+ mulx %o3,%g3,%g3
+ add %g1,%o5,%o4
+ dec 4,%o2
+ add %o4,%g3,%o4
+ stuw %o4,[%o0+4]
+ srlx %o4,32,%o5
+
+ lduw [%o0+8],%g1
+ lduw [%o1+12],%g3
+ mulx %o3,%g2,%g2
+ add %g1,%o5,%o4
+ inc 16,%o1
+ add %o4,%g2,%o4
+ stuw %o4,[%o0+8]
+ srlx %o4,32,%o5
+
+ lduw [%o0+12],%g1
+ mulx %o3,%g3,%g3
+ add %g1,%o5,%o4
+ inc 16,%o0
+ add %o4,%g3,%o4
+ andcc %o2,-4,%g0
+ stuw %o4,[%o0-4]
+ srlx %o4,32,%o5
+ bnz,a,pt %icc,.L_bn_mul_add_words_loop
+ lduw [%o1],%g2
+
+ brnz,a,pn %o2,.L_bn_mul_add_words_tail
+ lduw [%o1],%g2
+.L_bn_mul_add_words_return:
+ retl
+ mov %o5,%o0
+
+.L_bn_mul_add_words_tail:
+ lduw [%o0],%g1
+ mulx %o3,%g2,%g2
+ add %g1,%o5,%o4
+ dec %o2
+ add %o4,%g2,%o4
+ srlx %o4,32,%o5
+ brz,pt %o2,.L_bn_mul_add_words_return
+ stuw %o4,[%o0]
+
+ lduw [%o1+4],%g2
+ lduw [%o0+4],%g1
+ mulx %o3,%g2,%g2
+ add %g1,%o5,%o4
+ dec %o2
+ add %o4,%g2,%o4
+ srlx %o4,32,%o5
+ brz,pt %o2,.L_bn_mul_add_words_return
+ stuw %o4,[%o0+4]
+
+ lduw [%o1+8],%g2
+ lduw [%o0+8],%g1
+ mulx %o3,%g2,%g2
+ add %g1,%o5,%o4
+ add %o4,%g2,%o4
+ stuw %o4,[%o0+8]
+ retl
+ srlx %o4,32,%o0
+
+.type bn_mul_add_words,#function
+.size bn_mul_add_words,(.-bn_mul_add_words)
+
+.align 32
+
+.global bn_mul_words
+/*
+ * BN_ULONG bn_mul_words(rp,ap,num,w)
+ * BN_ULONG *rp,*ap;
+ * int num;
+ * BN_ULONG w;
+ */
+bn_mul_words:
+ sra %o2,%g0,%o2 ! signx %o2
+ brgz,a %o2,.L_bn_mul_words_proceeed
+ lduw [%o1],%g2
+ retl
+ clr %o0
+ nop
+ nop
+ nop
+
+.L_bn_mul_words_proceeed:
+ srl %o3,%g0,%o3 ! clruw %o3
+ andcc %o2,-4,%g0
+ bz,pn %icc,.L_bn_mul_words_tail
+ clr %o5
+
+.L_bn_mul_words_loop: ! wow! 32 aligned!
+ lduw [%o1+4],%g3
+ mulx %o3,%g2,%g2
+ add %g2,%o5,%o4
+ nop
+ stuw %o4,[%o0]
+ srlx %o4,32,%o5
+
+ lduw [%o1+8],%g2
+ mulx %o3,%g3,%g3
+ add %g3,%o5,%o4
+ dec 4,%o2
+ stuw %o4,[%o0+4]
+ srlx %o4,32,%o5
+
+ lduw [%o1+12],%g3
+ mulx %o3,%g2,%g2
+ add %g2,%o5,%o4
+ inc 16,%o1
+ stuw %o4,[%o0+8]
+ srlx %o4,32,%o5
+
+ mulx %o3,%g3,%g3
+ add %g3,%o5,%o4
+ inc 16,%o0
+ stuw %o4,[%o0-4]
+ srlx %o4,32,%o5
+ andcc %o2,-4,%g0
+ bnz,a,pt %icc,.L_bn_mul_words_loop
+ lduw [%o1],%g2
+ nop
+ nop
+
+ brnz,a,pn %o2,.L_bn_mul_words_tail
+ lduw [%o1],%g2
+.L_bn_mul_words_return:
+ retl
+ mov %o5,%o0
+
+.L_bn_mul_words_tail:
+ mulx %o3,%g2,%g2
+ add %g2,%o5,%o4
+ dec %o2
+ srlx %o4,32,%o5
+ brz,pt %o2,.L_bn_mul_words_return
+ stuw %o4,[%o0]
+
+ lduw [%o1+4],%g2
+ mulx %o3,%g2,%g2
+ add %g2,%o5,%o4
+ dec %o2
+ srlx %o4,32,%o5
+ brz,pt %o2,.L_bn_mul_words_return
+ stuw %o4,[%o0+4]
+
+ lduw [%o1+8],%g2
+ mulx %o3,%g2,%g2
+ add %g2,%o5,%o4
+ stuw %o4,[%o0+8]
+ retl
+ srlx %o4,32,%o0
+
+.type bn_mul_words,#function
+.size bn_mul_words,(.-bn_mul_words)
+
+.align 32
+.global bn_sqr_words
+/*
+ * void bn_sqr_words(r,a,n)
+ * BN_ULONG *r,*a;
+ * int n;
+ */
+bn_sqr_words:
+ sra %o2,%g0,%o2 ! signx %o2
+ brgz,a %o2,.L_bn_sqr_words_proceeed
+ lduw [%o1],%g2
+ retl
+ clr %o0
+ nop
+ nop
+ nop
+
+.L_bn_sqr_words_proceeed:
+ andcc %o2,-4,%g0
+ nop
+ bz,pn %icc,.L_bn_sqr_words_tail
+ nop
+
+.L_bn_sqr_words_loop: ! wow! 32 aligned!
+ lduw [%o1+4],%g3
+ mulx %g2,%g2,%o4
+ stuw %o4,[%o0]
+ srlx %o4,32,%o5
+ stuw %o5,[%o0+4]
+ nop
+
+ lduw [%o1+8],%g2
+ mulx %g3,%g3,%o4
+ dec 4,%o2
+ stuw %o4,[%o0+8]
+ srlx %o4,32,%o5
+ stuw %o5,[%o0+12]
+
+ lduw [%o1+12],%g3
+ mulx %g2,%g2,%o4
+ srlx %o4,32,%o5
+ stuw %o4,[%o0+16]
+ inc 16,%o1
+ stuw %o5,[%o0+20]
+
+ mulx %g3,%g3,%o4
+ inc 32,%o0
+ stuw %o4,[%o0-8]
+ srlx %o4,32,%o5
+ andcc %o2,-4,%g2
+ stuw %o5,[%o0-4]
+ bnz,a,pt %icc,.L_bn_sqr_words_loop
+ lduw [%o1],%g2
+ nop
+
+ brnz,a,pn %o2,.L_bn_sqr_words_tail
+ lduw [%o1],%g2
+.L_bn_sqr_words_return:
+ retl
+ clr %o0
+
+.L_bn_sqr_words_tail:
+ mulx %g2,%g2,%o4
+ dec %o2
+ stuw %o4,[%o0]
+ srlx %o4,32,%o5
+ brz,pt %o2,.L_bn_sqr_words_return
+ stuw %o5,[%o0+4]
+
+ lduw [%o1+4],%g2
+ mulx %g2,%g2,%o4
+ dec %o2
+ stuw %o4,[%o0+8]
+ srlx %o4,32,%o5
+ brz,pt %o2,.L_bn_sqr_words_return
+ stuw %o5,[%o0+12]
+
+ lduw [%o1+8],%g2
+ mulx %g2,%g2,%o4
+ srlx %o4,32,%o5
+ stuw %o4,[%o0+16]
+ stuw %o5,[%o0+20]
+ retl
+ clr %o0
+
+.type bn_sqr_words,#function
+.size bn_sqr_words,(.-bn_sqr_words)
+
+.align 32
+.global bn_div_words
+/*
+ * BN_ULONG bn_div_words(h,l,d)
+ * BN_ULONG h,l,d;
+ */
+bn_div_words:
+ sllx %o0,32,%o0
+ or %o0,%o1,%o0
+ udivx %o0,%o2,%o0
+ retl
+ srl %o0,%g0,%o0 ! clruw %o0
+
+.type bn_div_words,#function
+.size bn_div_words,(.-bn_div_words)
+
+.align 32
+
+.global bn_add_words
+/*
+ * BN_ULONG bn_add_words(rp,ap,bp,n)
+ * BN_ULONG *rp,*ap,*bp;
+ * int n;
+ */
+bn_add_words:
+ sra %o3,%g0,%o3 ! signx %o3
+ brgz,a %o3,.L_bn_add_words_proceed
+ lduw [%o1],%o4
+ retl
+ clr %o0
+
+.L_bn_add_words_proceed:
+ andcc %o3,-4,%g0
+ bz,pn %icc,.L_bn_add_words_tail
+ addcc %g0,0,%g0 ! clear carry flag
+
+.L_bn_add_words_loop: ! wow! 32 aligned!
+ dec 4,%o3
+ lduw [%o2],%o5
+ lduw [%o1+4],%g1
+ lduw [%o2+4],%g2
+ lduw [%o1+8],%g3
+ lduw [%o2+8],%g4
+ addccc %o5,%o4,%o5
+ stuw %o5,[%o0]
+
+ lduw [%o1+12],%o4
+ lduw [%o2+12],%o5
+ inc 16,%o1
+ addccc %g1,%g2,%g1
+ stuw %g1,[%o0+4]
+
+ inc 16,%o2
+ addccc %g3,%g4,%g3
+ stuw %g3,[%o0+8]
+
+ inc 16,%o0
+ addccc %o5,%o4,%o5
+ stuw %o5,[%o0-4]
+ and %o3,-4,%g1
+ brnz,a,pt %g1,.L_bn_add_words_loop
+ lduw [%o1],%o4
+
+ brnz,a,pn %o3,.L_bn_add_words_tail
+ lduw [%o1],%o4
+.L_bn_add_words_return:
+ clr %o0
+ retl
+ movcs %icc,1,%o0
+ nop
+
+.L_bn_add_words_tail:
+ lduw [%o2],%o5
+ dec %o3
+ addccc %o5,%o4,%o5
+ brz,pt %o3,.L_bn_add_words_return
+ stuw %o5,[%o0]
+
+ lduw [%o1+4],%o4
+ lduw [%o2+4],%o5
+ dec %o3
+ addccc %o5,%o4,%o5
+ brz,pt %o3,.L_bn_add_words_return
+ stuw %o5,[%o0+4]
+
+ lduw [%o1+8],%o4
+ lduw [%o2+8],%o5
+ addccc %o5,%o4,%o5
+ stuw %o5,[%o0+8]
+ clr %o0
+ retl
+ movcs %icc,1,%o0
+
+.type bn_add_words,#function
+.size bn_add_words,(.-bn_add_words)
+
+.global bn_sub_words
+/*
+ * BN_ULONG bn_sub_words(rp,ap,bp,n)
+ * BN_ULONG *rp,*ap,*bp;
+ * int n;
+ */
+bn_sub_words:
+ sra %o3,%g0,%o3 ! signx %o3
+ brgz,a %o3,.L_bn_sub_words_proceed
+ lduw [%o1],%o4
+ retl
+ clr %o0
+
+.L_bn_sub_words_proceed:
+ andcc %o3,-4,%g0
+ bz,pn %icc,.L_bn_sub_words_tail
+ addcc %g0,0,%g0 ! clear carry flag
+
+.L_bn_sub_words_loop: ! wow! 32 aligned!
+ dec 4,%o3
+ lduw [%o2],%o5
+ lduw [%o1+4],%g1
+ lduw [%o2+4],%g2
+ lduw [%o1+8],%g3
+ lduw [%o2+8],%g4
+ subccc %o4,%o5,%o5
+ stuw %o5,[%o0]
+
+ lduw [%o1+12],%o4
+ lduw [%o2+12],%o5
+ inc 16,%o1
+ subccc %g1,%g2,%g2
+ stuw %g2,[%o0+4]
+
+ inc 16,%o2
+ subccc %g3,%g4,%g4
+ stuw %g4,[%o0+8]
+
+ inc 16,%o0
+ subccc %o4,%o5,%o5
+ stuw %o5,[%o0-4]
+ and %o3,-4,%g1
+ brnz,a,pt %g1,.L_bn_sub_words_loop
+ lduw [%o1],%o4
+
+ brnz,a,pn %o3,.L_bn_sub_words_tail
+ lduw [%o1],%o4
+.L_bn_sub_words_return:
+ clr %o0
+ retl
+ movcs %icc,1,%o0
+ nop
+
+.L_bn_sub_words_tail: ! wow! 32 aligned!
+ lduw [%o2],%o5
+ dec %o3
+ subccc %o4,%o5,%o5
+ brz,pt %o3,.L_bn_sub_words_return
+ stuw %o5,[%o0]
+
+ lduw [%o1+4],%o4
+ lduw [%o2+4],%o5
+ dec %o3
+ subccc %o4,%o5,%o5
+ brz,pt %o3,.L_bn_sub_words_return
+ stuw %o5,[%o0+4]
+
+ lduw [%o1+8],%o4
+ lduw [%o2+8],%o5
+ subccc %o4,%o5,%o5
+ stuw %o5,[%o0+8]
+ clr %o0
+ retl
+ movcs %icc,1,%o0
+
+.type bn_sub_words,#function
+.size bn_sub_words,(.-bn_sub_words)
+
+/*
+ * Code below depends on the fact that upper parts of the %l0-%l7
+ * and %i0-%i7 are zeroed by kernel after context switch. In
+ * previous versions this comment stated that "the trouble is that
+ * it's not feasible to implement the mumbo-jumbo in less V9
+ * instructions:-(" which apparently isn't true thanks to
+ * 'bcs,a %xcc,.+8; inc %rd' pair. But the performance improvement
+ * results not from the shorter code, but from elimination of
+ * multicycle none-pairable 'rd %y,%rd' instructions.
+ *
+ * Andy.
+ */
+
+#define FRAME_SIZE -96
+
+/*
+ * Here is register usage map for *all* routines below.
+ */
+#define t_1 %o0
+#define t_2 %o1
+#define c_12 %o2
+#define c_3 %o3
+
+#define ap(I) [%i1+4*I]
+#define bp(I) [%i2+4*I]
+#define rp(I) [%i0+4*I]
+
+#define a_0 %l0
+#define a_1 %l1
+#define a_2 %l2
+#define a_3 %l3
+#define a_4 %l4
+#define a_5 %l5
+#define a_6 %l6
+#define a_7 %l7
+
+#define b_0 %i3
+#define b_1 %i4
+#define b_2 %i5
+#define b_3 %o4
+#define b_4 %o5
+#define b_5 %o7
+#define b_6 %g1
+#define b_7 %g4
+
+.align 32
+.global bn_mul_comba8
+/*
+ * void bn_mul_comba8(r,a,b)
+ * BN_ULONG *r,*a,*b;
+ */
+bn_mul_comba8:
+ save %sp,FRAME_SIZE,%sp
+ mov 1,t_2
+ lduw ap(0),a_0
+ sllx t_2,32,t_2
+ lduw bp(0),b_0 !=
+ lduw bp(1),b_1
+ mulx a_0,b_0,t_1 !mul_add_c(a[0],b[0],c1,c2,c3);
+ srlx t_1,32,c_12
+ stuw t_1,rp(0) !=!r[0]=c1;
+
+ lduw ap(1),a_1
+ mulx a_0,b_1,t_1 !mul_add_c(a[0],b[1],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(2),a_2
+ mulx a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12 !=
+ stuw t_1,rp(1) !r[1]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2);
+ addcc c_12,t_1,c_12 !=
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw bp(2),b_2 !=
+ mulx a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ lduw bp(3),b_3
+ mulx a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(2) !r[2]=c3;
+ or c_12,c_3,c_12 !=
+
+ mulx a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_1,b_2,t_1 !=!mul_add_c(a[1],b[2],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ lduw ap(3),a_3
+ mulx a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3);
+ addcc c_12,t_1,c_12 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(4),a_4
+ mulx a_3,b_0,t_1 !=!mul_add_c(a[3],b[0],c1,c2,c3);!=
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12 !=
+ stuw t_1,rp(3) !r[3]=c1;
+ or c_12,c_3,c_12
+
+ mulx a_4,b_0,t_1 !mul_add_c(a[4],b[0],c2,c3,c1);
+ addcc c_12,t_1,c_12 !=
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_3,b_1,t_1 !=!mul_add_c(a[3],b[1],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_2,b_2,t_1 !=!mul_add_c(a[2],b[2],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw bp(4),b_4 !=
+ mulx a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ lduw bp(5),b_5
+ mulx a_0,b_4,t_1 !mul_add_c(a[0],b[4],c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(4) !r[4]=c2;
+ or c_12,c_3,c_12 !=
+
+ mulx a_0,b_5,t_1 !mul_add_c(a[0],b[5],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_1,b_4,t_1 !mul_add_c(a[1],b[4],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ lduw ap(5),a_5
+ mulx a_4,b_1,t_1 !mul_add_c(a[4],b[1],c3,c1,c2);
+ addcc c_12,t_1,c_12 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(6),a_6
+ mulx a_5,b_0,t_1 !=!mul_add_c(a[5],b[0],c3,c1,c2);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12 !=
+ stuw t_1,rp(5) !r[5]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_6,b_0,t_1 !mul_add_c(a[6],b[0],c1,c2,c3);
+ addcc c_12,t_1,c_12 !=
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_5,b_1,t_1 !=!mul_add_c(a[5],b[1],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_4,b_2,t_1 !=!mul_add_c(a[4],b[2],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_3,b_3,t_1 !=!mul_add_c(a[3],b[3],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_2,b_4,t_1 !=!mul_add_c(a[2],b[4],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw bp(6),b_6 !=
+ mulx a_1,b_5,t_1 !mul_add_c(a[1],b[5],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ lduw bp(7),b_7
+ mulx a_0,b_6,t_1 !mul_add_c(a[0],b[6],c1,c2,c3);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(6) !r[6]=c1;
+ or c_12,c_3,c_12 !=
+
+ mulx a_0,b_7,t_1 !mul_add_c(a[0],b[7],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_1,b_6,t_1 !mul_add_c(a[1],b[6],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_2,b_5,t_1 !mul_add_c(a[2],b[5],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_3,b_4,t_1 !mul_add_c(a[3],b[4],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_4,b_3,t_1 !mul_add_c(a[4],b[3],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_5,b_2,t_1 !mul_add_c(a[5],b[2],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ lduw ap(7),a_7
+ mulx a_6,b_1,t_1 !=!mul_add_c(a[6],b[1],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_7,b_0,t_1 !=!mul_add_c(a[7],b[0],c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12 !=
+ stuw t_1,rp(7) !r[7]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_7,b_1,t_1 !=!mul_add_c(a[7],b[1],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ mulx a_6,b_2,t_1 !mul_add_c(a[6],b[2],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ mulx a_5,b_3,t_1 !mul_add_c(a[5],b[3],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ mulx a_4,b_4,t_1 !mul_add_c(a[4],b[4],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ mulx a_3,b_5,t_1 !mul_add_c(a[3],b[5],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ mulx a_2,b_6,t_1 !mul_add_c(a[2],b[6],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ mulx a_1,b_7,t_1 !mul_add_c(a[1],b[7],c3,c1,c2);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ srlx t_1,32,c_12
+ stuw t_1,rp(8) !r[8]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_2,b_7,t_1 !=!mul_add_c(a[2],b[7],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ mulx a_3,b_6,t_1 !mul_add_c(a[3],b[6],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_4,b_5,t_1 !mul_add_c(a[4],b[5],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_5,b_4,t_1 !mul_add_c(a[5],b[4],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_6,b_3,t_1 !mul_add_c(a[6],b[3],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_7,b_2,t_1 !mul_add_c(a[7],b[2],c1,c2,c3);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(9) !r[9]=c1;
+ or c_12,c_3,c_12 !=
+
+ mulx a_7,b_3,t_1 !mul_add_c(a[7],b[3],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_6,b_4,t_1 !mul_add_c(a[6],b[4],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_5,b_5,t_1 !mul_add_c(a[5],b[5],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_4,b_6,t_1 !mul_add_c(a[4],b[6],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_3,b_7,t_1 !mul_add_c(a[3],b[7],c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(10) !r[10]=c2;
+ or c_12,c_3,c_12 !=
+
+ mulx a_4,b_7,t_1 !mul_add_c(a[4],b[7],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_5,b_6,t_1 !mul_add_c(a[5],b[6],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_6,b_5,t_1 !mul_add_c(a[6],b[5],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_7,b_4,t_1 !mul_add_c(a[7],b[4],c3,c1,c2);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(11) !r[11]=c3;
+ or c_12,c_3,c_12 !=
+
+ mulx a_7,b_5,t_1 !mul_add_c(a[7],b[5],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_6,b_6,t_1 !mul_add_c(a[6],b[6],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_5,b_7,t_1 !mul_add_c(a[5],b[7],c1,c2,c3);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(12) !r[12]=c1;
+ or c_12,c_3,c_12 !=
+
+ mulx a_6,b_7,t_1 !mul_add_c(a[6],b[7],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_7,b_6,t_1 !mul_add_c(a[7],b[6],c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ st t_1,rp(13) !r[13]=c2;
+ or c_12,c_3,c_12 !=
+
+ mulx a_7,b_7,t_1 !mul_add_c(a[7],b[7],c3,c1,c2);
+ addcc c_12,t_1,t_1
+ srlx t_1,32,c_12 !=
+ stuw t_1,rp(14) !r[14]=c3;
+ stuw c_12,rp(15) !r[15]=c1;
+
+ ret
+ restore %g0,%g0,%o0 !=
+
+.type bn_mul_comba8,#function
+.size bn_mul_comba8,(.-bn_mul_comba8)
+
+.align 32
+
+.global bn_mul_comba4
+/*
+ * void bn_mul_comba4(r,a,b)
+ * BN_ULONG *r,*a,*b;
+ */
+bn_mul_comba4:
+ save %sp,FRAME_SIZE,%sp
+ lduw ap(0),a_0
+ mov 1,t_2
+ lduw bp(0),b_0
+ sllx t_2,32,t_2 !=
+ lduw bp(1),b_1
+ mulx a_0,b_0,t_1 !mul_add_c(a[0],b[0],c1,c2,c3);
+ srlx t_1,32,c_12
+ stuw t_1,rp(0) !=!r[0]=c1;
+
+ lduw ap(1),a_1
+ mulx a_0,b_1,t_1 !mul_add_c(a[0],b[1],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(2),a_2
+ mulx a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12 !=
+ stuw t_1,rp(1) !r[1]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2);
+ addcc c_12,t_1,c_12 !=
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw bp(2),b_2 !=
+ mulx a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3 !=
+ lduw bp(3),b_3
+ mulx a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(2) !r[2]=c3;
+ or c_12,c_3,c_12 !=
+
+ mulx a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ mulx a_1,b_2,t_1 !mul_add_c(a[1],b[2],c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8 !=
+ add c_3,t_2,c_3
+ lduw ap(3),a_3
+ mulx a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3);
+ addcc c_12,t_1,c_12 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_3,b_0,t_1 !mul_add_c(a[3],b[0],c1,c2,c3);!=
+ addcc c_12,t_1,t_1 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(3) !=!r[3]=c1;
+ or c_12,c_3,c_12
+
+ mulx a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_2,b_2,t_1 !mul_add_c(a[2],b[2],c2,c3,c1);
+ addcc c_12,t_1,c_12 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1);
+ addcc c_12,t_1,t_1 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(4) !=!r[4]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2);
+ addcc c_12,t_1,t_1 !=
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(5) !=!r[5]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3);
+ addcc c_12,t_1,t_1
+ srlx t_1,32,c_12 !=
+ stuw t_1,rp(6) !r[6]=c1;
+ stuw c_12,rp(7) !r[7]=c2;
+
+ ret
+ restore %g0,%g0,%o0
+
+.type bn_mul_comba4,#function
+.size bn_mul_comba4,(.-bn_mul_comba4)
+
+.align 32
+
+.global bn_sqr_comba8
+bn_sqr_comba8:
+ save %sp,FRAME_SIZE,%sp
+ mov 1,t_2
+ lduw ap(0),a_0
+ sllx t_2,32,t_2
+ lduw ap(1),a_1
+ mulx a_0,a_0,t_1 !sqr_add_c(a,0,c1,c2,c3);
+ srlx t_1,32,c_12
+ stuw t_1,rp(0) !r[0]=c1;
+
+ lduw ap(2),a_2
+ mulx a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(1) !r[1]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(3),a_3
+ mulx a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(2) !r[2]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(4),a_4
+ mulx a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ st t_1,rp(3) !r[3]=c1;
+ or c_12,c_3,c_12
+
+ mulx a_4,a_0,t_1 !sqr_add_c2(a,4,0,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(5),a_5
+ mulx a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(4) !r[4]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_0,a_5,t_1 !sqr_add_c2(a,5,0,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_1,a_4,t_1 !sqr_add_c2(a,4,1,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(6),a_6
+ mulx a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(5) !r[5]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_6,a_0,t_1 !sqr_add_c2(a,6,0,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_5,a_1,t_1 !sqr_add_c2(a,5,1,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_4,a_2,t_1 !sqr_add_c2(a,4,2,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(7),a_7
+ mulx a_3,a_3,t_1 !=!sqr_add_c(a,3,c1,c2,c3);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(6) !r[6]=c1;
+ or c_12,c_3,c_12
+
+ mulx a_0,a_7,t_1 !sqr_add_c2(a,7,0,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_1,a_6,t_1 !sqr_add_c2(a,6,1,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_2,a_5,t_1 !sqr_add_c2(a,5,2,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_3,a_4,t_1 !sqr_add_c2(a,4,3,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(7) !r[7]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_7,a_1,t_1 !sqr_add_c2(a,7,1,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_6,a_2,t_1 !sqr_add_c2(a,6,2,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_5,a_3,t_1 !sqr_add_c2(a,5,3,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_4,a_4,t_1 !sqr_add_c(a,4,c3,c1,c2);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(8) !r[8]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_2,a_7,t_1 !sqr_add_c2(a,7,2,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_3,a_6,t_1 !sqr_add_c2(a,6,3,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_4,a_5,t_1 !sqr_add_c2(a,5,4,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(9) !r[9]=c1;
+ or c_12,c_3,c_12
+
+ mulx a_7,a_3,t_1 !sqr_add_c2(a,7,3,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_6,a_4,t_1 !sqr_add_c2(a,6,4,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_5,a_5,t_1 !sqr_add_c(a,5,c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(10) !r[10]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_4,a_7,t_1 !sqr_add_c2(a,7,4,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_5,a_6,t_1 !sqr_add_c2(a,6,5,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(11) !r[11]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_7,a_5,t_1 !sqr_add_c2(a,7,5,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_6,a_6,t_1 !sqr_add_c(a,6,c1,c2,c3);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(12) !r[12]=c1;
+ or c_12,c_3,c_12
+
+ mulx a_6,a_7,t_1 !sqr_add_c2(a,7,6,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(13) !r[13]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_7,a_7,t_1 !sqr_add_c(a,7,c3,c1,c2);
+ addcc c_12,t_1,t_1
+ srlx t_1,32,c_12
+ stuw t_1,rp(14) !r[14]=c3;
+ stuw c_12,rp(15) !r[15]=c1;
+
+ ret
+ restore %g0,%g0,%o0
+
+.type bn_sqr_comba8,#function
+.size bn_sqr_comba8,(.-bn_sqr_comba8)
+
+.align 32
+
+.global bn_sqr_comba4
+/*
+ * void bn_sqr_comba4(r,a)
+ * BN_ULONG *r,*a;
+ */
+bn_sqr_comba4:
+ save %sp,FRAME_SIZE,%sp
+ mov 1,t_2
+ lduw ap(0),a_0
+ sllx t_2,32,t_2
+ lduw ap(1),a_1
+ mulx a_0,a_0,t_1 !sqr_add_c(a,0,c1,c2,c3);
+ srlx t_1,32,c_12
+ stuw t_1,rp(0) !r[0]=c1;
+
+ lduw ap(2),a_2
+ mulx a_0,a_1,t_1 !sqr_add_c2(a,1,0,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(1) !r[1]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ lduw ap(3),a_3
+ mulx a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(2) !r[2]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3);
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(3) !r[3]=c1;
+ or c_12,c_3,c_12
+
+ mulx a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,c_12
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ mulx a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1);
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(4) !r[4]=c2;
+ or c_12,c_3,c_12
+
+ mulx a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2);
+ addcc c_12,t_1,c_12
+ clr c_3
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ addcc c_12,t_1,t_1
+ bcs,a %xcc,.+8
+ add c_3,t_2,c_3
+ srlx t_1,32,c_12
+ stuw t_1,rp(5) !r[5]=c3;
+ or c_12,c_3,c_12
+
+ mulx a_3,a_3,t_1 !sqr_add_c(a,3,c1,c2,c3);
+ addcc c_12,t_1,t_1
+ srlx t_1,32,c_12
+ stuw t_1,rp(6) !r[6]=c1;
+ stuw c_12,rp(7) !r[7]=c2;
+
+ ret
+ restore %g0,%g0,%o0
+
+.type bn_sqr_comba4,#function
+.size bn_sqr_comba4,(.-bn_sqr_comba4)
+
+.align 32
diff --git a/openssl/trunk/crypto/bn/asm/vms.mar b/openssl/trunk/crypto/bn/asm/vms.mar
new file mode 100644
index 00000000..aefab15c
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/vms.mar
@@ -0,0 +1,6440 @@
+ .title vax_bn_mul_add_words unsigned multiply & add, 32*32+32+32=>64
+;
+; w.j.m. 15-jan-1999
+;
+; it's magic ...
+;
+; ULONG bn_mul_add_words(ULONG r[],ULONG a[],int n,ULONG w) {
+; ULONG c = 0;
+; int i;
+; for(i = 0; i < n; i++) <c,r[i]> := r[i] + c + a[i] * w ;
+; return c;
+; }
+
+r=4 ;(AP)
+a=8 ;(AP)
+n=12 ;(AP) n by value (input)
+w=16 ;(AP) w by value (input)
+
+
+ .psect code,nowrt
+
+.entry bn_mul_add_words,^m<r2,r3,r4,r5,r6>
+
+ moval @r(ap),r2
+ moval @a(ap),r3
+ movl n(ap),r4 ; assumed >0 by C code
+ movl w(ap),r5
+ clrl r6 ; c
+
+0$:
+ emul r5,(r3),(r2),r0 ; w, a[], r[] considered signed
+
+ ; fixup for "negative" r[]
+ tstl (r2)
+ bgeq 10$
+ incl r1
+10$:
+
+ ; add in c
+ addl2 r6,r0
+ adwc #0,r1
+
+ ; combined fixup for "negative" w, a[]
+ tstl r5
+ bgeq 20$
+ addl2 (r3),r1
+20$:
+ tstl (r3)
+ bgeq 30$
+ addl2 r5,r1
+30$:
+
+ movl r0,(r2)+ ; store lo result in r[] & advance
+ addl #4,r3 ; advance a[]
+ movl r1,r6 ; store hi result => c
+
+ sobgtr r4,0$
+
+ movl r6,r0 ; return c
+ ret
+
+ .title vax_bn_mul_words unsigned multiply & add, 32*32+32=>64
+;
+; w.j.m. 15-jan-1999
+;
+; it's magic ...
+;
+; ULONG bn_mul_words(ULONG r[],ULONG a[],int n,ULONG w) {
+; ULONG c = 0;
+; int i;
+; for(i = 0; i < num; i++) <c,r[i]> := a[i] * w + c ;
+; return(c);
+; }
+
+r=4 ;(AP)
+a=8 ;(AP)
+n=12 ;(AP) n by value (input)
+w=16 ;(AP) w by value (input)
+
+
+ .psect code,nowrt
+
+.entry bn_mul_words,^m<r2,r3,r4,r5,r6>
+
+ moval @r(ap),r2 ; r2 -> r[]
+ moval @a(ap),r3 ; r3 -> a[]
+ movl n(ap),r4 ; r4 = loop count (assumed >0 by C code)
+ movl w(ap),r5 ; r5 = w
+ clrl r6 ; r6 = c
+
+0$:
+ ; <r1,r0> := w * a[] + c
+ emul r5,(r3),r6,r0 ; w, a[], c considered signed
+
+ ; fixup for "negative" c
+ tstl r6 ; c
+ bgeq 10$
+ incl r1
+10$:
+
+ ; combined fixup for "negative" w, a[]
+ tstl r5 ; w
+ bgeq 20$
+ addl2 (r3),r1 ; a[]
+20$:
+ tstl (r3) ; a[]
+ bgeq 30$
+ addl2 r5,r1 ; w
+30$:
+
+ movl r0,(r2)+ ; store lo result in r[] & advance
+ addl #4,r3 ; advance a[]
+ movl r1,r6 ; store hi result => c
+
+ sobgtr r4,0$
+
+ movl r6,r0 ; return c
+ ret
+
+ .title vax_bn_sqr_words unsigned square, 32*32=>64
+;
+; w.j.m. 15-jan-1999
+;
+; it's magic ...
+;
+; void bn_sqr_words(ULONG r[],ULONG a[],int n) {
+; int i;
+; for(i = 0; i < n; i++) <r[2*i+1],r[2*i]> := a[i] * a[i] ;
+; }
+
+r=4 ;(AP)
+a=8 ;(AP)
+n=12 ;(AP) n by value (input)
+
+
+ .psect code,nowrt
+
+.entry bn_sqr_words,^m<r2,r3,r4,r5>
+
+ moval @r(ap),r2 ; r2 -> r[]
+ moval @a(ap),r3 ; r3 -> a[]
+ movl n(ap),r4 ; r4 = n (assumed >0 by C code)
+
+0$:
+ movl (r3)+,r5 ; r5 = a[] & advance
+
+ ; <r1,r0> := a[] * a[]
+ emul r5,r5,#0,r0 ; a[] considered signed
+
+ ; fixup for "negative" a[]
+ tstl r5 ; a[]
+ bgeq 30$
+ addl2 r5,r1 ; a[]
+ addl2 r5,r1 ; a[]
+30$:
+
+ movl r0,(r2)+ ; store lo result in r[] & advance
+ movl r1,(r2)+ ; store hi result in r[] & advance
+
+ sobgtr r4,0$
+
+ movl #1,r0 ; return SS$_NORMAL
+ ret
+
+ .title vax_bn_div_words unsigned divide
+;
+; Richard Levitte 20-Nov-2000
+;
+; ULONG bn_div_words(ULONG h, ULONG l, ULONG d)
+; {
+; return ((ULONG)((((ULLONG)h)<<32)|l) / (ULLONG)d);
+; }
+;
+; Using EDIV would be very easy, if it didn't do signed calculations.
+; Any time any of the input numbers are signed, there are problems,
+; usually with integer overflow, at which point it returns useless
+; data (the quotient gets the value of l, and the remainder becomes 0).
+;
+; If it was just for the dividend, it would be very easy, just divide
+; it by 2 (unsigned), do the division, multiply the resulting quotient
+; and remainder by 2, add the bit that was dropped when dividing by 2
+; to the remainder, and do some adjustment so the remainder doesn't
+; end up larger than the divisor. For some cases when the divisor is
+; negative (from EDIV's point of view, i.e. when the highest bit is set),
+; dividing the dividend by 2 isn't enough, and since some operations
+; might generate integer overflows even when the dividend is divided by
+; 4 (when the high part of the shifted down dividend ends up being exactly
+; half of the divisor, the result is the quotient 0x80000000, which is
+; negative...) it needs to be divided by 8. Furthermore, the divisor needs
+; to be divided by 2 (unsigned) as well, to avoid more problems with the sign.
+; In this case, a little extra fiddling with the remainder is required.
+;
+; So, the simplest way to handle this is always to divide the dividend
+; by 8, and to divide the divisor by 2 if it's highest bit is set.
+; After EDIV has been used, the quotient gets multiplied by 8 if the
+; original divisor was positive, otherwise 4. The remainder, oddly
+; enough, is *always* multiplied by 8.
+; NOTE: in the case mentioned above, where the high part of the shifted
+; down dividend ends up being exactly half the shifted down divisor, we
+; end up with a 33 bit quotient. That's no problem however, it usually
+; means we have ended up with a too large remainder as well, and the
+; problem is fixed by the last part of the algorithm (next paragraph).
+;
+; The routine ends with comparing the resulting remainder with the
+; original divisor and if the remainder is larger, subtract the
+; original divisor from it, and increase the quotient by 1. This is
+; done until the remainder is smaller than the divisor.
+;
+; The complete algorithm looks like this:
+;
+; d' = d
+; l' = l & 7
+; [h,l] = [h,l] >> 3
+; [q,r] = floor([h,l] / d) # This is the EDIV operation
+; if (q < 0) q = -q # I doubt this is necessary any more
+;
+; r' = r >> 29
+; if (d' >= 0)
+; q' = q >> 29
+; q = q << 3
+; else
+; q' = q >> 30
+; q = q << 2
+; r = (r << 3) + l'
+;
+; if (d' < 0)
+; {
+; [r',r] = [r',r] - q
+; while ([r',r] < 0)
+; {
+; [r',r] = [r',r] + d
+; [q',q] = [q',q] - 1
+; }
+; }
+;
+; while ([r',r] >= d')
+; {
+; [r',r] = [r',r] - d'
+; [q',q] = [q',q] + 1
+; }
+;
+; return q
+
+h=4 ;(AP) h by value (input)
+l=8 ;(AP) l by value (input)
+d=12 ;(AP) d by value (input)
+
+;r2 = l, q
+;r3 = h, r
+;r4 = d
+;r5 = l'
+;r6 = r'
+;r7 = d'
+;r8 = q'
+
+ .psect code,nowrt
+
+.entry bn_div_words,^m<r2,r3,r4,r5,r6,r7,r8>
+ movl l(ap),r2
+ movl h(ap),r3
+ movl d(ap),r4
+
+ bicl3 #^XFFFFFFF8,r2,r5 ; l' = l & 7
+ bicl3 #^X00000007,r2,r2
+
+ bicl3 #^XFFFFFFF8,r3,r6
+ bicl3 #^X00000007,r3,r3
+
+ addl r6,r2
+
+ rotl #-3,r2,r2 ; l = l >> 3
+ rotl #-3,r3,r3 ; h = h >> 3
+
+ movl r4,r7 ; d' = d
+
+ movl #0,r6 ; r' = 0
+ movl #0,r8 ; q' = 0
+
+ tstl r4
+ beql 666$ ; Uh-oh, the divisor is 0...
+ bgtr 1$
+ rotl #-1,r4,r4 ; If d is negative, shift it right.
+ bicl2 #^X80000000,r4 ; Since d is then a large number, the
+ ; lowest bit is insignificant
+ ; (contradict that, and I'll fix the problem!)
+1$:
+ ediv r4,r2,r2,r3 ; Do the actual division
+
+ tstl r2
+ bgeq 3$
+ mnegl r2,r2 ; if q < 0, negate it
+3$:
+ tstl r7
+ blss 4$
+ rotl #3,r2,r2 ; q = q << 3
+ bicl3 #^XFFFFFFF8,r2,r8 ; q' gets the high bits from q
+ bicl3 #^X00000007,r2,r2
+ bsb 41$
+4$: ; else
+ rotl #2,r2,r2 ; q = q << 2
+ bicl3 #^XFFFFFFFC,r2,r8 ; q' gets the high bits from q
+ bicl3 #^X00000003,r2,r2
+41$:
+ rotl #3,r3,r3 ; r = r << 3
+ bicl3 #^XFFFFFFF8,r3,r6 ; r' gets the high bits from r
+ bicl3 #^X00000007,r3,r3
+ addl r5,r3 ; r = r + l'
+
+ tstl r7
+ bgeq 5$
+ bitl #1,r7
+ beql 5$ ; if d' < 0 && d' & 1
+ subl r2,r3 ; [r',r] = [r',r] - [q',q]
+ sbwc r8,r6
+45$:
+ bgeq 5$ ; while r < 0
+ decl r2 ; [q',q] = [q',q] - 1
+ sbwc #0,r8
+ addl r7,r3 ; [r',r] = [r',r] + d'
+ adwc #0,r6
+ brb 45$
+
+; The return points are placed in the middle to keep a short distance from
+; all the branch points
+42$:
+; movl r3,r1
+ movl r2,r0
+ ret
+666$:
+ movl #^XFFFFFFFF,r0
+ ret
+
+5$:
+ tstl r6
+ bneq 6$
+ cmpl r3,r7
+ blssu 42$ ; while [r',r] >= d'
+6$:
+ subl r7,r3 ; [r',r] = [r',r] - d'
+ sbwc #0,r6
+ incl r2 ; [q',q] = [q',q] + 1
+ adwc #0,r8
+ brb 5$
+
+ .title vax_bn_add_words unsigned add of two arrays
+;
+; Richard Levitte 20-Nov-2000
+;
+; ULONG bn_add_words(ULONG r[], ULONG a[], ULONG b[], int n) {
+; ULONG c = 0;
+; int i;
+; for (i = 0; i < n; i++) <c,r[i]> = a[i] + b[i] + c;
+; return(c);
+; }
+
+r=4 ;(AP) r by reference (output)
+a=8 ;(AP) a by reference (input)
+b=12 ;(AP) b by reference (input)
+n=16 ;(AP) n by value (input)
+
+
+ .psect code,nowrt
+
+.entry bn_add_words,^m<r2,r3,r4,r5,r6>
+
+ moval @r(ap),r2
+ moval @a(ap),r3
+ moval @b(ap),r4
+ movl n(ap),r5 ; assumed >0 by C code
+ clrl r0 ; c
+
+ tstl r5 ; carry = 0
+ bleq 666$
+
+0$:
+ movl (r3)+,r6 ; carry untouched
+ adwc (r4)+,r6 ; carry used and touched
+ movl r6,(r2)+ ; carry untouched
+ sobgtr r5,0$ ; carry untouched
+
+ adwc #0,r0
+666$:
+ ret
+
+ .title vax_bn_sub_words unsigned add of two arrays
+;
+; Richard Levitte 20-Nov-2000
+;
+; ULONG bn_sub_words(ULONG r[], ULONG a[], ULONG b[], int n) {
+; ULONG c = 0;
+; int i;
+; for (i = 0; i < n; i++) <c,r[i]> = a[i] - b[i] - c;
+; return(c);
+; }
+
+r=4 ;(AP) r by reference (output)
+a=8 ;(AP) a by reference (input)
+b=12 ;(AP) b by reference (input)
+n=16 ;(AP) n by value (input)
+
+
+ .psect code,nowrt
+
+.entry bn_sub_words,^m<r2,r3,r4,r5,r6>
+
+ moval @r(ap),r2
+ moval @a(ap),r3
+ moval @b(ap),r4
+ movl n(ap),r5 ; assumed >0 by C code
+ clrl r0 ; c
+
+ tstl r5 ; carry = 0
+ bleq 666$
+
+0$:
+ movl (r3)+,r6 ; carry untouched
+ sbwc (r4)+,r6 ; carry used and touched
+ movl r6,(r2)+ ; carry untouched
+ sobgtr r5,0$ ; carry untouched
+
+ adwc #0,r0
+666$:
+ ret
+
+
+;r=4 ;(AP)
+;a=8 ;(AP)
+;b=12 ;(AP)
+;n=16 ;(AP) n by value (input)
+
+ .psect code,nowrt
+
+.entry BN_MUL_COMBA8,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
+ movab -924(sp),sp
+ clrq r8
+
+ clrl r10
+
+ movl 8(ap),r6
+ movzwl 2(r6),r3
+ movl 12(ap),r7
+ bicl3 #-65536,(r7),r2
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,(r6),-12(fp)
+ bicl3 #-65536,r3,-16(fp)
+ mull3 r0,-12(fp),-4(fp)
+ mull2 r2,-12(fp)
+ mull3 r2,-16(fp),-8(fp)
+ mull2 r0,-16(fp)
+ addl3 -4(fp),-8(fp),r0
+ bicl3 #0,r0,-4(fp)
+ cmpl -4(fp),-8(fp)
+ bgequ noname.45
+ addl2 #65536,-16(fp)
+noname.45:
+ movzwl -2(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-16(fp)
+ bicl3 #-65536,-4(fp),r0
+ ashl #16,r0,-8(fp)
+ addl3 -8(fp),-12(fp),r0
+ bicl3 #0,r0,-12(fp)
+ cmpl -12(fp),-8(fp)
+ bgequ noname.46
+ incl -16(fp)
+noname.46:
+ movl -12(fp),r1
+ movl -16(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.47
+ incl r2
+noname.47:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.48
+ incl r10
+noname.48:
+
+ movl 4(ap),r11
+ movl r9,(r11)
+
+ clrl r9
+
+ movzwl 2(r6),r2
+ bicl3 #-65536,4(r7),r3
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,(r6),-28(fp)
+ bicl3 #-65536,r2,-32(fp)
+ mull3 r0,-28(fp),-20(fp)
+ mull2 r3,-28(fp)
+ mull3 r3,-32(fp),-24(fp)
+ mull2 r0,-32(fp)
+ addl3 -20(fp),-24(fp),r0
+ bicl3 #0,r0,-20(fp)
+ cmpl -20(fp),-24(fp)
+ bgequ noname.49
+ addl2 #65536,-32(fp)
+noname.49:
+ movzwl -18(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-32(fp)
+ bicl3 #-65536,-20(fp),r0
+ ashl #16,r0,-24(fp)
+ addl3 -24(fp),-28(fp),r0
+ bicl3 #0,r0,-28(fp)
+ cmpl -28(fp),-24(fp)
+ bgequ noname.50
+ incl -32(fp)
+noname.50:
+ movl -28(fp),r1
+ movl -32(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.51
+ incl r2
+noname.51:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.52
+ incl r9
+noname.52:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,(r7),r3
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-44(fp)
+ bicl3 #-65536,r2,-48(fp)
+ mull3 r0,-44(fp),-36(fp)
+ mull2 r3,-44(fp)
+ mull3 r3,-48(fp),-40(fp)
+ mull2 r0,-48(fp)
+ addl3 -36(fp),-40(fp),r0
+ bicl3 #0,r0,-36(fp)
+ cmpl -36(fp),-40(fp)
+ bgequ noname.53
+ addl2 #65536,-48(fp)
+noname.53:
+ movzwl -34(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-48(fp)
+ bicl3 #-65536,-36(fp),r0
+ ashl #16,r0,-40(fp)
+ addl3 -40(fp),-44(fp),r0
+ bicl3 #0,r0,-44(fp)
+ cmpl -44(fp),-40(fp)
+ bgequ noname.54
+ incl -48(fp)
+noname.54:
+ movl -44(fp),r1
+ movl -48(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.55
+ incl r2
+noname.55:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.56
+ incl r9
+noname.56:
+
+ movl r8,4(r11)
+
+ clrl r8
+
+ movzwl 10(r6),r2
+ bicl3 #-65536,(r7),r3
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r6),-60(fp)
+ bicl3 #-65536,r2,-64(fp)
+ mull3 r0,-60(fp),-52(fp)
+ mull2 r3,-60(fp)
+ mull3 r3,-64(fp),-56(fp)
+ mull2 r0,-64(fp)
+ addl3 -52(fp),-56(fp),r0
+ bicl3 #0,r0,-52(fp)
+ cmpl -52(fp),-56(fp)
+ bgequ noname.57
+ addl2 #65536,-64(fp)
+noname.57:
+ movzwl -50(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-64(fp)
+ bicl3 #-65536,-52(fp),r0
+ ashl #16,r0,-56(fp)
+ addl3 -56(fp),-60(fp),r0
+ bicl3 #0,r0,-60(fp)
+ cmpl -60(fp),-56(fp)
+ bgequ noname.58
+ incl -64(fp)
+noname.58:
+ movl -60(fp),r1
+ movl -64(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.59
+ incl r2
+noname.59:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.60
+ incl r8
+noname.60:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,4(r7),r3
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-76(fp)
+ bicl3 #-65536,r2,-80(fp)
+ mull3 r0,-76(fp),-68(fp)
+ mull2 r3,-76(fp)
+ mull3 r3,-80(fp),-72(fp)
+ mull2 r0,-80(fp)
+ addl3 -68(fp),-72(fp),r0
+ bicl3 #0,r0,-68(fp)
+ cmpl -68(fp),-72(fp)
+ bgequ noname.61
+ addl2 #65536,-80(fp)
+noname.61:
+ movzwl -66(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-80(fp)
+ bicl3 #-65536,-68(fp),r0
+ ashl #16,r0,-72(fp)
+ addl3 -72(fp),-76(fp),r0
+ bicl3 #0,r0,-76(fp)
+ cmpl -76(fp),-72(fp)
+ bgequ noname.62
+ incl -80(fp)
+noname.62:
+ movl -76(fp),r1
+ movl -80(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.63
+ incl r2
+noname.63:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.64
+ incl r8
+noname.64:
+
+ movzwl 2(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,(r6),-92(fp)
+ bicl3 #-65536,r2,-96(fp)
+ mull3 r0,-92(fp),-84(fp)
+ mull2 r3,-92(fp)
+ mull3 r3,-96(fp),-88(fp)
+ mull2 r0,-96(fp)
+ addl3 -84(fp),-88(fp),r0
+ bicl3 #0,r0,-84(fp)
+ cmpl -84(fp),-88(fp)
+ bgequ noname.65
+ addl2 #65536,-96(fp)
+noname.65:
+ movzwl -82(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-96(fp)
+ bicl3 #-65536,-84(fp),r0
+ ashl #16,r0,-88(fp)
+ addl3 -88(fp),-92(fp),r0
+ bicl3 #0,r0,-92(fp)
+ cmpl -92(fp),-88(fp)
+ bgequ noname.66
+ incl -96(fp)
+noname.66:
+ movl -92(fp),r1
+ movl -96(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.67
+ incl r2
+noname.67:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.68
+ incl r8
+noname.68:
+
+ movl r10,8(r11)
+
+ clrl r10
+
+ movzwl 2(r6),r2
+ bicl3 #-65536,12(r7),r3
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,(r6),-108(fp)
+ bicl3 #-65536,r2,-112(fp)
+ mull3 r0,-108(fp),-100(fp)
+ mull2 r3,-108(fp)
+ mull3 r3,-112(fp),-104(fp)
+ mull2 r0,-112(fp)
+ addl3 -100(fp),-104(fp),r0
+ bicl3 #0,r0,-100(fp)
+ cmpl -100(fp),-104(fp)
+ bgequ noname.69
+ addl2 #65536,-112(fp)
+noname.69:
+ movzwl -98(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-112(fp)
+ bicl3 #-65536,-100(fp),r0
+ ashl #16,r0,-104(fp)
+ addl3 -104(fp),-108(fp),r0
+ bicl3 #0,r0,-108(fp)
+ cmpl -108(fp),-104(fp)
+ bgequ noname.70
+ incl -112(fp)
+noname.70:
+ movl -108(fp),r1
+ movl -112(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.71
+ incl r2
+noname.71:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.72
+ incl r10
+noname.72:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-124(fp)
+ bicl3 #-65536,r2,-128(fp)
+ mull3 r0,-124(fp),-116(fp)
+ mull2 r3,-124(fp)
+ mull3 r3,-128(fp),-120(fp)
+ mull2 r0,-128(fp)
+ addl3 -116(fp),-120(fp),r0
+ bicl3 #0,r0,-116(fp)
+ cmpl -116(fp),-120(fp)
+ bgequ noname.73
+ addl2 #65536,-128(fp)
+noname.73:
+ movzwl -114(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-128(fp)
+ bicl3 #-65536,-116(fp),r0
+ ashl #16,r0,-120(fp)
+ addl3 -120(fp),-124(fp),r0
+ bicl3 #0,r0,-124(fp)
+ cmpl -124(fp),-120(fp)
+ bgequ noname.74
+ incl -128(fp)
+noname.74:
+ movl -124(fp),r1
+ movl -128(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.75
+ incl r2
+noname.75:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.76
+ incl r10
+noname.76:
+
+ movzwl 10(r6),r2
+ bicl3 #-65536,4(r7),r3
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r6),-140(fp)
+ bicl3 #-65536,r2,-144(fp)
+ mull3 r0,-140(fp),-132(fp)
+ mull2 r3,-140(fp)
+ mull3 r3,-144(fp),-136(fp)
+ mull2 r0,-144(fp)
+ addl3 -132(fp),-136(fp),r0
+ bicl3 #0,r0,-132(fp)
+ cmpl -132(fp),-136(fp)
+ bgequ noname.77
+ addl2 #65536,-144(fp)
+noname.77:
+ movzwl -130(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-144(fp)
+ bicl3 #-65536,-132(fp),r0
+ ashl #16,r0,-136(fp)
+ addl3 -136(fp),-140(fp),r0
+ bicl3 #0,r0,-140(fp)
+ cmpl -140(fp),-136(fp)
+ bgequ noname.78
+ incl -144(fp)
+noname.78:
+ movl -140(fp),r1
+ movl -144(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.79
+ incl r2
+noname.79:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.80
+ incl r10
+noname.80:
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,(r7),r3
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-156(fp)
+ bicl3 #-65536,r2,-160(fp)
+ mull3 r0,-156(fp),-148(fp)
+ mull2 r3,-156(fp)
+ mull3 r3,-160(fp),-152(fp)
+ mull2 r0,-160(fp)
+ addl3 -148(fp),-152(fp),r0
+ bicl3 #0,r0,-148(fp)
+ cmpl -148(fp),-152(fp)
+ bgequ noname.81
+ addl2 #65536,-160(fp)
+noname.81:
+ movzwl -146(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-160(fp)
+ bicl3 #-65536,-148(fp),r0
+ ashl #16,r0,-152(fp)
+ addl3 -152(fp),-156(fp),r0
+ bicl3 #0,r0,-156(fp)
+ cmpl -156(fp),-152(fp)
+ bgequ noname.82
+ incl -160(fp)
+noname.82:
+ movl -156(fp),r1
+ movl -160(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.83
+ incl r2
+noname.83:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.84
+ incl r10
+noname.84:
+
+ movl r9,12(r11)
+
+ clrl r9
+
+ movzwl 18(r6),r2
+ bicl3 #-65536,(r7),r3
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,16(r6),-172(fp)
+ bicl3 #-65536,r2,-176(fp)
+ mull3 r0,-172(fp),-164(fp)
+ mull2 r3,-172(fp)
+ mull3 r3,-176(fp),-168(fp)
+ mull2 r0,-176(fp)
+ addl3 -164(fp),-168(fp),r0
+ bicl3 #0,r0,-164(fp)
+ cmpl -164(fp),-168(fp)
+ bgequ noname.85
+ addl2 #65536,-176(fp)
+noname.85:
+ movzwl -162(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-176(fp)
+ bicl3 #-65536,-164(fp),r0
+ ashl #16,r0,-168(fp)
+ addl3 -168(fp),-172(fp),r0
+ bicl3 #0,r0,-172(fp)
+ cmpl -172(fp),-168(fp)
+ bgequ noname.86
+ incl -176(fp)
+noname.86:
+ movl -172(fp),r1
+ movl -176(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.87
+ incl r2
+noname.87:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.88
+ incl r9
+noname.88:
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,4(r7),r3
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-188(fp)
+ bicl3 #-65536,r2,-192(fp)
+ mull3 r0,-188(fp),-180(fp)
+ mull2 r3,-188(fp)
+ mull3 r3,-192(fp),-184(fp)
+ mull2 r0,-192(fp)
+ addl3 -180(fp),-184(fp),r0
+ bicl3 #0,r0,-180(fp)
+ cmpl -180(fp),-184(fp)
+ bgequ noname.89
+ addl2 #65536,-192(fp)
+noname.89:
+ movzwl -178(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-192(fp)
+ bicl3 #-65536,-180(fp),r0
+ ashl #16,r0,-184(fp)
+ addl3 -184(fp),-188(fp),r0
+ bicl3 #0,r0,-188(fp)
+ cmpl -188(fp),-184(fp)
+ bgequ noname.90
+ incl -192(fp)
+noname.90:
+ movl -188(fp),r1
+ movl -192(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.91
+ incl r2
+noname.91:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.92
+ incl r9
+noname.92:
+
+ movzwl 10(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r6),-204(fp)
+ bicl3 #-65536,r2,-208(fp)
+ mull3 r0,-204(fp),-196(fp)
+ mull2 r3,-204(fp)
+ mull3 r3,-208(fp),-200(fp)
+ mull2 r0,-208(fp)
+ addl3 -196(fp),-200(fp),r0
+ bicl3 #0,r0,-196(fp)
+ cmpl -196(fp),-200(fp)
+ bgequ noname.93
+ addl2 #65536,-208(fp)
+noname.93:
+ movzwl -194(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-208(fp)
+ bicl3 #-65536,-196(fp),r0
+ ashl #16,r0,-200(fp)
+ addl3 -200(fp),-204(fp),r0
+ bicl3 #0,r0,-204(fp)
+ cmpl -204(fp),-200(fp)
+ bgequ noname.94
+ incl -208(fp)
+noname.94:
+ movl -204(fp),r1
+ movl -208(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.95
+ incl r2
+noname.95:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.96
+ incl r9
+noname.96:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,12(r7),r3
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-220(fp)
+ bicl3 #-65536,r2,-224(fp)
+ mull3 r0,-220(fp),-212(fp)
+ mull2 r3,-220(fp)
+ mull3 r3,-224(fp),-216(fp)
+ mull2 r0,-224(fp)
+ addl3 -212(fp),-216(fp),r0
+ bicl3 #0,r0,-212(fp)
+ cmpl -212(fp),-216(fp)
+ bgequ noname.97
+ addl2 #65536,-224(fp)
+noname.97:
+ movzwl -210(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-224(fp)
+ bicl3 #-65536,-212(fp),r0
+ ashl #16,r0,-216(fp)
+ addl3 -216(fp),-220(fp),r0
+ bicl3 #0,r0,-220(fp)
+ cmpl -220(fp),-216(fp)
+ bgequ noname.98
+ incl -224(fp)
+noname.98:
+ movl -220(fp),r1
+ movl -224(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.99
+ incl r2
+noname.99:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.100
+ incl r9
+noname.100:
+
+ movzwl 2(r6),r2
+ bicl3 #-65536,16(r7),r3
+ movzwl 18(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,(r6),-236(fp)
+ bicl3 #-65536,r2,-240(fp)
+ mull3 r0,-236(fp),-228(fp)
+ mull2 r3,-236(fp)
+ mull3 r3,-240(fp),-232(fp)
+ mull2 r0,-240(fp)
+ addl3 -228(fp),-232(fp),r0
+ bicl3 #0,r0,-228(fp)
+ cmpl -228(fp),-232(fp)
+ bgequ noname.101
+ addl2 #65536,-240(fp)
+noname.101:
+ movzwl -226(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-240(fp)
+ bicl3 #-65536,-228(fp),r0
+ ashl #16,r0,-232(fp)
+ addl3 -232(fp),-236(fp),r0
+ bicl3 #0,r0,-236(fp)
+ cmpl -236(fp),-232(fp)
+ bgequ noname.102
+ incl -240(fp)
+noname.102:
+ movl -236(fp),r1
+ movl -240(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.103
+ incl r2
+noname.103:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.104
+ incl r9
+noname.104:
+
+ movl r8,16(r11)
+
+ clrl r8
+
+ movzwl 2(r6),r2
+ bicl3 #-65536,20(r7),r3
+ movzwl 22(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,(r6),-252(fp)
+ bicl3 #-65536,r2,-256(fp)
+ mull3 r0,-252(fp),-244(fp)
+ mull2 r3,-252(fp)
+ mull3 r3,-256(fp),-248(fp)
+ mull2 r0,-256(fp)
+ addl3 -244(fp),-248(fp),r0
+ bicl3 #0,r0,-244(fp)
+ cmpl -244(fp),-248(fp)
+ bgequ noname.105
+ addl2 #65536,-256(fp)
+noname.105:
+ movzwl -242(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-256(fp)
+ bicl3 #-65536,-244(fp),r0
+ ashl #16,r0,-248(fp)
+ addl3 -248(fp),-252(fp),r0
+ bicl3 #0,r0,-252(fp)
+ cmpl -252(fp),-248(fp)
+ bgequ noname.106
+ incl -256(fp)
+noname.106:
+ movl -252(fp),r1
+ movl -256(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.107
+ incl r2
+noname.107:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.108
+ incl r8
+noname.108:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,16(r7),r3
+ movzwl 18(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-268(fp)
+ bicl3 #-65536,r2,-272(fp)
+ mull3 r0,-268(fp),-260(fp)
+ mull2 r3,-268(fp)
+ mull3 r3,-272(fp),-264(fp)
+ mull2 r0,-272(fp)
+ addl3 -260(fp),-264(fp),r0
+ bicl3 #0,r0,-260(fp)
+ cmpl -260(fp),-264(fp)
+ bgequ noname.109
+ addl2 #65536,-272(fp)
+noname.109:
+ movzwl -258(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-272(fp)
+ bicl3 #-65536,-260(fp),r0
+ ashl #16,r0,-264(fp)
+ addl3 -264(fp),-268(fp),r0
+ bicl3 #0,r0,-268(fp)
+ cmpl -268(fp),-264(fp)
+ bgequ noname.110
+ incl -272(fp)
+noname.110:
+ movl -268(fp),r1
+ movl -272(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.111
+ incl r2
+noname.111:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.112
+ incl r8
+noname.112:
+
+ movzwl 10(r6),r2
+ bicl3 #-65536,12(r7),r3
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r6),-284(fp)
+ bicl3 #-65536,r2,-288(fp)
+ mull3 r0,-284(fp),-276(fp)
+ mull2 r3,-284(fp)
+ mull3 r3,-288(fp),-280(fp)
+ mull2 r0,-288(fp)
+ addl3 -276(fp),-280(fp),r0
+ bicl3 #0,r0,-276(fp)
+ cmpl -276(fp),-280(fp)
+ bgequ noname.113
+ addl2 #65536,-288(fp)
+noname.113:
+ movzwl -274(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-288(fp)
+ bicl3 #-65536,-276(fp),r0
+ ashl #16,r0,-280(fp)
+ addl3 -280(fp),-284(fp),r0
+ bicl3 #0,r0,-284(fp)
+ cmpl -284(fp),-280(fp)
+ bgequ noname.114
+ incl -288(fp)
+noname.114:
+ movl -284(fp),r1
+ movl -288(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.115
+ incl r2
+noname.115:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.116
+ incl r8
+noname.116:
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-300(fp)
+ bicl3 #-65536,r2,-304(fp)
+ mull3 r0,-300(fp),-292(fp)
+ mull2 r3,-300(fp)
+ mull3 r3,-304(fp),-296(fp)
+ mull2 r0,-304(fp)
+ addl3 -292(fp),-296(fp),r0
+ bicl3 #0,r0,-292(fp)
+ cmpl -292(fp),-296(fp)
+ bgequ noname.117
+ addl2 #65536,-304(fp)
+noname.117:
+ movzwl -290(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-304(fp)
+ bicl3 #-65536,-292(fp),r0
+ ashl #16,r0,-296(fp)
+ addl3 -296(fp),-300(fp),r0
+ bicl3 #0,r0,-300(fp)
+ cmpl -300(fp),-296(fp)
+ bgequ noname.118
+ incl -304(fp)
+noname.118:
+ movl -300(fp),r1
+ movl -304(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.119
+ incl r2
+noname.119:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.120
+ incl r8
+noname.120:
+
+ movzwl 18(r6),r2
+ bicl3 #-65536,4(r7),r3
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,16(r6),-316(fp)
+ bicl3 #-65536,r2,-320(fp)
+ mull3 r0,-316(fp),-308(fp)
+ mull2 r3,-316(fp)
+ mull3 r3,-320(fp),-312(fp)
+ mull2 r0,-320(fp)
+ addl3 -308(fp),-312(fp),r0
+ bicl3 #0,r0,-308(fp)
+ cmpl -308(fp),-312(fp)
+ bgequ noname.121
+ addl2 #65536,-320(fp)
+noname.121:
+ movzwl -306(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-320(fp)
+ bicl3 #-65536,-308(fp),r0
+ ashl #16,r0,-312(fp)
+ addl3 -312(fp),-316(fp),r0
+ bicl3 #0,r0,-316(fp)
+ cmpl -316(fp),-312(fp)
+ bgequ noname.122
+ incl -320(fp)
+noname.122:
+ movl -316(fp),r1
+ movl -320(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.123
+ incl r2
+
+noname.123:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.124
+ incl r8
+noname.124:
+
+ movzwl 22(r6),r2
+ bicl3 #-65536,(r7),r3
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,20(r6),-332(fp)
+ bicl3 #-65536,r2,-336(fp)
+ mull3 r0,-332(fp),-324(fp)
+ mull2 r3,-332(fp)
+ mull3 r3,-336(fp),-328(fp)
+ mull2 r0,-336(fp)
+ addl3 -324(fp),-328(fp),r0
+ bicl3 #0,r0,-324(fp)
+ cmpl -324(fp),-328(fp)
+ bgequ noname.125
+ addl2 #65536,-336(fp)
+noname.125:
+ movzwl -322(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-336(fp)
+ bicl3 #-65536,-324(fp),r0
+ ashl #16,r0,-328(fp)
+ addl3 -328(fp),-332(fp),r0
+ bicl3 #0,r0,-332(fp)
+ cmpl -332(fp),-328(fp)
+ bgequ noname.126
+ incl -336(fp)
+noname.126:
+ movl -332(fp),r1
+ movl -336(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.127
+ incl r2
+noname.127:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.128
+ incl r8
+noname.128:
+
+ movl r10,20(r11)
+
+ clrl r10
+
+ movzwl 26(r6),r2
+ bicl3 #-65536,(r7),r3
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,24(r6),-348(fp)
+ bicl3 #-65536,r2,-352(fp)
+ mull3 r0,-348(fp),-340(fp)
+ mull2 r3,-348(fp)
+ mull3 r3,-352(fp),-344(fp)
+ mull2 r0,-352(fp)
+ addl3 -340(fp),-344(fp),r0
+ bicl3 #0,r0,-340(fp)
+ cmpl -340(fp),-344(fp)
+ bgequ noname.129
+ addl2 #65536,-352(fp)
+noname.129:
+ movzwl -338(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-352(fp)
+ bicl3 #-65536,-340(fp),r0
+ ashl #16,r0,-344(fp)
+ addl3 -344(fp),-348(fp),r0
+ bicl3 #0,r0,-348(fp)
+ cmpl -348(fp),-344(fp)
+ bgequ noname.130
+ incl -352(fp)
+noname.130:
+ movl -348(fp),r1
+ movl -352(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.131
+ incl r2
+noname.131:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.132
+ incl r10
+noname.132:
+
+ movzwl 22(r6),r2
+ bicl3 #-65536,4(r7),r3
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,20(r6),-364(fp)
+ bicl3 #-65536,r2,-368(fp)
+ mull3 r0,-364(fp),-356(fp)
+ mull2 r3,-364(fp)
+ mull3 r3,-368(fp),-360(fp)
+ mull2 r0,-368(fp)
+ addl3 -356(fp),-360(fp),r0
+ bicl3 #0,r0,-356(fp)
+ cmpl -356(fp),-360(fp)
+ bgequ noname.133
+ addl2 #65536,-368(fp)
+noname.133:
+ movzwl -354(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-368(fp)
+ bicl3 #-65536,-356(fp),r0
+ ashl #16,r0,-360(fp)
+ addl3 -360(fp),-364(fp),r0
+ bicl3 #0,r0,-364(fp)
+ cmpl -364(fp),-360(fp)
+ bgequ noname.134
+ incl -368(fp)
+noname.134:
+ movl -364(fp),r1
+ movl -368(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.135
+ incl r2
+noname.135:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.136
+ incl r10
+noname.136:
+
+ movzwl 18(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,16(r6),-380(fp)
+ bicl3 #-65536,r2,-384(fp)
+ mull3 r0,-380(fp),-372(fp)
+ mull2 r3,-380(fp)
+ mull3 r3,-384(fp),-376(fp)
+ mull2 r0,-384(fp)
+ addl3 -372(fp),-376(fp),r0
+ bicl3 #0,r0,-372(fp)
+ cmpl -372(fp),-376(fp)
+ bgequ noname.137
+ addl2 #65536,-384(fp)
+noname.137:
+ movzwl -370(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-384(fp)
+ bicl3 #-65536,-372(fp),r0
+ ashl #16,r0,-376(fp)
+ addl3 -376(fp),-380(fp),r0
+ bicl3 #0,r0,-380(fp)
+ cmpl -380(fp),-376(fp)
+ bgequ noname.138
+ incl -384(fp)
+noname.138:
+ movl -380(fp),r1
+ movl -384(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.139
+ incl r2
+noname.139:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.140
+ incl r10
+noname.140:
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,12(r7),r3
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-396(fp)
+ bicl3 #-65536,r2,-400(fp)
+ mull3 r0,-396(fp),-388(fp)
+ mull2 r3,-396(fp)
+ mull3 r3,-400(fp),-392(fp)
+ mull2 r0,-400(fp)
+ addl3 -388(fp),-392(fp),r0
+ bicl3 #0,r0,-388(fp)
+ cmpl -388(fp),-392(fp)
+ bgequ noname.141
+ addl2 #65536,-400(fp)
+noname.141:
+ movzwl -386(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-400(fp)
+ bicl3 #-65536,-388(fp),r0
+ ashl #16,r0,-392(fp)
+ addl3 -392(fp),-396(fp),r0
+ bicl3 #0,r0,-396(fp)
+ cmpl -396(fp),-392(fp)
+ bgequ noname.142
+ incl -400(fp)
+noname.142:
+ movl -396(fp),r1
+ movl -400(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.143
+ incl r2
+noname.143:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.144
+ incl r10
+noname.144:
+
+ movzwl 10(r6),r2
+ bicl3 #-65536,16(r7),r3
+ movzwl 18(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r6),-412(fp)
+ bicl3 #-65536,r2,-416(fp)
+ mull3 r0,-412(fp),-404(fp)
+ mull2 r3,-412(fp)
+ mull3 r3,-416(fp),-408(fp)
+ mull2 r0,-416(fp)
+ addl3 -404(fp),-408(fp),r0
+ bicl3 #0,r0,-404(fp)
+ cmpl -404(fp),-408(fp)
+ bgequ noname.145
+ addl2 #65536,-416(fp)
+noname.145:
+ movzwl -402(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-416(fp)
+ bicl3 #-65536,-404(fp),r0
+ ashl #16,r0,-408(fp)
+ addl3 -408(fp),-412(fp),r0
+ bicl3 #0,r0,-412(fp)
+ cmpl -412(fp),-408(fp)
+ bgequ noname.146
+ incl -416(fp)
+noname.146:
+ movl -412(fp),r1
+ movl -416(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.147
+ incl r2
+noname.147:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.148
+ incl r10
+noname.148:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,20(r7),r3
+ movzwl 22(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-428(fp)
+ bicl3 #-65536,r2,-432(fp)
+ mull3 r0,-428(fp),-420(fp)
+ mull2 r3,-428(fp)
+ mull3 r3,-432(fp),-424(fp)
+ mull2 r0,-432(fp)
+ addl3 -420(fp),-424(fp),r0
+ bicl3 #0,r0,-420(fp)
+ cmpl -420(fp),-424(fp)
+ bgequ noname.149
+ addl2 #65536,-432(fp)
+noname.149:
+ movzwl -418(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-432(fp)
+ bicl3 #-65536,-420(fp),r0
+ ashl #16,r0,-424(fp)
+ addl3 -424(fp),-428(fp),r0
+ bicl3 #0,r0,-428(fp)
+ cmpl -428(fp),-424(fp)
+ bgequ noname.150
+ incl -432(fp)
+noname.150:
+ movl -428(fp),r1
+ movl -432(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.151
+ incl r2
+noname.151:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.152
+ incl r10
+noname.152:
+
+ movzwl 2(r6),r2
+ bicl3 #-65536,24(r7),r3
+ movzwl 26(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,(r6),-444(fp)
+ bicl3 #-65536,r2,-448(fp)
+ mull3 r0,-444(fp),-436(fp)
+ mull2 r3,-444(fp)
+ mull3 r3,-448(fp),-440(fp)
+ mull2 r0,-448(fp)
+ addl3 -436(fp),-440(fp),r0
+ bicl3 #0,r0,-436(fp)
+ cmpl -436(fp),-440(fp)
+ bgequ noname.153
+ addl2 #65536,-448(fp)
+noname.153:
+ movzwl -434(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-448(fp)
+ bicl3 #-65536,-436(fp),r0
+ ashl #16,r0,-440(fp)
+ addl3 -440(fp),-444(fp),r0
+ bicl3 #0,r0,-444(fp)
+ cmpl -444(fp),-440(fp)
+ bgequ noname.154
+ incl -448(fp)
+noname.154:
+ movl -444(fp),r1
+ movl -448(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.155
+ incl r2
+noname.155:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.156
+ incl r10
+noname.156:
+
+ movl r9,24(r11)
+
+ clrl r9
+
+ movzwl 2(r6),r2
+ bicl3 #-65536,28(r7),r3
+ movzwl 30(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,(r6),-460(fp)
+ bicl3 #-65536,r2,-464(fp)
+ mull3 r0,-460(fp),-452(fp)
+ mull2 r3,-460(fp)
+ mull3 r3,-464(fp),-456(fp)
+ mull2 r0,-464(fp)
+ addl3 -452(fp),-456(fp),r0
+ bicl3 #0,r0,-452(fp)
+ cmpl -452(fp),-456(fp)
+ bgequ noname.157
+ addl2 #65536,-464(fp)
+noname.157:
+ movzwl -450(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-464(fp)
+ bicl3 #-65536,-452(fp),r0
+ ashl #16,r0,-456(fp)
+ addl3 -456(fp),-460(fp),r0
+ bicl3 #0,r0,-460(fp)
+ cmpl -460(fp),-456(fp)
+ bgequ noname.158
+ incl -464(fp)
+noname.158:
+ movl -460(fp),r1
+ movl -464(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.159
+ incl r2
+noname.159:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.160
+ incl r9
+noname.160:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,24(r7),r3
+ movzwl 26(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-476(fp)
+ bicl3 #-65536,r2,-480(fp)
+ mull3 r0,-476(fp),-468(fp)
+ mull2 r3,-476(fp)
+ mull3 r3,-480(fp),-472(fp)
+ mull2 r0,-480(fp)
+ addl3 -468(fp),-472(fp),r0
+ bicl3 #0,r0,-468(fp)
+ cmpl -468(fp),-472(fp)
+ bgequ noname.161
+ addl2 #65536,-480(fp)
+noname.161:
+ movzwl -466(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-480(fp)
+ bicl3 #-65536,-468(fp),r0
+ ashl #16,r0,-472(fp)
+ addl3 -472(fp),-476(fp),r0
+ bicl3 #0,r0,-476(fp)
+ cmpl -476(fp),-472(fp)
+ bgequ noname.162
+ incl -480(fp)
+noname.162:
+ movl -476(fp),r1
+ movl -480(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.163
+ incl r2
+noname.163:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.164
+ incl r9
+noname.164:
+
+ movzwl 10(r6),r2
+ bicl3 #-65536,20(r7),r3
+ movzwl 22(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r6),-492(fp)
+ bicl3 #-65536,r2,-496(fp)
+ mull3 r0,-492(fp),-484(fp)
+ mull2 r3,-492(fp)
+ mull3 r3,-496(fp),-488(fp)
+ mull2 r0,-496(fp)
+ addl3 -484(fp),-488(fp),r0
+ bicl3 #0,r0,-484(fp)
+ cmpl -484(fp),-488(fp)
+ bgequ noname.165
+ addl2 #65536,-496(fp)
+noname.165:
+ movzwl -482(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-496(fp)
+ bicl3 #-65536,-484(fp),r0
+ ashl #16,r0,-488(fp)
+ addl3 -488(fp),-492(fp),r0
+ bicl3 #0,r0,-492(fp)
+ cmpl -492(fp),-488(fp)
+ bgequ noname.166
+ incl -496(fp)
+noname.166:
+ movl -492(fp),r1
+ movl -496(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.167
+ incl r2
+noname.167:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.168
+ incl r9
+noname.168:
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,16(r7),r3
+ movzwl 18(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-508(fp)
+ bicl3 #-65536,r2,-512(fp)
+ mull3 r0,-508(fp),-500(fp)
+ mull2 r3,-508(fp)
+ mull3 r3,-512(fp),-504(fp)
+ mull2 r0,-512(fp)
+ addl3 -500(fp),-504(fp),r0
+ bicl3 #0,r0,-500(fp)
+ cmpl -500(fp),-504(fp)
+ bgequ noname.169
+ addl2 #65536,-512(fp)
+noname.169:
+ movzwl -498(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-512(fp)
+ bicl3 #-65536,-500(fp),r0
+ ashl #16,r0,-504(fp)
+ addl3 -504(fp),-508(fp),r0
+ bicl3 #0,r0,-508(fp)
+ cmpl -508(fp),-504(fp)
+ bgequ noname.170
+ incl -512(fp)
+noname.170:
+ movl -508(fp),r1
+ movl -512(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.171
+ incl r2
+noname.171:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.172
+ incl r9
+noname.172:
+
+ movzwl 18(r6),r2
+ bicl3 #-65536,12(r7),r3
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,16(r6),-524(fp)
+ bicl3 #-65536,r2,-528(fp)
+ mull3 r0,-524(fp),-516(fp)
+ mull2 r3,-524(fp)
+ mull3 r3,-528(fp),-520(fp)
+ mull2 r0,-528(fp)
+ addl3 -516(fp),-520(fp),r0
+ bicl3 #0,r0,-516(fp)
+ cmpl -516(fp),-520(fp)
+ bgequ noname.173
+ addl2 #65536,-528(fp)
+noname.173:
+ movzwl -514(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-528(fp)
+ bicl3 #-65536,-516(fp),r0
+ ashl #16,r0,-520(fp)
+ addl3 -520(fp),-524(fp),r0
+ bicl3 #0,r0,-524(fp)
+ cmpl -524(fp),-520(fp)
+ bgequ noname.174
+ incl -528(fp)
+noname.174:
+ movl -524(fp),r1
+ movl -528(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.175
+ incl r2
+noname.175:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.176
+ incl r9
+noname.176:
+
+ movzwl 22(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,20(r6),-540(fp)
+ bicl3 #-65536,r2,-544(fp)
+ mull3 r0,-540(fp),-532(fp)
+ mull2 r3,-540(fp)
+ mull3 r3,-544(fp),-536(fp)
+ mull2 r0,-544(fp)
+ addl3 -532(fp),-536(fp),r0
+ bicl3 #0,r0,-532(fp)
+ cmpl -532(fp),-536(fp)
+ bgequ noname.177
+ addl2 #65536,-544(fp)
+noname.177:
+ movzwl -530(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-544(fp)
+ bicl3 #-65536,-532(fp),r0
+ ashl #16,r0,-536(fp)
+ addl3 -536(fp),-540(fp),r0
+ bicl3 #0,r0,-540(fp)
+ cmpl -540(fp),-536(fp)
+ bgequ noname.178
+ incl -544(fp)
+noname.178:
+ movl -540(fp),r1
+ movl -544(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.179
+ incl r2
+noname.179:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.180
+ incl r9
+noname.180:
+
+ movzwl 26(r6),r2
+ bicl3 #-65536,4(r7),r3
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,24(r6),-556(fp)
+ bicl3 #-65536,r2,-560(fp)
+ mull3 r0,-556(fp),-548(fp)
+ mull2 r3,-556(fp)
+ mull3 r3,-560(fp),-552(fp)
+ mull2 r0,-560(fp)
+ addl3 -548(fp),-552(fp),r0
+ bicl3 #0,r0,-548(fp)
+ cmpl -548(fp),-552(fp)
+ bgequ noname.181
+ addl2 #65536,-560(fp)
+noname.181:
+ movzwl -546(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-560(fp)
+ bicl3 #-65536,-548(fp),r0
+ ashl #16,r0,-552(fp)
+ addl3 -552(fp),-556(fp),r0
+ bicl3 #0,r0,-556(fp)
+ cmpl -556(fp),-552(fp)
+ bgequ noname.182
+ incl -560(fp)
+noname.182:
+ movl -556(fp),r1
+ movl -560(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.183
+ incl r2
+noname.183:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.184
+ incl r9
+noname.184:
+
+ movzwl 30(r6),r2
+ bicl3 #-65536,(r7),r3
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,28(r6),-572(fp)
+ bicl3 #-65536,r2,-576(fp)
+ mull3 r0,-572(fp),-564(fp)
+ mull2 r3,-572(fp)
+ mull3 r3,-576(fp),-568(fp)
+ mull2 r0,-576(fp)
+ addl3 -564(fp),-568(fp),r0
+ bicl3 #0,r0,-564(fp)
+ cmpl -564(fp),-568(fp)
+ bgequ noname.185
+ addl2 #65536,-576(fp)
+noname.185:
+ movzwl -562(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-576(fp)
+ bicl3 #-65536,-564(fp),r0
+ ashl #16,r0,-568(fp)
+ addl3 -568(fp),-572(fp),r0
+ bicl3 #0,r0,-572(fp)
+ cmpl -572(fp),-568(fp)
+ bgequ noname.186
+ incl -576(fp)
+noname.186:
+ movl -572(fp),r1
+ movl -576(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.187
+ incl r2
+noname.187:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.188
+ incl r9
+noname.188:
+
+ movl r8,28(r11)
+
+ clrl r8
+
+ movzwl 30(r6),r2
+ bicl3 #-65536,4(r7),r3
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,28(r6),-588(fp)
+ bicl3 #-65536,r2,-592(fp)
+ mull3 r0,-588(fp),-580(fp)
+ mull2 r3,-588(fp)
+ mull3 r3,-592(fp),-584(fp)
+ mull2 r0,-592(fp)
+ addl3 -580(fp),-584(fp),r0
+ bicl3 #0,r0,-580(fp)
+ cmpl -580(fp),-584(fp)
+ bgequ noname.189
+ addl2 #65536,-592(fp)
+noname.189:
+ movzwl -578(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-592(fp)
+ bicl3 #-65536,-580(fp),r0
+ ashl #16,r0,-584(fp)
+ addl3 -584(fp),-588(fp),r0
+ bicl3 #0,r0,-588(fp)
+ cmpl -588(fp),-584(fp)
+ bgequ noname.190
+ incl -592(fp)
+noname.190:
+ movl -588(fp),r1
+ movl -592(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.191
+ incl r2
+noname.191:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.192
+ incl r8
+noname.192:
+
+ movzwl 26(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,24(r6),-604(fp)
+ bicl3 #-65536,r2,-608(fp)
+ mull3 r0,-604(fp),-596(fp)
+ mull2 r3,-604(fp)
+ mull3 r3,-608(fp),-600(fp)
+ mull2 r0,-608(fp)
+ addl3 -596(fp),-600(fp),r0
+ bicl3 #0,r0,-596(fp)
+ cmpl -596(fp),-600(fp)
+ bgequ noname.193
+ addl2 #65536,-608(fp)
+noname.193:
+ movzwl -594(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-608(fp)
+ bicl3 #-65536,-596(fp),r0
+ ashl #16,r0,-600(fp)
+ addl3 -600(fp),-604(fp),r0
+ bicl3 #0,r0,-604(fp)
+ cmpl -604(fp),-600(fp)
+ bgequ noname.194
+ incl -608(fp)
+noname.194:
+ movl -604(fp),r1
+ movl -608(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.195
+ incl r2
+noname.195:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.196
+ incl r8
+noname.196:
+
+ movzwl 22(r6),r2
+ bicl3 #-65536,12(r7),r3
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,20(r6),-620(fp)
+ bicl3 #-65536,r2,-624(fp)
+ mull3 r0,-620(fp),-612(fp)
+ mull2 r3,-620(fp)
+ mull3 r3,-624(fp),-616(fp)
+ mull2 r0,-624(fp)
+ addl3 -612(fp),-616(fp),r0
+ bicl3 #0,r0,-612(fp)
+ cmpl -612(fp),-616(fp)
+ bgequ noname.197
+ addl2 #65536,-624(fp)
+noname.197:
+ movzwl -610(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-624(fp)
+ bicl3 #-65536,-612(fp),r0
+ ashl #16,r0,-616(fp)
+ addl3 -616(fp),-620(fp),r0
+ bicl3 #0,r0,-620(fp)
+ cmpl -620(fp),-616(fp)
+ bgequ noname.198
+ incl -624(fp)
+noname.198:
+ movl -620(fp),r1
+ movl -624(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.199
+ incl r2
+noname.199:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.200
+ incl r8
+noname.200:
+
+ movzwl 18(r6),r2
+ bicl3 #-65536,16(r7),r3
+ movzwl 18(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,16(r6),-636(fp)
+ bicl3 #-65536,r2,-640(fp)
+ mull3 r0,-636(fp),-628(fp)
+ mull2 r3,-636(fp)
+ mull3 r3,-640(fp),-632(fp)
+ mull2 r0,-640(fp)
+ addl3 -628(fp),-632(fp),r0
+ bicl3 #0,r0,-628(fp)
+ cmpl -628(fp),-632(fp)
+ bgequ noname.201
+ addl2 #65536,-640(fp)
+noname.201:
+ movzwl -626(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-640(fp)
+ bicl3 #-65536,-628(fp),r0
+ ashl #16,r0,-632(fp)
+ addl3 -632(fp),-636(fp),r0
+ bicl3 #0,r0,-636(fp)
+ cmpl -636(fp),-632(fp)
+ bgequ noname.202
+ incl -640(fp)
+noname.202:
+ movl -636(fp),r1
+ movl -640(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.203
+ incl r2
+noname.203:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.204
+ incl r8
+noname.204:
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,20(r7),r3
+ movzwl 22(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-652(fp)
+ bicl3 #-65536,r2,-656(fp)
+ mull3 r0,-652(fp),-644(fp)
+ mull2 r3,-652(fp)
+ mull3 r3,-656(fp),-648(fp)
+ mull2 r0,-656(fp)
+ addl3 -644(fp),-648(fp),r0
+ bicl3 #0,r0,-644(fp)
+ cmpl -644(fp),-648(fp)
+ bgequ noname.205
+ addl2 #65536,-656(fp)
+noname.205:
+ movzwl -642(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-656(fp)
+ bicl3 #-65536,-644(fp),r0
+ ashl #16,r0,-648(fp)
+ addl3 -648(fp),-652(fp),r0
+ bicl3 #0,r0,-652(fp)
+ cmpl -652(fp),-648(fp)
+ bgequ noname.206
+ incl -656(fp)
+noname.206:
+ movl -652(fp),r1
+ movl -656(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.207
+ incl r2
+noname.207:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.208
+ incl r8
+noname.208:
+
+ movzwl 10(r6),r2
+ bicl3 #-65536,24(r7),r3
+ movzwl 26(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r6),-668(fp)
+ bicl3 #-65536,r2,-672(fp)
+ mull3 r0,-668(fp),-660(fp)
+ mull2 r3,-668(fp)
+ mull3 r3,-672(fp),-664(fp)
+ mull2 r0,-672(fp)
+ addl3 -660(fp),-664(fp),r0
+ bicl3 #0,r0,-660(fp)
+ cmpl -660(fp),-664(fp)
+ bgequ noname.209
+ addl2 #65536,-672(fp)
+noname.209:
+ movzwl -658(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-672(fp)
+ bicl3 #-65536,-660(fp),r0
+ ashl #16,r0,-664(fp)
+ addl3 -664(fp),-668(fp),r0
+ bicl3 #0,r0,-668(fp)
+ cmpl -668(fp),-664(fp)
+ bgequ noname.210
+ incl -672(fp)
+noname.210:
+ movl -668(fp),r1
+ movl -672(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.211
+ incl r2
+noname.211:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.212
+ incl r8
+noname.212:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,28(r7),r3
+ movzwl 30(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-684(fp)
+ bicl3 #-65536,r2,-688(fp)
+ mull3 r0,-684(fp),-676(fp)
+ mull2 r3,-684(fp)
+ mull3 r3,-688(fp),-680(fp)
+ mull2 r0,-688(fp)
+ addl3 -676(fp),-680(fp),r0
+ bicl3 #0,r0,-676(fp)
+ cmpl -676(fp),-680(fp)
+ bgequ noname.213
+ addl2 #65536,-688(fp)
+noname.213:
+ movzwl -674(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-688(fp)
+ bicl3 #-65536,-676(fp),r0
+ ashl #16,r0,-680(fp)
+ addl3 -680(fp),-684(fp),r0
+ bicl3 #0,r0,-684(fp)
+ cmpl -684(fp),-680(fp)
+ bgequ noname.214
+ incl -688(fp)
+noname.214:
+ movl -684(fp),r1
+ movl -688(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.215
+ incl r2
+noname.215:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.216
+ incl r8
+noname.216:
+
+ movl r10,32(r11)
+
+ clrl r10
+
+ movzwl 10(r6),r2
+ bicl3 #-65536,28(r7),r3
+ movzwl 30(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r6),-700(fp)
+ bicl3 #-65536,r2,-704(fp)
+ mull3 r0,-700(fp),-692(fp)
+ mull2 r3,-700(fp)
+ mull3 r3,-704(fp),-696(fp)
+ mull2 r0,-704(fp)
+ addl3 -692(fp),-696(fp),r0
+ bicl3 #0,r0,-692(fp)
+ cmpl -692(fp),-696(fp)
+ bgequ noname.217
+ addl2 #65536,-704(fp)
+noname.217:
+ movzwl -690(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-704(fp)
+ bicl3 #-65536,-692(fp),r0
+ ashl #16,r0,-696(fp)
+ addl3 -696(fp),-700(fp),r0
+ bicl3 #0,r0,-700(fp)
+ cmpl -700(fp),-696(fp)
+ bgequ noname.218
+ incl -704(fp)
+noname.218:
+ movl -700(fp),r1
+ movl -704(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.219
+ incl r2
+noname.219:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.220
+ incl r10
+noname.220:
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,24(r7),r3
+ movzwl 26(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-716(fp)
+ bicl3 #-65536,r2,-720(fp)
+ mull3 r0,-716(fp),-708(fp)
+ mull2 r3,-716(fp)
+ mull3 r3,-720(fp),-712(fp)
+ mull2 r0,-720(fp)
+ addl3 -708(fp),-712(fp),r0
+ bicl3 #0,r0,-708(fp)
+ cmpl -708(fp),-712(fp)
+ bgequ noname.221
+ addl2 #65536,-720(fp)
+noname.221:
+ movzwl -706(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-720(fp)
+ bicl3 #-65536,-708(fp),r0
+ ashl #16,r0,-712(fp)
+ addl3 -712(fp),-716(fp),r0
+ bicl3 #0,r0,-716(fp)
+ cmpl -716(fp),-712(fp)
+ bgequ noname.222
+ incl -720(fp)
+noname.222:
+ movl -716(fp),r1
+ movl -720(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.223
+ incl r2
+noname.223:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.224
+ incl r10
+noname.224:
+
+ movzwl 18(r6),r2
+ bicl3 #-65536,20(r7),r3
+ movzwl 22(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,16(r6),-732(fp)
+ bicl3 #-65536,r2,-736(fp)
+ mull3 r0,-732(fp),-724(fp)
+ mull2 r3,-732(fp)
+ mull3 r3,-736(fp),-728(fp)
+ mull2 r0,-736(fp)
+ addl3 -724(fp),-728(fp),r0
+ bicl3 #0,r0,-724(fp)
+ cmpl -724(fp),-728(fp)
+ bgequ noname.225
+ addl2 #65536,-736(fp)
+noname.225:
+ movzwl -722(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-736(fp)
+ bicl3 #-65536,-724(fp),r0
+ ashl #16,r0,-728(fp)
+ addl3 -728(fp),-732(fp),r0
+ bicl3 #0,r0,-732(fp)
+ cmpl -732(fp),-728(fp)
+ bgequ noname.226
+ incl -736(fp)
+noname.226:
+ movl -732(fp),r1
+ movl -736(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.227
+ incl r2
+noname.227:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.228
+ incl r10
+noname.228:
+
+ movzwl 22(r6),r2
+ bicl3 #-65536,16(r7),r3
+ movzwl 18(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,20(r6),-748(fp)
+ bicl3 #-65536,r2,-752(fp)
+ mull3 r0,-748(fp),-740(fp)
+ mull2 r3,-748(fp)
+ mull3 r3,-752(fp),-744(fp)
+ mull2 r0,-752(fp)
+ addl3 -740(fp),-744(fp),r0
+ bicl3 #0,r0,-740(fp)
+ cmpl -740(fp),-744(fp)
+ bgequ noname.229
+ addl2 #65536,-752(fp)
+noname.229:
+ movzwl -738(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-752(fp)
+ bicl3 #-65536,-740(fp),r0
+ ashl #16,r0,-744(fp)
+ addl3 -744(fp),-748(fp),r0
+ bicl3 #0,r0,-748(fp)
+ cmpl -748(fp),-744(fp)
+ bgequ noname.230
+ incl -752(fp)
+noname.230:
+ movl -748(fp),r1
+ movl -752(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.231
+ incl r2
+noname.231:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.232
+ incl r10
+noname.232:
+
+ movzwl 26(r6),r2
+ bicl3 #-65536,12(r7),r3
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,24(r6),-764(fp)
+ bicl3 #-65536,r2,-768(fp)
+ mull3 r0,-764(fp),-756(fp)
+ mull2 r3,-764(fp)
+ mull3 r3,-768(fp),-760(fp)
+ mull2 r0,-768(fp)
+ addl3 -756(fp),-760(fp),r0
+ bicl3 #0,r0,-756(fp)
+ cmpl -756(fp),-760(fp)
+ bgequ noname.233
+ addl2 #65536,-768(fp)
+noname.233:
+ movzwl -754(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-768(fp)
+ bicl3 #-65536,-756(fp),r0
+ ashl #16,r0,-760(fp)
+ addl3 -760(fp),-764(fp),r0
+ bicl3 #0,r0,-764(fp)
+ cmpl -764(fp),-760(fp)
+ bgequ noname.234
+ incl -768(fp)
+noname.234:
+ movl -764(fp),r1
+ movl -768(fp),r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.235
+ incl r2
+noname.235:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.236
+ incl r10
+noname.236:
+
+ bicl3 #-65536,28(r6),r3
+ movzwl 30(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,8(r7),r2
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-772(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-776(fp)
+ mull2 r0,r4
+ addl3 -772(fp),-776(fp),r0
+ bicl3 #0,r0,-772(fp)
+ cmpl -772(fp),-776(fp)
+ bgequ noname.237
+ addl2 #65536,r4
+noname.237:
+ movzwl -770(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-772(fp),r0
+ ashl #16,r0,-776(fp)
+ addl2 -776(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-776(fp)
+ bgequ noname.238
+ incl r4
+noname.238:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.239
+ incl r2
+noname.239:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.240
+ incl r10
+noname.240:
+
+ movl r9,36(r11)
+
+ clrl r9
+
+ bicl3 #-65536,28(r6),r3
+ movzwl 30(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,12(r7),r2
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-780(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-784(fp)
+ mull2 r0,r4
+ addl3 -780(fp),-784(fp),r0
+ bicl3 #0,r0,-780(fp)
+ cmpl -780(fp),-784(fp)
+ bgequ noname.241
+ addl2 #65536,r4
+noname.241:
+ movzwl -778(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-780(fp),r0
+ ashl #16,r0,-784(fp)
+ addl2 -784(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-784(fp)
+ bgequ noname.242
+ incl r4
+noname.242:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.243
+ incl r2
+noname.243:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.244
+ incl r9
+noname.244:
+
+ bicl3 #-65536,24(r6),r3
+ movzwl 26(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,16(r7),r2
+ movzwl 18(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-788(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-792(fp)
+ mull2 r0,r4
+ addl3 -788(fp),-792(fp),r0
+ bicl3 #0,r0,-788(fp)
+ cmpl -788(fp),-792(fp)
+ bgequ noname.245
+ addl2 #65536,r4
+noname.245:
+ movzwl -786(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-788(fp),r0
+ ashl #16,r0,-792(fp)
+ addl2 -792(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-792(fp)
+ bgequ noname.246
+ incl r4
+noname.246:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.247
+ incl r2
+noname.247:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.248
+ incl r9
+noname.248:
+
+ bicl3 #-65536,20(r6),r3
+ movzwl 22(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,20(r7),r2
+ movzwl 22(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-796(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-800(fp)
+ mull2 r0,r4
+ addl3 -796(fp),-800(fp),r0
+ bicl3 #0,r0,-796(fp)
+ cmpl -796(fp),-800(fp)
+ bgequ noname.249
+ addl2 #65536,r4
+noname.249:
+ movzwl -794(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-796(fp),r0
+ ashl #16,r0,-800(fp)
+ addl2 -800(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-800(fp)
+ bgequ noname.250
+ incl r4
+noname.250:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.251
+ incl r2
+noname.251:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.252
+ incl r9
+noname.252:
+
+ bicl3 #-65536,16(r6),r3
+ movzwl 18(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,24(r7),r2
+ movzwl 26(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-804(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-808(fp)
+ mull2 r0,r4
+ addl3 -804(fp),-808(fp),r0
+ bicl3 #0,r0,-804(fp)
+ cmpl -804(fp),-808(fp)
+ bgequ noname.253
+ addl2 #65536,r4
+noname.253:
+ movzwl -802(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-804(fp),r0
+ ashl #16,r0,-808(fp)
+ addl2 -808(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-808(fp)
+ bgequ noname.254
+ incl r4
+noname.254:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.255
+ incl r2
+noname.255:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.256
+ incl r9
+noname.256:
+
+ bicl3 #-65536,12(r6),r3
+ movzwl 14(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,28(r7),r2
+ movzwl 30(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-812(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-816(fp)
+ mull2 r0,r4
+ addl3 -812(fp),-816(fp),r0
+ bicl3 #0,r0,-812(fp)
+ cmpl -812(fp),-816(fp)
+ bgequ noname.257
+ addl2 #65536,r4
+noname.257:
+ movzwl -810(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-812(fp),r0
+ ashl #16,r0,-816(fp)
+ addl2 -816(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-816(fp)
+ bgequ noname.258
+ incl r4
+noname.258:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.259
+ incl r2
+noname.259:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.260
+ incl r9
+noname.260:
+
+ movl r8,40(r11)
+
+ clrl r8
+
+ bicl3 #-65536,16(r6),r3
+ movzwl 18(r6),r2
+ bicl3 #-65536,28(r7),r1
+ movzwl 30(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r4
+ bicl3 #-65536,r2,-828(fp)
+ mull3 r0,r4,-820(fp)
+ mull2 r1,r4
+ mull3 r1,-828(fp),-824(fp)
+ mull2 r0,-828(fp)
+ addl3 -820(fp),-824(fp),r0
+ bicl3 #0,r0,-820(fp)
+ cmpl -820(fp),-824(fp)
+ bgequ noname.261
+ addl2 #65536,-828(fp)
+noname.261:
+ movzwl -818(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-828(fp)
+ bicl3 #-65536,-820(fp),r0
+ ashl #16,r0,-824(fp)
+ addl2 -824(fp),r4
+ bicl2 #0,r4
+ cmpl r4,-824(fp)
+ bgequ noname.262
+ incl -828(fp)
+noname.262:
+ movl r4,r1
+ movl -828(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.263
+ incl r2
+noname.263:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.264
+ incl r8
+noname.264:
+
+ movzwl 22(r6),r2
+ bicl3 #-65536,24(r7),r3
+ movzwl 26(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,20(r6),-840(fp)
+ bicl3 #-65536,r2,-844(fp)
+ mull3 r0,-840(fp),-832(fp)
+ mull2 r3,-840(fp)
+ mull3 r3,-844(fp),-836(fp)
+ mull2 r0,-844(fp)
+ addl3 -832(fp),-836(fp),r0
+ bicl3 #0,r0,-832(fp)
+ cmpl -832(fp),-836(fp)
+ bgequ noname.265
+ addl2 #65536,-844(fp)
+noname.265:
+ movzwl -830(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-844(fp)
+ bicl3 #-65536,-832(fp),r0
+ ashl #16,r0,-836(fp)
+ addl3 -836(fp),-840(fp),r0
+ bicl3 #0,r0,-840(fp)
+ cmpl -840(fp),-836(fp)
+ bgequ noname.266
+ incl -844(fp)
+noname.266:
+ movl -840(fp),r1
+ movl -844(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.267
+ incl r2
+noname.267:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.268
+ incl r8
+noname.268:
+
+ bicl3 #-65536,24(r6),r3
+ movzwl 26(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,20(r7),r2
+ movzwl 22(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-848(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-852(fp)
+ mull2 r0,r4
+ addl3 -848(fp),-852(fp),r0
+ bicl3 #0,r0,-848(fp)
+ cmpl -848(fp),-852(fp)
+ bgequ noname.269
+ addl2 #65536,r4
+noname.269:
+ movzwl -846(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-848(fp),r0
+ ashl #16,r0,-852(fp)
+ addl2 -852(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-852(fp)
+ bgequ noname.270
+ incl r4
+noname.270:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.271
+ incl r2
+noname.271:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.272
+ incl r8
+noname.272:
+
+ bicl3 #-65536,28(r6),r3
+ movzwl 30(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,16(r7),r2
+ movzwl 18(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-856(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-860(fp)
+ mull2 r0,r4
+ addl3 -856(fp),-860(fp),r0
+ bicl3 #0,r0,-856(fp)
+ cmpl -856(fp),-860(fp)
+ bgequ noname.273
+ addl2 #65536,r4
+noname.273:
+ movzwl -854(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-856(fp),r0
+ ashl #16,r0,-860(fp)
+ addl2 -860(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-860(fp)
+ bgequ noname.274
+ incl r4
+noname.274:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.275
+ incl r2
+noname.275:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.276
+ incl r8
+noname.276:
+
+ movl r10,44(r11)
+
+ clrl r10
+
+ bicl3 #-65536,28(r6),r3
+ movzwl 30(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,20(r7),r2
+ movzwl 22(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-864(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-868(fp)
+ mull2 r0,r4
+ addl3 -864(fp),-868(fp),r0
+ bicl3 #0,r0,-864(fp)
+ cmpl -864(fp),-868(fp)
+ bgequ noname.277
+ addl2 #65536,r4
+noname.277:
+ movzwl -862(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-864(fp),r0
+ ashl #16,r0,-868(fp)
+ addl2 -868(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-868(fp)
+ bgequ noname.278
+ incl r4
+noname.278:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.279
+ incl r2
+noname.279:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.280
+ incl r10
+noname.280:
+
+ bicl3 #-65536,24(r6),r3
+ movzwl 26(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,24(r7),r2
+ movzwl 26(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-872(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-876(fp)
+ mull2 r0,r4
+ addl3 -872(fp),-876(fp),r0
+ bicl3 #0,r0,-872(fp)
+ cmpl -872(fp),-876(fp)
+ bgequ noname.281
+ addl2 #65536,r4
+noname.281:
+ movzwl -870(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-872(fp),r0
+ ashl #16,r0,-876(fp)
+ addl2 -876(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-876(fp)
+ bgequ noname.282
+ incl r4
+noname.282:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.283
+ incl r2
+noname.283:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.284
+ incl r10
+noname.284:
+
+ bicl3 #-65536,20(r6),r3
+ movzwl 22(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,28(r7),r2
+ movzwl 30(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-880(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-884(fp)
+ mull2 r0,r4
+ addl3 -880(fp),-884(fp),r0
+ bicl3 #0,r0,-880(fp)
+ cmpl -880(fp),-884(fp)
+ bgequ noname.285
+ addl2 #65536,r4
+noname.285:
+ movzwl -878(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-880(fp),r0
+ ashl #16,r0,-884(fp)
+ addl2 -884(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-884(fp)
+ bgequ noname.286
+ incl r4
+noname.286:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.287
+ incl r2
+noname.287:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.288
+ incl r10
+noname.288:
+
+ movl r9,48(r11)
+
+ clrl r9
+
+ bicl3 #-65536,24(r6),r3
+ movzwl 26(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,28(r7),r2
+ movzwl 30(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-888(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-892(fp)
+ mull2 r0,r4
+ addl3 -888(fp),-892(fp),r0
+ bicl3 #0,r0,-888(fp)
+ cmpl -888(fp),-892(fp)
+ bgequ noname.289
+ addl2 #65536,r4
+noname.289:
+ movzwl -886(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-888(fp),r0
+ ashl #16,r0,-892(fp)
+ addl2 -892(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-892(fp)
+ bgequ noname.290
+ incl r4
+noname.290:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.291
+ incl r2
+noname.291:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.292
+ incl r9
+noname.292:
+
+ movzwl 30(r6),r2
+ bicl3 #-65536,24(r7),r3
+ movzwl 26(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,28(r6),-904(fp)
+ bicl3 #-65536,r2,-908(fp)
+ mull3 r0,-904(fp),-896(fp)
+ mull2 r3,-904(fp)
+ mull3 r3,-908(fp),-900(fp)
+ mull2 r0,-908(fp)
+ addl3 -896(fp),-900(fp),r0
+ bicl3 #0,r0,-896(fp)
+ cmpl -896(fp),-900(fp)
+ bgequ noname.293
+ addl2 #65536,-908(fp)
+noname.293:
+ movzwl -894(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-908(fp)
+ bicl3 #-65536,-896(fp),r0
+ ashl #16,r0,-900(fp)
+ addl3 -900(fp),-904(fp),r0
+ bicl3 #0,r0,-904(fp)
+ cmpl -904(fp),-900(fp)
+ bgequ noname.294
+ incl -908(fp)
+noname.294:
+ movl -904(fp),r1
+ movl -908(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.295
+ incl r2
+noname.295:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.296
+ incl r9
+noname.296:
+
+ movl r8,52(r11)
+
+ clrl r8
+
+ movzwl 30(r6),r2
+ bicl3 #-65536,28(r7),r3
+ movzwl 30(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,28(r6),-920(fp)
+ bicl3 #-65536,r2,-924(fp)
+ mull3 r0,-920(fp),-912(fp)
+ mull2 r3,-920(fp)
+ mull3 r3,-924(fp),-916(fp)
+ mull2 r0,-924(fp)
+ addl3 -912(fp),-916(fp),r0
+ bicl3 #0,r0,-912(fp)
+ cmpl -912(fp),-916(fp)
+ bgequ noname.297
+ addl2 #65536,-924(fp)
+noname.297:
+ movzwl -910(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-924(fp)
+ bicl3 #-65536,-912(fp),r0
+ ashl #16,r0,-916(fp)
+ addl3 -916(fp),-920(fp),r0
+ bicl3 #0,r0,-920(fp)
+ cmpl -920(fp),-916(fp)
+ bgequ noname.298
+ incl -924(fp)
+noname.298:
+ movl -920(fp),r1
+ movl -924(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.299
+ incl r2
+noname.299:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.300
+ incl r8
+noname.300:
+
+ movl r10,56(r11)
+
+ movl r9,60(r11)
+
+ ret
+
+
+
+;r=4 ;(AP)
+;a=8 ;(AP)
+;b=12 ;(AP)
+;n=16 ;(AP) n by value (input)
+
+ .psect code,nowrt
+
+.entry BN_MUL_COMBA4,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10,r11>
+ movab -156(sp),sp
+
+ clrq r9
+
+ clrl r8
+
+ movl 8(ap),r6
+ bicl3 #-65536,(r6),r3
+ movzwl 2(r6),r2
+ bicl2 #-65536,r2
+ movl 12(ap),r7
+ bicl3 #-65536,(r7),r1
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r2,r4
+ mull3 r0,r5,-4(fp)
+ mull2 r1,r5
+ mull3 r1,r4,-8(fp)
+ mull2 r0,r4
+ addl3 -4(fp),-8(fp),r0
+ bicl3 #0,r0,-4(fp)
+ cmpl -4(fp),-8(fp)
+ bgequ noname.303
+ addl2 #65536,r4
+noname.303:
+ movzwl -2(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-4(fp),r0
+ ashl #16,r0,-8(fp)
+ addl2 -8(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-8(fp)
+ bgequ noname.304
+ incl r4
+noname.304:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.305
+ incl r2
+noname.305:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.306
+ incl r8
+noname.306:
+
+ movl 4(ap),r11
+ movl r10,(r11)
+
+ clrl r10
+
+ bicl3 #-65536,(r6),r3
+ movzwl 2(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,4(r7),r2
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-12(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-16(fp)
+ mull2 r0,r4
+ addl3 -12(fp),-16(fp),r0
+ bicl3 #0,r0,-12(fp)
+ cmpl -12(fp),-16(fp)
+ bgequ noname.307
+ addl2 #65536,r4
+noname.307:
+ movzwl -10(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-12(fp),r0
+ ashl #16,r0,-16(fp)
+ addl2 -16(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-16(fp)
+ bgequ noname.308
+ incl r4
+noname.308:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.309
+ incl r2
+noname.309:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.310
+ incl r10
+noname.310:
+
+ bicl3 #-65536,4(r6),r3
+ movzwl 6(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,(r7),r2
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-20(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-24(fp)
+ mull2 r0,r4
+ addl3 -20(fp),-24(fp),r0
+ bicl3 #0,r0,-20(fp)
+ cmpl -20(fp),-24(fp)
+ bgequ noname.311
+ addl2 #65536,r4
+noname.311:
+ movzwl -18(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-20(fp),r0
+ ashl #16,r0,-24(fp)
+ addl2 -24(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-24(fp)
+ bgequ noname.312
+ incl r4
+noname.312:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.313
+ incl r2
+noname.313:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.314
+ incl r10
+noname.314:
+
+ movl r9,4(r11)
+
+ clrl r9
+
+ bicl3 #-65536,8(r6),r3
+ movzwl 10(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,(r7),r2
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-28(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-32(fp)
+ mull2 r0,r4
+ addl3 -28(fp),-32(fp),r0
+ bicl3 #0,r0,-28(fp)
+ cmpl -28(fp),-32(fp)
+ bgequ noname.315
+ addl2 #65536,r4
+noname.315:
+ movzwl -26(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-28(fp),r0
+ ashl #16,r0,-32(fp)
+ addl2 -32(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-32(fp)
+ bgequ noname.316
+ incl r4
+noname.316:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.317
+ incl r2
+noname.317:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.318
+ incl r9
+noname.318:
+
+ bicl3 #-65536,4(r6),r3
+ movzwl 6(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,4(r7),r2
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-36(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-40(fp)
+ mull2 r0,r4
+ addl3 -36(fp),-40(fp),r0
+ bicl3 #0,r0,-36(fp)
+ cmpl -36(fp),-40(fp)
+ bgequ noname.319
+ addl2 #65536,r4
+noname.319:
+ movzwl -34(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-36(fp),r0
+ ashl #16,r0,-40(fp)
+ addl2 -40(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-40(fp)
+ bgequ noname.320
+ incl r4
+noname.320:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.321
+ incl r2
+noname.321:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.322
+ incl r9
+noname.322:
+
+ bicl3 #-65536,(r6),r3
+ movzwl 2(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,8(r7),r2
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-44(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-48(fp)
+ mull2 r0,r4
+ addl3 -44(fp),-48(fp),r0
+ bicl3 #0,r0,-44(fp)
+ cmpl -44(fp),-48(fp)
+ bgequ noname.323
+ addl2 #65536,r4
+noname.323:
+ movzwl -42(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-44(fp),r0
+ ashl #16,r0,-48(fp)
+ addl2 -48(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-48(fp)
+ bgequ noname.324
+ incl r4
+noname.324:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.325
+ incl r2
+noname.325:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.326
+ incl r9
+noname.326:
+
+ movl r8,8(r11)
+
+ clrl r8
+
+ bicl3 #-65536,(r6),r3
+ movzwl 2(r6),r2
+ bicl3 #-65536,12(r7),r1
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r4
+ bicl3 #-65536,r2,-60(fp)
+ mull3 r0,r4,-52(fp)
+ mull2 r1,r4
+ mull3 r1,-60(fp),-56(fp)
+ mull2 r0,-60(fp)
+ addl3 -52(fp),-56(fp),r0
+ bicl3 #0,r0,-52(fp)
+ cmpl -52(fp),-56(fp)
+ bgequ noname.327
+ addl2 #65536,-60(fp)
+noname.327:
+ movzwl -50(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-60(fp)
+ bicl3 #-65536,-52(fp),r0
+ ashl #16,r0,-56(fp)
+ addl2 -56(fp),r4
+ bicl2 #0,r4
+ cmpl r4,-56(fp)
+ bgequ noname.328
+ incl -60(fp)
+noname.328:
+ movl r4,r1
+ movl -60(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.329
+ incl r2
+noname.329:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.330
+ incl r8
+noname.330:
+
+ movzwl 6(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r6),-72(fp)
+ bicl3 #-65536,r2,-76(fp)
+ mull3 r0,-72(fp),-64(fp)
+ mull2 r3,-72(fp)
+ mull3 r3,-76(fp),-68(fp)
+ mull2 r0,-76(fp)
+ addl3 -64(fp),-68(fp),r0
+ bicl3 #0,r0,-64(fp)
+ cmpl -64(fp),-68(fp)
+ bgequ noname.331
+ addl2 #65536,-76(fp)
+noname.331:
+ movzwl -62(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-76(fp)
+ bicl3 #-65536,-64(fp),r0
+ ashl #16,r0,-68(fp)
+ addl3 -68(fp),-72(fp),r0
+ bicl3 #0,r0,-72(fp)
+ cmpl -72(fp),-68(fp)
+ bgequ noname.332
+ incl -76(fp)
+noname.332:
+ movl -72(fp),r1
+ movl -76(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.333
+ incl r2
+noname.333:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.334
+ incl r8
+noname.334:
+
+ bicl3 #-65536,8(r6),r3
+ movzwl 10(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,4(r7),r2
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-80(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-84(fp)
+ mull2 r0,r4
+ addl3 -80(fp),-84(fp),r0
+ bicl3 #0,r0,-80(fp)
+ cmpl -80(fp),-84(fp)
+ bgequ noname.335
+ addl2 #65536,r4
+noname.335:
+ movzwl -78(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-80(fp),r0
+ ashl #16,r0,-84(fp)
+ addl2 -84(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-84(fp)
+ bgequ noname.336
+ incl r4
+noname.336:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.337
+ incl r2
+noname.337:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.338
+ incl r8
+noname.338:
+
+ bicl3 #-65536,12(r6),r3
+ movzwl 14(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,(r7),r2
+ movzwl 2(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-88(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-92(fp)
+ mull2 r0,r4
+ addl3 -88(fp),-92(fp),r0
+ bicl3 #0,r0,-88(fp)
+ cmpl -88(fp),-92(fp)
+ bgequ noname.339
+ addl2 #65536,r4
+noname.339:
+ movzwl -86(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-88(fp),r0
+ ashl #16,r0,-92(fp)
+ addl2 -92(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-92(fp)
+ bgequ noname.340
+ incl r4
+noname.340:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.341
+ incl r2
+noname.341:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.342
+ incl r8
+noname.342:
+
+ movl r10,12(r11)
+
+ clrl r10
+
+ bicl3 #-65536,12(r6),r3
+ movzwl 14(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,4(r7),r2
+ movzwl 6(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-96(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-100(fp)
+ mull2 r0,r4
+ addl3 -96(fp),-100(fp),r0
+ bicl3 #0,r0,-96(fp)
+ cmpl -96(fp),-100(fp)
+ bgequ noname.343
+ addl2 #65536,r4
+noname.343:
+ movzwl -94(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-96(fp),r0
+ ashl #16,r0,-100(fp)
+ addl2 -100(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-100(fp)
+ bgequ noname.344
+ incl r4
+noname.344:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.345
+ incl r2
+noname.345:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.346
+ incl r10
+noname.346:
+
+ bicl3 #-65536,8(r6),r3
+ movzwl 10(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,8(r7),r2
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-104(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-108(fp)
+ mull2 r0,r4
+ addl3 -104(fp),-108(fp),r0
+ bicl3 #0,r0,-104(fp)
+ cmpl -104(fp),-108(fp)
+ bgequ noname.347
+ addl2 #65536,r4
+noname.347:
+ movzwl -102(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-104(fp),r0
+ ashl #16,r0,-108(fp)
+ addl2 -108(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-108(fp)
+ bgequ noname.348
+ incl r4
+noname.348:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.349
+ incl r2
+noname.349:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.350
+ incl r10
+noname.350:
+
+ bicl3 #-65536,4(r6),r3
+ movzwl 6(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,12(r7),r2
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-112(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-116(fp)
+ mull2 r0,r4
+ addl3 -112(fp),-116(fp),r0
+ bicl3 #0,r0,-112(fp)
+ cmpl -112(fp),-116(fp)
+ bgequ noname.351
+ addl2 #65536,r4
+noname.351:
+ movzwl -110(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-112(fp),r0
+ ashl #16,r0,-116(fp)
+ addl2 -116(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-116(fp)
+ bgequ noname.352
+ incl r4
+noname.352:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.353
+ incl r2
+noname.353:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.354
+ incl r10
+noname.354:
+
+ movl r9,16(r11)
+
+ clrl r9
+
+ bicl3 #-65536,8(r6),r3
+ movzwl 10(r6),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,12(r7),r2
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-120(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-124(fp)
+ mull2 r0,r4
+ addl3 -120(fp),-124(fp),r0
+ bicl3 #0,r0,-120(fp)
+ cmpl -120(fp),-124(fp)
+ bgequ noname.355
+ addl2 #65536,r4
+noname.355:
+ movzwl -118(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-120(fp),r0
+ ashl #16,r0,-124(fp)
+ addl2 -124(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-124(fp)
+ bgequ noname.356
+ incl r4
+noname.356:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.357
+ incl r2
+noname.357:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.358
+ incl r9
+noname.358:
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,8(r7),r3
+ movzwl 10(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-136(fp)
+ bicl3 #-65536,r2,-140(fp)
+ mull3 r0,-136(fp),-128(fp)
+ mull2 r3,-136(fp)
+ mull3 r3,-140(fp),-132(fp)
+ mull2 r0,-140(fp)
+ addl3 -128(fp),-132(fp),r0
+ bicl3 #0,r0,-128(fp)
+ cmpl -128(fp),-132(fp)
+ bgequ noname.359
+ addl2 #65536,-140(fp)
+noname.359:
+ movzwl -126(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-140(fp)
+ bicl3 #-65536,-128(fp),r0
+ ashl #16,r0,-132(fp)
+ addl3 -132(fp),-136(fp),r0
+ bicl3 #0,r0,-136(fp)
+ cmpl -136(fp),-132(fp)
+ bgequ noname.360
+ incl -140(fp)
+noname.360:
+ movl -136(fp),r1
+ movl -140(fp),r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.361
+ incl r2
+noname.361:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.362
+ incl r9
+noname.362:
+
+ movl r8,20(r11)
+
+ clrl r8
+
+ movzwl 14(r6),r2
+ bicl3 #-65536,12(r7),r3
+ movzwl 14(r7),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r6),-152(fp)
+ bicl3 #-65536,r2,-156(fp)
+ mull3 r0,-152(fp),-144(fp)
+ mull2 r3,-152(fp)
+ mull3 r3,-156(fp),-148(fp)
+ mull2 r0,-156(fp)
+ addl3 -144(fp),-148(fp),r0
+ bicl3 #0,r0,-144(fp)
+ cmpl -144(fp),-148(fp)
+ bgequ noname.363
+ addl2 #65536,-156(fp)
+noname.363:
+ movzwl -142(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-156(fp)
+ bicl3 #-65536,-144(fp),r0
+ ashl #16,r0,-148(fp)
+ addl3 -148(fp),-152(fp),r0
+ bicl3 #0,r0,-152(fp)
+ cmpl -152(fp),-148(fp)
+ bgequ noname.364
+ incl -156(fp)
+noname.364:
+ movl -152(fp),r1
+ movl -156(fp),r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.365
+ incl r2
+noname.365:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.366
+ incl r8
+noname.366:
+
+ movl r10,24(r11)
+
+ movl r9,28(r11)
+
+ ret
+
+
+
+;r=4 ;(AP)
+;a=8 ;(AP)
+;b=12 ;(AP)
+;n=16 ;(AP) n by value (input)
+
+ .psect code,nowrt
+
+.entry BN_SQR_COMBA8,^m<r2,r3,r4,r5,r6,r7,r8,r9>
+ movab -444(sp),sp
+
+ clrq r8
+
+ clrl r7
+
+ movl 8(ap),r4
+ movl (r4),r3
+ bicl3 #-65536,r3,-4(fp)
+ extzv #16,#16,r3,r0
+ bicl3 #-65536,r0,r3
+ movl -4(fp),r0
+ mull3 r0,r3,-8(fp)
+ mull3 r0,r0,-4(fp)
+ mull2 r3,r3
+ bicl3 #32767,-8(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r3
+ bicl3 #-65536,-8(fp),r0
+ ashl #17,r0,-8(fp)
+ addl3 -4(fp),-8(fp),r0
+ bicl3 #0,r0,-4(fp)
+ cmpl -4(fp),-8(fp)
+ bgequ noname.369
+ incl r3
+noname.369:
+ movl -4(fp),r1
+ movl r3,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.370
+ incl r2
+noname.370:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.371
+ incl r7
+noname.371:
+
+ movl r9,@4(ap)
+
+ clrl r9
+
+ movzwl 6(r4),r2
+ bicl3 #-65536,(r4),r3
+ movzwl 2(r4),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,4(r4),-20(fp)
+ bicl3 #-65536,r2,-24(fp)
+ mull3 r0,-20(fp),-12(fp)
+ mull2 r3,-20(fp)
+ mull3 r3,-24(fp),-16(fp)
+ mull2 r0,-24(fp)
+ addl3 -12(fp),-16(fp),r0
+ bicl3 #0,r0,-12(fp)
+ cmpl -12(fp),-16(fp)
+ bgequ noname.372
+ addl2 #65536,-24(fp)
+noname.372:
+ movzwl -10(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-24(fp)
+ bicl3 #-65536,-12(fp),r0
+ ashl #16,r0,-16(fp)
+ addl3 -16(fp),-20(fp),r0
+ bicl3 #0,r0,-20(fp)
+ cmpl -20(fp),-16(fp)
+ bgequ noname.373
+ incl -24(fp)
+noname.373:
+ movl -20(fp),r3
+ movl -24(fp),r2
+ bbc #31,r2,noname.374
+ incl r9
+noname.374:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.375
+ incl r2
+noname.375:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.376
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.376
+ incl r9
+noname.376:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.377
+ incl r9
+noname.377:
+
+ movl 4(ap),r0
+ movl r8,4(r0)
+
+ clrl r8
+
+ movl 8(ap),r4
+ movl 4(r4),r3
+ bicl3 #-65536,r3,-28(fp)
+ extzv #16,#16,r3,r0
+ bicl3 #-65536,r0,r3
+ movl -28(fp),r0
+ mull3 r0,r3,-32(fp)
+ mull3 r0,r0,-28(fp)
+ mull2 r3,r3
+ bicl3 #32767,-32(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r3
+ bicl3 #-65536,-32(fp),r0
+ ashl #17,r0,-32(fp)
+ addl3 -28(fp),-32(fp),r0
+ bicl3 #0,r0,-28(fp)
+ cmpl -28(fp),-32(fp)
+ bgequ noname.378
+ incl r3
+noname.378:
+ movl -28(fp),r1
+ movl r3,r2
+ addl2 r1,r7
+ bicl2 #0,r7
+ cmpl r7,r1
+ bgequ noname.379
+ incl r2
+noname.379:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.380
+ incl r8
+noname.380:
+
+ movzwl 10(r4),r2
+ bicl3 #-65536,(r4),r3
+ movzwl 2(r4),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,8(r4),-44(fp)
+ bicl3 #-65536,r2,-48(fp)
+ mull3 r0,-44(fp),-36(fp)
+ mull2 r3,-44(fp)
+ mull3 r3,-48(fp),-40(fp)
+ mull2 r0,-48(fp)
+ addl3 -36(fp),-40(fp),r0
+ bicl3 #0,r0,-36(fp)
+ cmpl -36(fp),-40(fp)
+ bgequ noname.381
+ addl2 #65536,-48(fp)
+noname.381:
+ movzwl -34(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-48(fp)
+ bicl3 #-65536,-36(fp),r0
+ ashl #16,r0,-40(fp)
+ addl3 -40(fp),-44(fp),r0
+ bicl3 #0,r0,-44(fp)
+ cmpl -44(fp),-40(fp)
+ bgequ noname.382
+ incl -48(fp)
+noname.382:
+ movl -44(fp),r3
+ movl -48(fp),r2
+ bbc #31,r2,noname.383
+ incl r8
+noname.383:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.384
+ incl r2
+noname.384:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.385
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.385
+ incl r8
+noname.385:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.386
+ incl r8
+noname.386:
+
+ movl 4(ap),r0
+ movl r7,8(r0)
+
+ clrl r7
+
+ movl 8(ap),r0
+ movzwl 14(r0),r2
+ bicl3 #-65536,(r0),r3
+ movzwl 2(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,12(r0),-60(fp)
+ bicl3 #-65536,r2,-64(fp)
+ mull3 r1,-60(fp),-52(fp)
+ mull2 r3,-60(fp)
+ mull3 r3,-64(fp),-56(fp)
+ mull2 r1,-64(fp)
+ addl3 -52(fp),-56(fp),r0
+ bicl3 #0,r0,-52(fp)
+ cmpl -52(fp),-56(fp)
+ bgequ noname.387
+ addl2 #65536,-64(fp)
+noname.387:
+ movzwl -50(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-64(fp)
+ bicl3 #-65536,-52(fp),r0
+ ashl #16,r0,-56(fp)
+ addl3 -56(fp),-60(fp),r0
+ bicl3 #0,r0,-60(fp)
+ cmpl -60(fp),-56(fp)
+ bgequ noname.388
+ incl -64(fp)
+noname.388:
+ movl -60(fp),r3
+ movl -64(fp),r2
+ bbc #31,r2,noname.389
+ incl r7
+noname.389:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.390
+ incl r2
+noname.390:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.391
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.391
+ incl r7
+noname.391:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.392
+ incl r7
+noname.392:
+
+ movl 8(ap),r0
+ movzwl 10(r0),r2
+ bicl3 #-65536,4(r0),r3
+ movzwl 6(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,8(r0),-76(fp)
+ bicl3 #-65536,r2,-80(fp)
+ mull3 r1,-76(fp),-68(fp)
+ mull2 r3,-76(fp)
+ mull3 r3,-80(fp),-72(fp)
+ mull2 r1,-80(fp)
+ addl3 -68(fp),-72(fp),r0
+ bicl3 #0,r0,-68(fp)
+ cmpl -68(fp),-72(fp)
+ bgequ noname.393
+ addl2 #65536,-80(fp)
+noname.393:
+ movzwl -66(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-80(fp)
+ bicl3 #-65536,-68(fp),r0
+ ashl #16,r0,-72(fp)
+ addl3 -72(fp),-76(fp),r0
+ bicl3 #0,r0,-76(fp)
+ cmpl -76(fp),-72(fp)
+ bgequ noname.394
+ incl -80(fp)
+noname.394:
+ movl -76(fp),r3
+ movl -80(fp),r2
+ bbc #31,r2,noname.395
+ incl r7
+noname.395:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.396
+ incl r2
+noname.396:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.397
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.397
+ incl r7
+noname.397:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.398
+ incl r7
+noname.398:
+
+ movl 4(ap),r0
+ movl r9,12(r0)
+
+ clrl r9
+
+ movl 8(ap),r2
+ movl 8(r2),r4
+ bicl3 #-65536,r4,-84(fp)
+ extzv #16,#16,r4,r0
+ bicl3 #-65536,r0,r4
+ movl -84(fp),r0
+ mull3 r0,r4,-88(fp)
+ mull3 r0,r0,-84(fp)
+ mull2 r4,r4
+ bicl3 #32767,-88(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r4
+ bicl3 #-65536,-88(fp),r0
+ ashl #17,r0,-88(fp)
+ addl3 -84(fp),-88(fp),r0
+ bicl3 #0,r0,-84(fp)
+ cmpl -84(fp),-88(fp)
+ bgequ noname.399
+ incl r4
+noname.399:
+ movl -84(fp),r1
+ movl r4,r3
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.400
+ incl r3
+noname.400:
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.401
+ incl r9
+noname.401:
+
+ movzwl 14(r2),r3
+ bicl3 #-65536,4(r2),r1
+ movzwl 6(r2),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,12(r2),-100(fp)
+ bicl3 #-65536,r3,-104(fp)
+ mull3 r0,-100(fp),-92(fp)
+ mull2 r1,-100(fp)
+ mull3 r1,-104(fp),-96(fp)
+ mull2 r0,-104(fp)
+ addl3 -92(fp),-96(fp),r0
+ bicl3 #0,r0,-92(fp)
+ cmpl -92(fp),-96(fp)
+ bgequ noname.402
+ addl2 #65536,-104(fp)
+noname.402:
+ movzwl -90(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-104(fp)
+ bicl3 #-65536,-92(fp),r0
+ ashl #16,r0,-96(fp)
+ addl3 -96(fp),-100(fp),r0
+ bicl3 #0,r0,-100(fp)
+ cmpl -100(fp),-96(fp)
+ bgequ noname.403
+ incl -104(fp)
+noname.403:
+ movl -100(fp),r3
+ movl -104(fp),r2
+ bbc #31,r2,noname.404
+ incl r9
+noname.404:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.405
+ incl r2
+noname.405:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.406
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.406
+ incl r9
+noname.406:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.407
+ incl r9
+noname.407:
+
+ movl 8(ap),r0
+ movzwl 18(r0),r2
+ bicl3 #-65536,(r0),r3
+ movzwl 2(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,16(r0),-116(fp)
+ bicl3 #-65536,r2,-120(fp)
+ mull3 r1,-116(fp),-108(fp)
+ mull2 r3,-116(fp)
+ mull3 r3,-120(fp),-112(fp)
+ mull2 r1,-120(fp)
+ addl3 -108(fp),-112(fp),r0
+ bicl3 #0,r0,-108(fp)
+ cmpl -108(fp),-112(fp)
+ bgequ noname.408
+ addl2 #65536,-120(fp)
+noname.408:
+ movzwl -106(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-120(fp)
+ bicl3 #-65536,-108(fp),r0
+ ashl #16,r0,-112(fp)
+ addl3 -112(fp),-116(fp),r0
+ bicl3 #0,r0,-116(fp)
+ cmpl -116(fp),-112(fp)
+ bgequ noname.409
+ incl -120(fp)
+noname.409:
+ movl -116(fp),r3
+ movl -120(fp),r2
+ bbc #31,r2,noname.410
+ incl r9
+noname.410:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.411
+ incl r2
+noname.411:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.412
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.412
+ incl r9
+noname.412:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.413
+ incl r9
+noname.413:
+
+ movl 4(ap),r0
+ movl r8,16(r0)
+
+ clrl r8
+
+ movl 8(ap),r0
+ movzwl 22(r0),r2
+ bicl3 #-65536,(r0),r3
+ movzwl 2(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,20(r0),-132(fp)
+ bicl3 #-65536,r2,-136(fp)
+ mull3 r1,-132(fp),-124(fp)
+ mull2 r3,-132(fp)
+ mull3 r3,-136(fp),-128(fp)
+ mull2 r1,-136(fp)
+ addl3 -124(fp),-128(fp),r0
+ bicl3 #0,r0,-124(fp)
+ cmpl -124(fp),-128(fp)
+ bgequ noname.414
+ addl2 #65536,-136(fp)
+noname.414:
+ movzwl -122(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-136(fp)
+ bicl3 #-65536,-124(fp),r0
+ ashl #16,r0,-128(fp)
+ addl3 -128(fp),-132(fp),r0
+ bicl3 #0,r0,-132(fp)
+ cmpl -132(fp),-128(fp)
+ bgequ noname.415
+ incl -136(fp)
+noname.415:
+ movl -132(fp),r3
+ movl -136(fp),r2
+ bbc #31,r2,noname.416
+ incl r8
+noname.416:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.417
+ incl r2
+noname.417:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.418
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.418
+ incl r8
+noname.418:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.419
+ incl r8
+noname.419:
+
+ movl 8(ap),r0
+ movzwl 18(r0),r2
+ bicl3 #-65536,4(r0),r3
+ movzwl 6(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,16(r0),-148(fp)
+ bicl3 #-65536,r2,-152(fp)
+ mull3 r1,-148(fp),-140(fp)
+ mull2 r3,-148(fp)
+ mull3 r3,-152(fp),-144(fp)
+ mull2 r1,-152(fp)
+ addl3 -140(fp),-144(fp),r0
+ bicl3 #0,r0,-140(fp)
+ cmpl -140(fp),-144(fp)
+ bgequ noname.420
+ addl2 #65536,-152(fp)
+noname.420:
+ movzwl -138(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-152(fp)
+ bicl3 #-65536,-140(fp),r0
+ ashl #16,r0,-144(fp)
+ addl3 -144(fp),-148(fp),r0
+ bicl3 #0,r0,-148(fp)
+ cmpl -148(fp),-144(fp)
+ bgequ noname.421
+ incl -152(fp)
+noname.421:
+ movl -148(fp),r3
+ movl -152(fp),r2
+ bbc #31,r2,noname.422
+ incl r8
+noname.422:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.423
+ incl r2
+noname.423:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.424
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.424
+ incl r8
+noname.424:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.425
+ incl r8
+noname.425:
+
+ movl 8(ap),r0
+ movzwl 14(r0),r2
+ bicl3 #-65536,8(r0),r3
+ movzwl 10(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,12(r0),-164(fp)
+ bicl3 #-65536,r2,-168(fp)
+ mull3 r1,-164(fp),-156(fp)
+ mull2 r3,-164(fp)
+ mull3 r3,-168(fp),-160(fp)
+ mull2 r1,-168(fp)
+ addl3 -156(fp),-160(fp),r0
+ bicl3 #0,r0,-156(fp)
+ cmpl -156(fp),-160(fp)
+ bgequ noname.426
+ addl2 #65536,-168(fp)
+noname.426:
+ movzwl -154(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-168(fp)
+ bicl3 #-65536,-156(fp),r0
+ ashl #16,r0,-160(fp)
+ addl3 -160(fp),-164(fp),r0
+ bicl3 #0,r0,-164(fp)
+ cmpl -164(fp),-160(fp)
+ bgequ noname.427
+ incl -168(fp)
+noname.427:
+ movl -164(fp),r3
+ movl -168(fp),r2
+ bbc #31,r2,noname.428
+ incl r8
+noname.428:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.429
+ incl r2
+noname.429:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.430
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.430
+ incl r8
+noname.430:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.431
+ incl r8
+noname.431:
+
+ movl 4(ap),r0
+ movl r7,20(r0)
+
+ clrl r7
+
+ movl 8(ap),r2
+ movl 12(r2),r4
+ bicl3 #-65536,r4,-172(fp)
+ extzv #16,#16,r4,r0
+ bicl3 #-65536,r0,r4
+ movl -172(fp),r0
+ mull3 r0,r4,-176(fp)
+ mull3 r0,r0,-172(fp)
+ mull2 r4,r4
+ bicl3 #32767,-176(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r4
+ bicl3 #-65536,-176(fp),r0
+ ashl #17,r0,-176(fp)
+ addl3 -172(fp),-176(fp),r0
+ bicl3 #0,r0,-172(fp)
+ cmpl -172(fp),-176(fp)
+ bgequ noname.432
+ incl r4
+noname.432:
+ movl -172(fp),r1
+ movl r4,r3
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.433
+ incl r3
+noname.433:
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.434
+ incl r7
+noname.434:
+
+ movzwl 18(r2),r3
+ bicl3 #-65536,8(r2),r1
+ movzwl 10(r2),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,16(r2),-188(fp)
+ bicl3 #-65536,r3,-192(fp)
+ mull3 r0,-188(fp),-180(fp)
+ mull2 r1,-188(fp)
+ mull3 r1,-192(fp),-184(fp)
+ mull2 r0,-192(fp)
+ addl3 -180(fp),-184(fp),r0
+ bicl3 #0,r0,-180(fp)
+ cmpl -180(fp),-184(fp)
+ bgequ noname.435
+ addl2 #65536,-192(fp)
+noname.435:
+ movzwl -178(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-192(fp)
+ bicl3 #-65536,-180(fp),r0
+ ashl #16,r0,-184(fp)
+ addl3 -184(fp),-188(fp),r0
+ bicl3 #0,r0,-188(fp)
+ cmpl -188(fp),-184(fp)
+ bgequ noname.436
+ incl -192(fp)
+noname.436:
+ movl -188(fp),r3
+ movl -192(fp),r2
+ bbc #31,r2,noname.437
+ incl r7
+noname.437:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.438
+ incl r2
+noname.438:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.439
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.439
+ incl r7
+noname.439:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.440
+ incl r7
+noname.440:
+
+ movl 8(ap),r0
+ movzwl 22(r0),r2
+ bicl3 #-65536,4(r0),r3
+ movzwl 6(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,20(r0),-204(fp)
+ bicl3 #-65536,r2,-208(fp)
+ mull3 r1,-204(fp),-196(fp)
+ mull2 r3,-204(fp)
+ mull3 r3,-208(fp),-200(fp)
+ mull2 r1,-208(fp)
+ addl3 -196(fp),-200(fp),r0
+ bicl3 #0,r0,-196(fp)
+ cmpl -196(fp),-200(fp)
+ bgequ noname.441
+ addl2 #65536,-208(fp)
+noname.441:
+ movzwl -194(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-208(fp)
+ bicl3 #-65536,-196(fp),r0
+ ashl #16,r0,-200(fp)
+ addl3 -200(fp),-204(fp),r0
+ bicl3 #0,r0,-204(fp)
+ cmpl -204(fp),-200(fp)
+ bgequ noname.442
+ incl -208(fp)
+noname.442:
+ movl -204(fp),r3
+ movl -208(fp),r2
+ bbc #31,r2,noname.443
+ incl r7
+noname.443:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.444
+ incl r2
+noname.444:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.445
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.445
+ incl r7
+noname.445:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.446
+ incl r7
+noname.446:
+
+ movl 8(ap),r0
+ movzwl 26(r0),r2
+ bicl3 #-65536,(r0),r3
+ movzwl 2(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,24(r0),-220(fp)
+ bicl3 #-65536,r2,-224(fp)
+ mull3 r1,-220(fp),-212(fp)
+ mull2 r3,-220(fp)
+ mull3 r3,-224(fp),-216(fp)
+ mull2 r1,-224(fp)
+ addl3 -212(fp),-216(fp),r0
+ bicl3 #0,r0,-212(fp)
+ cmpl -212(fp),-216(fp)
+ bgequ noname.447
+ addl2 #65536,-224(fp)
+noname.447:
+ movzwl -210(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-224(fp)
+ bicl3 #-65536,-212(fp),r0
+ ashl #16,r0,-216(fp)
+ addl3 -216(fp),-220(fp),r0
+ bicl3 #0,r0,-220(fp)
+ cmpl -220(fp),-216(fp)
+ bgequ noname.448
+ incl -224(fp)
+noname.448:
+ movl -220(fp),r3
+ movl -224(fp),r2
+ bbc #31,r2,noname.449
+ incl r7
+noname.449:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.450
+ incl r2
+noname.450:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.451
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.451
+ incl r7
+noname.451:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.452
+ incl r7
+noname.452:
+
+ movl 4(ap),r0
+ movl r9,24(r0)
+
+ clrl r9
+
+ movl 8(ap),r0
+ movzwl 30(r0),r2
+ bicl3 #-65536,(r0),r3
+ movzwl 2(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,28(r0),-236(fp)
+ bicl3 #-65536,r2,-240(fp)
+ mull3 r1,-236(fp),-228(fp)
+ mull2 r3,-236(fp)
+ mull3 r3,-240(fp),-232(fp)
+ mull2 r1,-240(fp)
+ addl3 -228(fp),-232(fp),r0
+ bicl3 #0,r0,-228(fp)
+ cmpl -228(fp),-232(fp)
+ bgequ noname.453
+ addl2 #65536,-240(fp)
+noname.453:
+ movzwl -226(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-240(fp)
+ bicl3 #-65536,-228(fp),r0
+ ashl #16,r0,-232(fp)
+ addl3 -232(fp),-236(fp),r0
+ bicl3 #0,r0,-236(fp)
+ cmpl -236(fp),-232(fp)
+ bgequ noname.454
+ incl -240(fp)
+noname.454:
+ movl -236(fp),r3
+ movl -240(fp),r2
+ bbc #31,r2,noname.455
+ incl r9
+noname.455:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.456
+ incl r2
+noname.456:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.457
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.457
+ incl r9
+noname.457:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.458
+ incl r9
+noname.458:
+
+ movl 8(ap),r0
+ movzwl 26(r0),r2
+ bicl3 #-65536,4(r0),r3
+ movzwl 6(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,24(r0),-252(fp)
+ bicl3 #-65536,r2,-256(fp)
+ mull3 r1,-252(fp),-244(fp)
+ mull2 r3,-252(fp)
+ mull3 r3,-256(fp),-248(fp)
+ mull2 r1,-256(fp)
+ addl3 -244(fp),-248(fp),r0
+ bicl3 #0,r0,-244(fp)
+ cmpl -244(fp),-248(fp)
+ bgequ noname.459
+ addl2 #65536,-256(fp)
+noname.459:
+ movzwl -242(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-256(fp)
+ bicl3 #-65536,-244(fp),r0
+ ashl #16,r0,-248(fp)
+ addl3 -248(fp),-252(fp),r0
+ bicl3 #0,r0,-252(fp)
+ cmpl -252(fp),-248(fp)
+ bgequ noname.460
+ incl -256(fp)
+noname.460:
+ movl -252(fp),r3
+ movl -256(fp),r2
+ bbc #31,r2,noname.461
+ incl r9
+noname.461:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.462
+ incl r2
+noname.462:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.463
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.463
+ incl r9
+noname.463:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.464
+ incl r9
+noname.464:
+
+ movl 8(ap),r0
+ movzwl 22(r0),r2
+ bicl3 #-65536,8(r0),r3
+ movzwl 10(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,20(r0),-268(fp)
+ bicl3 #-65536,r2,-272(fp)
+ mull3 r1,-268(fp),-260(fp)
+ mull2 r3,-268(fp)
+ mull3 r3,-272(fp),-264(fp)
+ mull2 r1,-272(fp)
+ addl3 -260(fp),-264(fp),r0
+ bicl3 #0,r0,-260(fp)
+ cmpl -260(fp),-264(fp)
+ bgequ noname.465
+ addl2 #65536,-272(fp)
+noname.465:
+ movzwl -258(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-272(fp)
+ bicl3 #-65536,-260(fp),r0
+ ashl #16,r0,-264(fp)
+ addl3 -264(fp),-268(fp),r0
+ bicl3 #0,r0,-268(fp)
+ cmpl -268(fp),-264(fp)
+ bgequ noname.466
+ incl -272(fp)
+noname.466:
+ movl -268(fp),r3
+ movl -272(fp),r2
+ bbc #31,r2,noname.467
+ incl r9
+noname.467:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.468
+ incl r2
+noname.468:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.469
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.469
+ incl r9
+noname.469:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.470
+ incl r9
+noname.470:
+
+ movl 8(ap),r0
+ movzwl 18(r0),r2
+ bicl3 #-65536,12(r0),r3
+ movzwl 14(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,16(r0),-284(fp)
+ bicl3 #-65536,r2,-288(fp)
+ mull3 r1,-284(fp),-276(fp)
+ mull2 r3,-284(fp)
+ mull3 r3,-288(fp),-280(fp)
+ mull2 r1,-288(fp)
+ addl3 -276(fp),-280(fp),r0
+ bicl3 #0,r0,-276(fp)
+ cmpl -276(fp),-280(fp)
+ bgequ noname.471
+ addl2 #65536,-288(fp)
+noname.471:
+ movzwl -274(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-288(fp)
+ bicl3 #-65536,-276(fp),r0
+ ashl #16,r0,-280(fp)
+ addl3 -280(fp),-284(fp),r0
+ bicl3 #0,r0,-284(fp)
+ cmpl -284(fp),-280(fp)
+ bgequ noname.472
+ incl -288(fp)
+noname.472:
+ movl -284(fp),r3
+ movl -288(fp),r2
+ bbc #31,r2,noname.473
+ incl r9
+noname.473:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.474
+ incl r2
+noname.474:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.475
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.475
+ incl r9
+noname.475:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.476
+ incl r9
+noname.476:
+
+ movl 4(ap),r0
+ movl r8,28(r0)
+
+ clrl r8
+
+ movl 8(ap),r3
+ movl 16(r3),r4
+ bicl3 #-65536,r4,r5
+ extzv #16,#16,r4,r0
+ bicl3 #-65536,r0,r4
+ mull3 r5,r4,-292(fp)
+ mull2 r5,r5
+ mull2 r4,r4
+ bicl3 #32767,-292(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r4
+ bicl3 #-65536,-292(fp),r0
+ ashl #17,r0,-292(fp)
+ addl2 -292(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-292(fp)
+ bgequ noname.477
+ incl r4
+noname.477:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r7
+ bicl2 #0,r7
+ cmpl r7,r1
+ bgequ noname.478
+ incl r2
+noname.478:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.479
+ incl r8
+noname.479:
+
+ bicl3 #-65536,20(r3),r4
+ movzwl 22(r3),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,12(r3),r2
+ movzwl 14(r3),r0
+ bicl2 #-65536,r0
+ movl r4,r6
+ movl r1,r5
+ mull3 r0,r6,-296(fp)
+ mull2 r2,r6
+ mull3 r2,r5,-300(fp)
+ mull2 r0,r5
+ addl3 -296(fp),-300(fp),r0
+ bicl3 #0,r0,-296(fp)
+ cmpl -296(fp),-300(fp)
+ bgequ noname.480
+ addl2 #65536,r5
+noname.480:
+ movzwl -294(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r5
+ bicl3 #-65536,-296(fp),r0
+ ashl #16,r0,-300(fp)
+ addl2 -300(fp),r6
+ bicl2 #0,r6
+ cmpl r6,-300(fp)
+ bgequ noname.481
+ incl r5
+noname.481:
+ movl r6,r3
+ movl r5,r2
+ bbc #31,r2,noname.482
+ incl r8
+noname.482:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.483
+ incl r2
+noname.483:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.484
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.484
+ incl r8
+noname.484:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.485
+ incl r8
+noname.485:
+
+ movl 8(ap),r0
+ bicl3 #-65536,24(r0),r3
+ movzwl 26(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,8(r0),r2
+ movzwl 10(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-304(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-308(fp)
+ mull2 r0,r4
+ addl3 -304(fp),-308(fp),r0
+ bicl3 #0,r0,-304(fp)
+ cmpl -304(fp),-308(fp)
+ bgequ noname.486
+ addl2 #65536,r4
+noname.486:
+ movzwl -302(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-304(fp),r0
+ ashl #16,r0,-308(fp)
+ addl2 -308(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-308(fp)
+ bgequ noname.487
+ incl r4
+noname.487:
+ movl r5,r3
+ movl r4,r2
+ bbc #31,r2,noname.488
+ incl r8
+noname.488:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.489
+ incl r2
+noname.489:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.490
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.490
+ incl r8
+noname.490:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.491
+ incl r8
+noname.491:
+
+ movl 8(ap),r0
+ bicl3 #-65536,28(r0),r3
+ movzwl 30(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,4(r0),r2
+ movzwl 6(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-312(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-316(fp)
+ mull2 r0,r4
+ addl3 -312(fp),-316(fp),r0
+ bicl3 #0,r0,-312(fp)
+ cmpl -312(fp),-316(fp)
+ bgequ noname.492
+ addl2 #65536,r4
+noname.492:
+ movzwl -310(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-312(fp),r0
+ ashl #16,r0,-316(fp)
+ addl2 -316(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-316(fp)
+ bgequ noname.493
+ incl r4
+noname.493:
+ movl r5,r3
+ movl r4,r2
+ bbc #31,r2,noname.494
+ incl r8
+noname.494:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.495
+ incl r2
+noname.495:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.496
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.496
+ incl r8
+noname.496:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.497
+ incl r8
+noname.497:
+
+ movl 4(ap),r0
+ movl r7,32(r0)
+
+ clrl r7
+
+ movl 8(ap),r0
+ bicl3 #-65536,28(r0),r3
+ movzwl 30(r0),r2
+ bicl3 #-65536,8(r0),r1
+ movzwl 10(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r4
+ bicl3 #-65536,r2,-328(fp)
+ mull3 r0,r4,-320(fp)
+ mull2 r1,r4
+ mull3 r1,-328(fp),-324(fp)
+ mull2 r0,-328(fp)
+ addl3 -320(fp),-324(fp),r0
+ bicl3 #0,r0,-320(fp)
+ cmpl -320(fp),-324(fp)
+ bgequ noname.498
+ addl2 #65536,-328(fp)
+noname.498:
+ movzwl -318(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-328(fp)
+ bicl3 #-65536,-320(fp),r0
+ ashl #16,r0,-324(fp)
+ addl2 -324(fp),r4
+ bicl2 #0,r4
+ cmpl r4,-324(fp)
+ bgequ noname.499
+ incl -328(fp)
+noname.499:
+ movl r4,r3
+ movl -328(fp),r2
+ bbc #31,r2,noname.500
+ incl r7
+noname.500:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.501
+ incl r2
+noname.501:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.502
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.502
+ incl r7
+noname.502:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.503
+ incl r7
+noname.503:
+
+ movl 8(ap),r0
+ movzwl 26(r0),r2
+ bicl3 #-65536,12(r0),r3
+ movzwl 14(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,24(r0),-340(fp)
+ bicl3 #-65536,r2,-344(fp)
+ mull3 r1,-340(fp),-332(fp)
+ mull2 r3,-340(fp)
+ mull3 r3,-344(fp),-336(fp)
+ mull2 r1,-344(fp)
+ addl3 -332(fp),-336(fp),r0
+ bicl3 #0,r0,-332(fp)
+ cmpl -332(fp),-336(fp)
+ bgequ noname.504
+ addl2 #65536,-344(fp)
+noname.504:
+ movzwl -330(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-344(fp)
+ bicl3 #-65536,-332(fp),r0
+ ashl #16,r0,-336(fp)
+ addl3 -336(fp),-340(fp),r0
+ bicl3 #0,r0,-340(fp)
+ cmpl -340(fp),-336(fp)
+ bgequ noname.505
+ incl -344(fp)
+noname.505:
+ movl -340(fp),r3
+ movl -344(fp),r2
+ bbc #31,r2,noname.506
+ incl r7
+noname.506:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.507
+ incl r2
+noname.507:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.508
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.508
+ incl r7
+noname.508:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.509
+ incl r7
+noname.509:
+
+ movl 8(ap),r0
+ movzwl 22(r0),r2
+ bicl3 #-65536,16(r0),r3
+ movzwl 18(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,20(r0),-356(fp)
+ bicl3 #-65536,r2,-360(fp)
+ mull3 r1,-356(fp),-348(fp)
+ mull2 r3,-356(fp)
+ mull3 r3,-360(fp),-352(fp)
+ mull2 r1,-360(fp)
+ addl3 -348(fp),-352(fp),r0
+ bicl3 #0,r0,-348(fp)
+ cmpl -348(fp),-352(fp)
+ bgequ noname.510
+ addl2 #65536,-360(fp)
+noname.510:
+ movzwl -346(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-360(fp)
+ bicl3 #-65536,-348(fp),r0
+ ashl #16,r0,-352(fp)
+ addl3 -352(fp),-356(fp),r0
+ bicl3 #0,r0,-356(fp)
+ cmpl -356(fp),-352(fp)
+ bgequ noname.511
+ incl -360(fp)
+noname.511:
+ movl -356(fp),r3
+ movl -360(fp),r2
+ bbc #31,r2,noname.512
+ incl r7
+noname.512:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.513
+ incl r2
+noname.513:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.514
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.514
+ incl r7
+noname.514:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.515
+ incl r7
+noname.515:
+
+ movl 4(ap),r0
+ movl r9,36(r0)
+
+ clrl r9
+
+ movl 8(ap),r3
+ movl 20(r3),r4
+ bicl3 #-65536,r4,-364(fp)
+ extzv #16,#16,r4,r0
+ bicl3 #-65536,r0,r4
+ movl -364(fp),r0
+ mull3 r0,r4,-368(fp)
+ mull3 r0,r0,-364(fp)
+ mull2 r4,r4
+ bicl3 #32767,-368(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r4
+ bicl3 #-65536,-368(fp),r0
+ ashl #17,r0,-368(fp)
+ addl3 -364(fp),-368(fp),r0
+ bicl3 #0,r0,-364(fp)
+ cmpl -364(fp),-368(fp)
+ bgequ noname.516
+ incl r4
+noname.516:
+ movl -364(fp),r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.517
+ incl r2
+noname.517:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.518
+ incl r9
+noname.518:
+
+ bicl3 #-65536,24(r3),r4
+ movzwl 26(r3),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,16(r3),r2
+ movzwl 18(r3),r0
+ bicl2 #-65536,r0
+ movl r4,r6
+ movl r1,r5
+ mull3 r0,r6,-372(fp)
+ mull2 r2,r6
+ mull3 r2,r5,-376(fp)
+ mull2 r0,r5
+ addl3 -372(fp),-376(fp),r0
+ bicl3 #0,r0,-372(fp)
+ cmpl -372(fp),-376(fp)
+ bgequ noname.519
+ addl2 #65536,r5
+noname.519:
+ movzwl -370(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r5
+ bicl3 #-65536,-372(fp),r0
+ ashl #16,r0,-376(fp)
+ addl2 -376(fp),r6
+ bicl2 #0,r6
+ cmpl r6,-376(fp)
+ bgequ noname.520
+ incl r5
+noname.520:
+ movl r6,r3
+ movl r5,r2
+ bbc #31,r2,noname.521
+ incl r9
+noname.521:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.522
+ incl r2
+noname.522:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.523
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.523
+ incl r9
+noname.523:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.524
+ incl r9
+noname.524:
+
+ movl 8(ap),r0
+ bicl3 #-65536,28(r0),r3
+ movzwl 30(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,12(r0),r2
+ movzwl 14(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-380(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-384(fp)
+ mull2 r0,r4
+ addl3 -380(fp),-384(fp),r0
+ bicl3 #0,r0,-380(fp)
+ cmpl -380(fp),-384(fp)
+ bgequ noname.525
+ addl2 #65536,r4
+noname.525:
+ movzwl -378(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-380(fp),r0
+ ashl #16,r0,-384(fp)
+ addl2 -384(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-384(fp)
+ bgequ noname.526
+ incl r4
+noname.526:
+ movl r5,r3
+ movl r4,r2
+ bbc #31,r2,noname.527
+ incl r9
+noname.527:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.528
+ incl r2
+noname.528:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.529
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.529
+ incl r9
+noname.529:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.530
+ incl r9
+noname.530:
+ movl 4(ap),r0
+ movl r8,40(r0)
+
+ clrl r8
+
+ movl 8(ap),r0
+ bicl3 #-65536,28(r0),r3
+ movzwl 30(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,16(r0),r2
+ movzwl 18(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-388(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-392(fp)
+ mull2 r0,r4
+ addl3 -388(fp),-392(fp),r0
+ bicl3 #0,r0,-388(fp)
+ cmpl -388(fp),-392(fp)
+ bgequ noname.531
+ addl2 #65536,r4
+noname.531:
+ movzwl -386(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-388(fp),r0
+ ashl #16,r0,-392(fp)
+ addl2 -392(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-392(fp)
+ bgequ noname.532
+ incl r4
+noname.532:
+ movl r5,r3
+ movl r4,r2
+ bbc #31,r2,noname.533
+ incl r8
+noname.533:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.534
+ incl r2
+noname.534:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.535
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.535
+ incl r8
+noname.535:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.536
+ incl r8
+noname.536:
+
+ movl 8(ap),r0
+ bicl3 #-65536,24(r0),r3
+ movzwl 26(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,20(r0),r2
+ movzwl 22(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-396(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-400(fp)
+ mull2 r0,r4
+ addl3 -396(fp),-400(fp),r0
+ bicl3 #0,r0,-396(fp)
+ cmpl -396(fp),-400(fp)
+ bgequ noname.537
+ addl2 #65536,r4
+noname.537:
+ movzwl -394(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-396(fp),r0
+ ashl #16,r0,-400(fp)
+ addl2 -400(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-400(fp)
+ bgequ noname.538
+ incl r4
+noname.538:
+ movl r5,r3
+ movl r4,r2
+ bbc #31,r2,noname.539
+ incl r8
+noname.539:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.540
+ incl r2
+noname.540:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r7
+ bicl2 #0,r7
+ cmpl r7,r3
+ bgequ noname.541
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.541
+ incl r8
+noname.541:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.542
+ incl r8
+noname.542:
+
+ movl 4(ap),r0
+ movl r7,44(r0)
+
+ clrl r7
+
+ movl 8(ap),r3
+ movl 24(r3),r4
+ bicl3 #-65536,r4,r5
+ extzv #16,#16,r4,r0
+ bicl3 #-65536,r0,r4
+ mull3 r5,r4,-404(fp)
+ mull2 r5,r5
+ mull2 r4,r4
+ bicl3 #32767,-404(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r4
+ bicl3 #-65536,-404(fp),r0
+ ashl #17,r0,-404(fp)
+ addl2 -404(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-404(fp)
+ bgequ noname.543
+ incl r4
+noname.543:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.544
+ incl r2
+noname.544:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.545
+ incl r7
+noname.545:
+
+ movzwl 30(r3),r2
+ bicl3 #-65536,20(r3),r1
+ movzwl 22(r3),r0
+ bicl2 #-65536,r0
+ bicl3 #-65536,28(r3),-416(fp)
+ bicl3 #-65536,r2,-420(fp)
+ mull3 r0,-416(fp),-408(fp)
+ mull2 r1,-416(fp)
+ mull3 r1,-420(fp),-412(fp)
+ mull2 r0,-420(fp)
+ addl3 -408(fp),-412(fp),r0
+ bicl3 #0,r0,-408(fp)
+ cmpl -408(fp),-412(fp)
+ bgequ noname.546
+ addl2 #65536,-420(fp)
+noname.546:
+ movzwl -406(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-420(fp)
+ bicl3 #-65536,-408(fp),r0
+ ashl #16,r0,-412(fp)
+ addl3 -412(fp),-416(fp),r0
+ bicl3 #0,r0,-416(fp)
+ cmpl -416(fp),-412(fp)
+ bgequ noname.547
+ incl -420(fp)
+noname.547:
+ movl -416(fp),r3
+ movl -420(fp),r2
+ bbc #31,r2,noname.548
+ incl r7
+noname.548:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.549
+ incl r2
+noname.549:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.550
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.550
+ incl r7
+noname.550:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.551
+ incl r7
+noname.551:
+
+ movl 4(ap),r0
+ movl r9,48(r0)
+
+ clrl r9
+
+ movl 8(ap),r0
+ movzwl 30(r0),r2
+ bicl3 #-65536,24(r0),r3
+ movzwl 26(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,28(r0),-432(fp)
+ bicl3 #-65536,r2,-436(fp)
+ mull3 r1,-432(fp),-424(fp)
+ mull2 r3,-432(fp)
+ mull3 r3,-436(fp),-428(fp)
+ mull2 r1,-436(fp)
+ addl3 -424(fp),-428(fp),r0
+ bicl3 #0,r0,-424(fp)
+ cmpl -424(fp),-428(fp)
+ bgequ noname.552
+ addl2 #65536,-436(fp)
+noname.552:
+ movzwl -422(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,-436(fp)
+ bicl3 #-65536,-424(fp),r0
+ ashl #16,r0,-428(fp)
+ addl3 -428(fp),-432(fp),r0
+ bicl3 #0,r0,-432(fp)
+ cmpl -432(fp),-428(fp)
+ bgequ noname.553
+ incl -436(fp)
+noname.553:
+ movl -432(fp),r3
+ movl -436(fp),r2
+ bbc #31,r2,noname.554
+ incl r9
+noname.554:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.555
+ incl r2
+noname.555:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.556
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.556
+ incl r9
+noname.556:
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.557
+ incl r9
+noname.557:
+
+ movl 4(ap),r4
+ movl r8,52(r4)
+
+ clrl r8
+
+ movl 8(ap),r0
+ movl 28(r0),r3
+ bicl3 #-65536,r3,-440(fp)
+ extzv #16,#16,r3,r0
+ bicl3 #-65536,r0,r3
+ movl -440(fp),r0
+ mull3 r0,r3,-444(fp)
+ mull3 r0,r0,-440(fp)
+ mull2 r3,r3
+ bicl3 #32767,-444(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r3
+ bicl3 #-65536,-444(fp),r0
+ ashl #17,r0,-444(fp)
+ addl3 -440(fp),-444(fp),r0
+ bicl3 #0,r0,-440(fp)
+ cmpl -440(fp),-444(fp)
+ bgequ noname.558
+ incl r3
+noname.558:
+ movl -440(fp),r1
+ movl r3,r2
+ addl2 r1,r7
+ bicl2 #0,r7
+ cmpl r7,r1
+ bgequ noname.559
+ incl r2
+noname.559:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.560
+ incl r8
+noname.560:
+
+ movl r7,56(r4)
+
+ movl r9,60(r4)
+
+ ret
+
+
+
+;r=4 ;(AP)
+;a=8 ;(AP)
+;b=12 ;(AP)
+;n=16 ;(AP) n by value (input)
+
+ .psect code,nowrt
+
+.entry BN_SQR_COMBA4,^m<r2,r3,r4,r5,r6,r7,r8,r9,r10>
+ subl2 #44,sp
+
+ clrq r8
+
+ clrl r10
+
+ movl 8(ap),r5
+ movl (r5),r3
+ bicl3 #-65536,r3,r4
+ extzv #16,#16,r3,r0
+ bicl3 #-65536,r0,r3
+ mull3 r4,r3,-4(fp)
+ mull2 r4,r4
+ mull2 r3,r3
+ bicl3 #32767,-4(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r3
+ bicl3 #-65536,-4(fp),r0
+ ashl #17,r0,-4(fp)
+ addl2 -4(fp),r4
+ bicl2 #0,r4
+ cmpl r4,-4(fp)
+ bgequ noname.563
+ incl r3
+noname.563:
+ movl r4,r1
+ movl r3,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.564
+ incl r2
+noname.564:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.565
+ incl r10
+noname.565:
+
+ movl r9,@4(ap)
+
+ clrl r9
+
+ bicl3 #-65536,4(r5),r3
+ movzwl 6(r5),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,(r5),r2
+ movzwl 2(r5),r0
+ bicl2 #-65536,r0
+ movl r3,r6
+ movl r1,r4
+ mull3 r0,r6,-8(fp)
+ mull2 r2,r6
+ mull2 r4,r2
+ mull2 r0,r4
+ addl3 -8(fp),r2,r0
+ bicl3 #0,r0,-8(fp)
+ cmpl -8(fp),r2
+ bgequ noname.566
+ addl2 #65536,r4
+noname.566:
+ movzwl -6(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-8(fp),r0
+ ashl #16,r0,r1
+ addl2 r1,r6
+ bicl2 #0,r6
+ cmpl r6,r1
+ bgequ noname.567
+ incl r4
+noname.567:
+ movl r6,r3
+ movl r4,r2
+ bbc #31,r2,noname.568
+ incl r9
+noname.568:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.569
+ incl r2
+noname.569:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.570
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.570
+ incl r9
+noname.570:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.571
+ incl r9
+noname.571:
+
+ movl 4(ap),r0
+ movl r8,4(r0)
+
+ clrl r8
+
+ movl 8(ap),r4
+ movl 4(r4),r3
+ bicl3 #-65536,r3,r5
+ extzv #16,#16,r3,r0
+ bicl3 #-65536,r0,r3
+ mull3 r5,r3,r1
+ mull2 r5,r5
+ mull2 r3,r3
+ bicl3 #32767,r1,r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r3
+ bicl2 #-65536,r1
+ ashl #17,r1,r1
+ addl2 r1,r5
+ bicl2 #0,r5
+ cmpl r5,r1
+ bgequ noname.572
+ incl r3
+noname.572:
+ movl r5,r1
+ movl r3,r2
+ addl2 r1,r10
+ bicl2 #0,r10
+ cmpl r10,r1
+ bgequ noname.573
+ incl r2
+noname.573:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.574
+ incl r8
+noname.574:
+
+ bicl3 #-65536,8(r4),r3
+ movzwl 10(r4),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,(r4),r2
+ movzwl 2(r4),r0
+ bicl2 #-65536,r0
+ movl r3,r6
+ movl r1,r5
+ mull3 r0,r6,r7
+ mull2 r2,r6
+ mull2 r5,r2
+ mull2 r0,r5
+ addl2 r2,r7
+ bicl2 #0,r7
+ cmpl r7,r2
+ bgequ noname.575
+ addl2 #65536,r5
+noname.575:
+ extzv #16,#16,r7,r0
+ bicl2 #-65536,r0
+ addl2 r0,r5
+ bicl3 #-65536,r7,r0
+ ashl #16,r0,r1
+ addl2 r1,r6
+ bicl2 #0,r6
+ cmpl r6,r1
+ bgequ noname.576
+ incl r5
+noname.576:
+ movl r6,r3
+ movl r5,r2
+ bbc #31,r2,noname.577
+ incl r8
+noname.577:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.578
+ incl r2
+noname.578:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r10
+ bicl2 #0,r10
+ cmpl r10,r3
+ bgequ noname.579
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.579
+ incl r8
+noname.579:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.580
+ incl r8
+noname.580:
+
+ movl 4(ap),r0
+ movl r10,8(r0)
+
+ clrl r10
+
+ movl 8(ap),r0
+ bicl3 #-65536,12(r0),r3
+ movzwl 14(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,(r0),r2
+ movzwl 2(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,r6
+ mull2 r2,r5
+ mull3 r2,r4,-12(fp)
+ mull2 r0,r4
+ addl2 -12(fp),r6
+ bicl2 #0,r6
+ cmpl r6,-12(fp)
+ bgequ noname.581
+ addl2 #65536,r4
+noname.581:
+ extzv #16,#16,r6,r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,r6,r0
+ ashl #16,r0,-12(fp)
+ addl2 -12(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-12(fp)
+ bgequ noname.582
+ incl r4
+noname.582:
+ movl r5,r3
+ movl r4,r2
+ bbc #31,r2,noname.583
+ incl r10
+noname.583:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.584
+ incl r2
+noname.584:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.585
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.585
+ incl r10
+noname.585:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.586
+ incl r10
+noname.586:
+
+ movl 8(ap),r0
+ bicl3 #-65536,8(r0),r3
+ movzwl 10(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,4(r0),r2
+ movzwl 6(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-16(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-20(fp)
+ mull2 r0,r4
+ addl3 -16(fp),-20(fp),r0
+ bicl3 #0,r0,-16(fp)
+ cmpl -16(fp),-20(fp)
+ bgequ noname.587
+ addl2 #65536,r4
+noname.587:
+ movzwl -14(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-16(fp),r0
+ ashl #16,r0,-20(fp)
+ addl2 -20(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-20(fp)
+ bgequ noname.588
+ incl r4
+noname.588:
+ movl r5,r3
+ movl r4,r2
+ bbc #31,r2,noname.589
+ incl r10
+noname.589:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.590
+ incl r2
+noname.590:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r9
+ bicl2 #0,r9
+ cmpl r9,r3
+ bgequ noname.591
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.591
+ incl r10
+noname.591:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.592
+ incl r10
+noname.592:
+ movl 4(ap),r0
+ movl r9,12(r0)
+
+ clrl r9
+
+ movl 8(ap),r3
+ movl 8(r3),r4
+ bicl3 #-65536,r4,r5
+ extzv #16,#16,r4,r0
+ bicl3 #-65536,r0,r4
+ mull3 r5,r4,-24(fp)
+ mull2 r5,r5
+ mull2 r4,r4
+ bicl3 #32767,-24(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r4
+ bicl3 #-65536,-24(fp),r0
+ ashl #17,r0,-24(fp)
+ addl2 -24(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-24(fp)
+ bgequ noname.593
+ incl r4
+noname.593:
+ movl r5,r1
+ movl r4,r2
+ addl2 r1,r8
+ bicl2 #0,r8
+ cmpl r8,r1
+ bgequ noname.594
+ incl r2
+noname.594:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.595
+ incl r9
+noname.595:
+
+ bicl3 #-65536,12(r3),r4
+ movzwl 14(r3),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,4(r3),r2
+ movzwl 6(r3),r0
+ bicl2 #-65536,r0
+ movl r4,r6
+ movl r1,r5
+ mull3 r0,r6,-28(fp)
+ mull2 r2,r6
+ mull3 r2,r5,-32(fp)
+ mull2 r0,r5
+ addl3 -28(fp),-32(fp),r0
+ bicl3 #0,r0,-28(fp)
+ cmpl -28(fp),-32(fp)
+ bgequ noname.596
+ addl2 #65536,r5
+noname.596:
+ movzwl -26(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r5
+ bicl3 #-65536,-28(fp),r0
+ ashl #16,r0,-32(fp)
+ addl2 -32(fp),r6
+ bicl2 #0,r6
+ cmpl r6,-32(fp)
+ bgequ noname.597
+ incl r5
+noname.597:
+ movl r6,r3
+ movl r5,r2
+ bbc #31,r2,noname.598
+ incl r9
+noname.598:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.599
+ incl r2
+noname.599:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r8
+ bicl2 #0,r8
+ cmpl r8,r3
+ bgequ noname.600
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.600
+ incl r9
+noname.600:
+ addl2 r2,r10
+ bicl2 #0,r10
+ cmpl r10,r2
+ bgequ noname.601
+ incl r9
+noname.601:
+
+ movl 4(ap),r0
+ movl r8,16(r0)
+
+ clrl r8
+
+ movl 8(ap),r0
+ bicl3 #-65536,12(r0),r3
+ movzwl 14(r0),r1
+ bicl2 #-65536,r1
+ bicl3 #-65536,8(r0),r2
+ movzwl 10(r0),r0
+ bicl2 #-65536,r0
+ movl r3,r5
+ movl r1,r4
+ mull3 r0,r5,-36(fp)
+ mull2 r2,r5
+ mull3 r2,r4,-40(fp)
+ mull2 r0,r4
+ addl3 -36(fp),-40(fp),r0
+ bicl3 #0,r0,-36(fp)
+ cmpl -36(fp),-40(fp)
+ bgequ noname.602
+ addl2 #65536,r4
+noname.602:
+ movzwl -34(fp),r0
+ bicl2 #-65536,r0
+ addl2 r0,r4
+ bicl3 #-65536,-36(fp),r0
+ ashl #16,r0,-40(fp)
+ addl2 -40(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-40(fp)
+ bgequ noname.603
+ incl r4
+noname.603:
+ movl r5,r3
+ movl r4,r2
+ bbc #31,r2,noname.604
+ incl r8
+noname.604:
+ addl2 r2,r2
+ bicl2 #0,r2
+ bbc #31,r3,noname.605
+ incl r2
+noname.605:
+ addl2 r3,r3
+ bicl2 #0,r3
+ addl2 r3,r10
+ bicl2 #0,r10
+ cmpl r10,r3
+ bgequ noname.606
+ incl r2
+ bicl3 #0,r2,r0
+ bneq noname.606
+ incl r8
+noname.606:
+ addl2 r2,r9
+ bicl2 #0,r9
+ cmpl r9,r2
+ bgequ noname.607
+ incl r8
+noname.607:
+
+ movl 4(ap),r4
+ movl r10,20(r4)
+
+ clrl r10
+
+ movl 8(ap),r0
+ movl 12(r0),r3
+ bicl3 #-65536,r3,r5
+ extzv #16,#16,r3,r0
+ bicl3 #-65536,r0,r3
+ mull3 r5,r3,-44(fp)
+ mull2 r5,r5
+ mull2 r3,r3
+ bicl3 #32767,-44(fp),r0
+ extzv #15,#17,r0,r0
+ addl2 r0,r3
+ bicl3 #-65536,-44(fp),r0
+ ashl #17,r0,-44(fp)
+ addl2 -44(fp),r5
+ bicl2 #0,r5
+ cmpl r5,-44(fp)
+ bgequ noname.608
+ incl r3
+noname.608:
+ movl r5,r1
+ movl r3,r2
+ addl2 r1,r9
+ bicl2 #0,r9
+ cmpl r9,r1
+ bgequ noname.609
+ incl r2
+noname.609:
+ addl2 r2,r8
+ bicl2 #0,r8
+ cmpl r8,r2
+ bgequ noname.610
+ incl r10
+noname.610:
+
+ movl r9,24(r4)
+
+ movl r8,28(r4)
+
+ ret
+
+; For now, the code below doesn't work, so I end this prematurely.
+.end
diff --git a/openssl/trunk/crypto/bn/asm/x86.pl b/openssl/trunk/crypto/bn/asm/x86.pl
new file mode 100644
index 00000000..1bc4f1bb
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86.pl
@@ -0,0 +1,28 @@
+#!/usr/local/bin/perl
+
+push(@INC,"perlasm","../../perlasm");
+require "x86asm.pl";
+
+require("x86/mul_add.pl");
+require("x86/mul.pl");
+require("x86/sqr.pl");
+require("x86/div.pl");
+require("x86/add.pl");
+require("x86/sub.pl");
+require("x86/comba.pl");
+
+&asm_init($ARGV[0],$0);
+
+&bn_mul_add_words("bn_mul_add_words");
+&bn_mul_words("bn_mul_words");
+&bn_sqr_words("bn_sqr_words");
+&bn_div_words("bn_div_words");
+&bn_add_words("bn_add_words");
+&bn_sub_words("bn_sub_words");
+&bn_mul_comba("bn_mul_comba8",8);
+&bn_mul_comba("bn_mul_comba4",4);
+&bn_sqr_comba("bn_sqr_comba8",8);
+&bn_sqr_comba("bn_sqr_comba4",4);
+
+&asm_finish();
+
diff --git a/openssl/trunk/crypto/bn/asm/x86/add.pl b/openssl/trunk/crypto/bn/asm/x86/add.pl
new file mode 100644
index 00000000..0b5cf583
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86/add.pl
@@ -0,0 +1,76 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_add_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $a="esi";
+ $b="edi";
+ $c="eax";
+ $r="ebx";
+ $tmp1="ecx";
+ $tmp2="edx";
+ $num="ebp";
+
+ &mov($r,&wparam(0)); # get r
+ &mov($a,&wparam(1)); # get a
+ &mov($b,&wparam(2)); # get b
+ &mov($num,&wparam(3)); # get num
+ &xor($c,$c); # clear carry
+ &and($num,0xfffffff8); # num / 8
+
+ &jz(&label("aw_finish"));
+
+ &set_label("aw_loop",0);
+ for ($i=0; $i<8; $i++)
+ {
+ &comment("Round $i");
+
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
+ &add($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &add($tmp1,$tmp2);
+ &adc($c,0);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($b,32);
+ &add($r,32);
+ &sub($num,8);
+ &jnz(&label("aw_loop"));
+
+ &set_label("aw_finish",0);
+ &mov($num,&wparam(3)); # get num
+ &and($num,7);
+ &jz(&label("aw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+ &add($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &add($tmp1,$tmp2);
+ &adc($c,0);
+ &dec($num) if ($i != 6);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *a
+ &jz(&label("aw_end")) if ($i != 6);
+ }
+ &set_label("aw_end",0);
+
+# &mov("eax",$c); # $c is "eax"
+
+ &function_end($name);
+ }
+
+1;
diff --git a/openssl/trunk/crypto/bn/asm/x86/comba.pl b/openssl/trunk/crypto/bn/asm/x86/comba.pl
new file mode 100644
index 00000000..22912536
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86/comba.pl
@@ -0,0 +1,277 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub mul_add_c
+ {
+ local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+ # pos == -1 if eax and edx are pre-loaded, 0 to load from next
+ # words, and 1 if load return value
+
+ &comment("mul a[$ai]*b[$bi]");
+
+ # "eax" and "edx" will always be pre-loaded.
+ # &mov("eax",&DWP($ai*4,$a,"",0)) ;
+ # &mov("edx",&DWP($bi*4,$b,"",0));
+
+ &mul("edx");
+ &add($c0,"eax");
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # laod next a
+ &mov("eax",&wparam(0)) if $pos > 0; # load r[]
+ ###
+ &adc($c1,"edx");
+ &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0; # laod next b
+ &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # laod next b
+ ###
+ &adc($c2,0);
+ # is pos > 1, it means it is the last loop
+ &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[];
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # laod next a
+ }
+
+sub sqr_add_c
+ {
+ local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+ # pos == -1 if eax and edx are pre-loaded, 0 to load from next
+ # words, and 1 if load return value
+
+ &comment("sqr a[$ai]*a[$bi]");
+
+ # "eax" and "edx" will always be pre-loaded.
+ # &mov("eax",&DWP($ai*4,$a,"",0)) ;
+ # &mov("edx",&DWP($bi*4,$b,"",0));
+
+ if ($ai == $bi)
+ { &mul("eax");}
+ else
+ { &mul("edx");}
+ &add($c0,"eax");
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a
+ ###
+ &adc($c1,"edx");
+ &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
+ ###
+ &adc($c2,0);
+ # is pos > 1, it means it is the last loop
+ &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[];
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b
+ }
+
+sub sqr_add_c2
+ {
+ local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
+
+ # pos == -1 if eax and edx are pre-loaded, 0 to load from next
+ # words, and 1 if load return value
+
+ &comment("sqr a[$ai]*a[$bi]");
+
+ # "eax" and "edx" will always be pre-loaded.
+ # &mov("eax",&DWP($ai*4,$a,"",0)) ;
+ # &mov("edx",&DWP($bi*4,$a,"",0));
+
+ if ($ai == $bi)
+ { &mul("eax");}
+ else
+ { &mul("edx");}
+ &add("eax","eax");
+ ###
+ &adc("edx","edx");
+ ###
+ &adc($c2,0);
+ &add($c0,"eax");
+ &adc($c1,"edx");
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a
+ &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b
+ &adc($c2,0);
+ &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[];
+ &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
+ ###
+ }
+
+sub bn_mul_comba
+ {
+ local($name,$num)=@_;
+ local($a,$b,$c0,$c1,$c2);
+ local($i,$as,$ae,$bs,$be,$ai,$bi);
+ local($tot,$end);
+
+ &function_begin_B($name,"");
+
+ $c0="ebx";
+ $c1="ecx";
+ $c2="ebp";
+ $a="esi";
+ $b="edi";
+
+ $as=0;
+ $ae=0;
+ $bs=0;
+ $be=0;
+ $tot=$num+$num-1;
+
+ &push("esi");
+ &mov($a,&wparam(1));
+ &push("edi");
+ &mov($b,&wparam(2));
+ &push("ebp");
+ &push("ebx");
+
+ &xor($c0,$c0);
+ &mov("eax",&DWP(0,$a,"",0)); # load the first word
+ &xor($c1,$c1);
+ &mov("edx",&DWP(0,$b,"",0)); # load the first second
+
+ for ($i=0; $i<$tot; $i++)
+ {
+ $ai=$as;
+ $bi=$bs;
+ $end=$be+1;
+
+ &comment("################## Calculate word $i");
+
+ for ($j=$bs; $j<$end; $j++)
+ {
+ &xor($c2,$c2) if ($j == $bs);
+ if (($j+1) == $end)
+ {
+ $v=1;
+ $v=2 if (($i+1) == $tot);
+ }
+ else
+ { $v=0; }
+ if (($j+1) != $end)
+ {
+ $na=($ai-1);
+ $nb=($bi+1);
+ }
+ else
+ {
+ $na=$as+($i < ($num-1));
+ $nb=$bs+($i >= ($num-1));
+ }
+#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
+ &mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
+ if ($v)
+ {
+ &comment("saved r[$i]");
+ # &mov("eax",&wparam(0));
+ # &mov(&DWP($i*4,"eax","",0),$c0);
+ ($c0,$c1,$c2)=($c1,$c2,$c0);
+ }
+ $ai--;
+ $bi++;
+ }
+ $as++ if ($i < ($num-1));
+ $ae++ if ($i >= ($num-1));
+
+ $bs++ if ($i >= ($num-1));
+ $be++ if ($i < ($num-1));
+ }
+ &comment("save r[$i]");
+ # &mov("eax",&wparam(0));
+ &mov(&DWP($i*4,"eax","",0),$c0);
+
+ &pop("ebx");
+ &pop("ebp");
+ &pop("edi");
+ &pop("esi");
+ &ret();
+ &function_end_B($name);
+ }
+
+sub bn_sqr_comba
+ {
+ local($name,$num)=@_;
+ local($r,$a,$c0,$c1,$c2)=@_;
+ local($i,$as,$ae,$bs,$be,$ai,$bi);
+ local($b,$tot,$end,$half);
+
+ &function_begin_B($name,"");
+
+ $c0="ebx";
+ $c1="ecx";
+ $c2="ebp";
+ $a="esi";
+ $r="edi";
+
+ &push("esi");
+ &push("edi");
+ &push("ebp");
+ &push("ebx");
+ &mov($r,&wparam(0));
+ &mov($a,&wparam(1));
+ &xor($c0,$c0);
+ &xor($c1,$c1);
+ &mov("eax",&DWP(0,$a,"",0)); # load the first word
+
+ $as=0;
+ $ae=0;
+ $bs=0;
+ $be=0;
+ $tot=$num+$num-1;
+
+ for ($i=0; $i<$tot; $i++)
+ {
+ $ai=$as;
+ $bi=$bs;
+ $end=$be+1;
+
+ &comment("############### Calculate word $i");
+ for ($j=$bs; $j<$end; $j++)
+ {
+ &xor($c2,$c2) if ($j == $bs);
+ if (($ai-1) < ($bi+1))
+ {
+ $v=1;
+ $v=2 if ($i+1) == $tot;
+ }
+ else
+ { $v=0; }
+ if (!$v)
+ {
+ $na=$ai-1;
+ $nb=$bi+1;
+ }
+ else
+ {
+ $na=$as+($i < ($num-1));
+ $nb=$bs+($i >= ($num-1));
+ }
+ if ($ai == $bi)
+ {
+ &sqr_add_c($r,$a,$ai,$bi,
+ $c0,$c1,$c2,$v,$i,$na,$nb);
+ }
+ else
+ {
+ &sqr_add_c2($r,$a,$ai,$bi,
+ $c0,$c1,$c2,$v,$i,$na,$nb);
+ }
+ if ($v)
+ {
+ &comment("saved r[$i]");
+ #&mov(&DWP($i*4,$r,"",0),$c0);
+ ($c0,$c1,$c2)=($c1,$c2,$c0);
+ last;
+ }
+ $ai--;
+ $bi++;
+ }
+ $as++ if ($i < ($num-1));
+ $ae++ if ($i >= ($num-1));
+
+ $bs++ if ($i >= ($num-1));
+ $be++ if ($i < ($num-1));
+ }
+ &mov(&DWP($i*4,$r,"",0),$c0);
+ &pop("ebx");
+ &pop("ebp");
+ &pop("edi");
+ &pop("esi");
+ &ret();
+ &function_end_B($name);
+ }
+
+1;
diff --git a/openssl/trunk/crypto/bn/asm/x86/div.pl b/openssl/trunk/crypto/bn/asm/x86/div.pl
new file mode 100644
index 00000000..0e90152c
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86/div.pl
@@ -0,0 +1,15 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_div_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+ &mov("edx",&wparam(0)); #
+ &mov("eax",&wparam(1)); #
+ &mov("ebx",&wparam(2)); #
+ &div("ebx");
+ &function_end($name);
+ }
+1;
diff --git a/openssl/trunk/crypto/bn/asm/x86/f b/openssl/trunk/crypto/bn/asm/x86/f
new file mode 100644
index 00000000..22e41122
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86/f
@@ -0,0 +1,3 @@
+#!/usr/local/bin/perl
+# x86 assember
+
diff --git a/openssl/trunk/crypto/bn/asm/x86/mul.pl b/openssl/trunk/crypto/bn/asm/x86/mul.pl
new file mode 100644
index 00000000..674cb9b0
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86/mul.pl
@@ -0,0 +1,77 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_mul_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $Low="eax";
+ $High="edx";
+ $a="ebx";
+ $w="ecx";
+ $r="edi";
+ $c="esi";
+ $num="ebp";
+
+ &xor($c,$c); # clear carry
+ &mov($r,&wparam(0)); #
+ &mov($a,&wparam(1)); #
+ &mov($num,&wparam(2)); #
+ &mov($w,&wparam(3)); #
+
+ &and($num,0xfffffff8); # num / 8
+ &jz(&label("mw_finish"));
+
+ &set_label("mw_loop",0);
+ for ($i=0; $i<32; $i+=4)
+ {
+ &comment("Round $i");
+
+ &mov("eax",&DWP($i,$a,"",0)); # *a
+ &mul($w); # *a * w
+ &add("eax",$c); # L(t)+=c
+ # XXX
+
+ &adc("edx",0); # H(t)+=carry
+ &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t);
+
+ &mov($c,"edx"); # c= H(t);
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($r,32);
+ &sub($num,8);
+ &jz(&label("mw_finish"));
+ &jmp(&label("mw_loop"));
+
+ &set_label("mw_finish",0);
+ &mov($num,&wparam(2)); # get num
+ &and($num,7);
+ &jnz(&label("mw_finish2"));
+ &jmp(&label("mw_end"));
+
+ &set_label("mw_finish2",1);
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov("eax",&DWP($i*4,$a,"",0));# *a
+ &mul($w); # *a * w
+ &add("eax",$c); # L(t)+=c
+ # XXX
+ &adc("edx",0); # H(t)+=carry
+ &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t);
+ &mov($c,"edx"); # c= H(t);
+ &dec($num) if ($i != 7-1);
+ &jz(&label("mw_end")) if ($i != 7-1);
+ }
+ &set_label("mw_end",0);
+ &mov("eax",$c);
+
+ &function_end($name);
+ }
+
+1;
diff --git a/openssl/trunk/crypto/bn/asm/x86/mul_add.pl b/openssl/trunk/crypto/bn/asm/x86/mul_add.pl
new file mode 100644
index 00000000..61830d3a
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86/mul_add.pl
@@ -0,0 +1,87 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_mul_add_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $Low="eax";
+ $High="edx";
+ $a="ebx";
+ $w="ebp";
+ $r="edi";
+ $c="esi";
+
+ &xor($c,$c); # clear carry
+ &mov($r,&wparam(0)); #
+
+ &mov("ecx",&wparam(2)); #
+ &mov($a,&wparam(1)); #
+
+ &and("ecx",0xfffffff8); # num / 8
+ &mov($w,&wparam(3)); #
+
+ &push("ecx"); # Up the stack for a tmp variable
+
+ &jz(&label("maw_finish"));
+
+ &set_label("maw_loop",0);
+
+ &mov(&swtmp(0),"ecx"); #
+
+ for ($i=0; $i<32; $i+=4)
+ {
+ &comment("Round $i");
+
+ &mov("eax",&DWP($i,$a,"",0)); # *a
+ &mul($w); # *a * w
+ &add("eax",$c); # L(t)+= *r
+ &mov($c,&DWP($i,$r,"",0)); # L(t)+= *r
+ &adc("edx",0); # H(t)+=carry
+ &add("eax",$c); # L(t)+=c
+ &adc("edx",0); # H(t)+=carry
+ &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t);
+ &mov($c,"edx"); # c= H(t);
+ }
+
+ &comment("");
+ &mov("ecx",&swtmp(0)); #
+ &add($a,32);
+ &add($r,32);
+ &sub("ecx",8);
+ &jnz(&label("maw_loop"));
+
+ &set_label("maw_finish",0);
+ &mov("ecx",&wparam(2)); # get num
+ &and("ecx",7);
+ &jnz(&label("maw_finish2")); # helps branch prediction
+ &jmp(&label("maw_end"));
+
+ &set_label("maw_finish2",1);
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov("eax",&DWP($i*4,$a,"",0));# *a
+ &mul($w); # *a * w
+ &add("eax",$c); # L(t)+=c
+ &mov($c,&DWP($i*4,$r,"",0)); # L(t)+= *r
+ &adc("edx",0); # H(t)+=carry
+ &add("eax",$c);
+ &adc("edx",0); # H(t)+=carry
+ &dec("ecx") if ($i != 7-1);
+ &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t);
+ &mov($c,"edx"); # c= H(t);
+ &jz(&label("maw_end")) if ($i != 7-1);
+ }
+ &set_label("maw_end",0);
+ &mov("eax",$c);
+
+ &pop("ecx"); # clear variable from
+
+ &function_end($name);
+ }
+
+1;
diff --git a/openssl/trunk/crypto/bn/asm/x86/sqr.pl b/openssl/trunk/crypto/bn/asm/x86/sqr.pl
new file mode 100644
index 00000000..1f90993c
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86/sqr.pl
@@ -0,0 +1,60 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_sqr_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $r="esi";
+ $a="edi";
+ $num="ebx";
+
+ &mov($r,&wparam(0)); #
+ &mov($a,&wparam(1)); #
+ &mov($num,&wparam(2)); #
+
+ &and($num,0xfffffff8); # num / 8
+ &jz(&label("sw_finish"));
+
+ &set_label("sw_loop",0);
+ for ($i=0; $i<32; $i+=4)
+ {
+ &comment("Round $i");
+ &mov("eax",&DWP($i,$a,"",0)); # *a
+ # XXX
+ &mul("eax"); # *a * *a
+ &mov(&DWP($i*2,$r,"",0),"eax"); #
+ &mov(&DWP($i*2+4,$r,"",0),"edx");#
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($r,64);
+ &sub($num,8);
+ &jnz(&label("sw_loop"));
+
+ &set_label("sw_finish",0);
+ &mov($num,&wparam(2)); # get num
+ &and($num,7);
+ &jz(&label("sw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov("eax",&DWP($i*4,$a,"",0)); # *a
+ # XXX
+ &mul("eax"); # *a * *a
+ &mov(&DWP($i*8,$r,"",0),"eax"); #
+ &dec($num) if ($i != 7-1);
+ &mov(&DWP($i*8+4,$r,"",0),"edx");
+ &jz(&label("sw_end")) if ($i != 7-1);
+ }
+ &set_label("sw_end",0);
+
+ &function_end($name);
+ }
+
+1;
diff --git a/openssl/trunk/crypto/bn/asm/x86/sub.pl b/openssl/trunk/crypto/bn/asm/x86/sub.pl
new file mode 100644
index 00000000..837b0e1b
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86/sub.pl
@@ -0,0 +1,76 @@
+#!/usr/local/bin/perl
+# x86 assember
+
+sub bn_sub_words
+ {
+ local($name)=@_;
+
+ &function_begin($name,"");
+
+ &comment("");
+ $a="esi";
+ $b="edi";
+ $c="eax";
+ $r="ebx";
+ $tmp1="ecx";
+ $tmp2="edx";
+ $num="ebp";
+
+ &mov($r,&wparam(0)); # get r
+ &mov($a,&wparam(1)); # get a
+ &mov($b,&wparam(2)); # get b
+ &mov($num,&wparam(3)); # get num
+ &xor($c,$c); # clear carry
+ &and($num,0xfffffff8); # num / 8
+
+ &jz(&label("aw_finish"));
+
+ &set_label("aw_loop",0);
+ for ($i=0; $i<8; $i++)
+ {
+ &comment("Round $i");
+
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0)); # *b
+ &sub($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &sub($tmp1,$tmp2);
+ &adc($c,0);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *r
+ }
+
+ &comment("");
+ &add($a,32);
+ &add($b,32);
+ &add($r,32);
+ &sub($num,8);
+ &jnz(&label("aw_loop"));
+
+ &set_label("aw_finish",0);
+ &mov($num,&wparam(3)); # get num
+ &and($num,7);
+ &jz(&label("aw_end"));
+
+ for ($i=0; $i<7; $i++)
+ {
+ &comment("Tail Round $i");
+ &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
+ &mov($tmp2,&DWP($i*4,$b,"",0));# *b
+ &sub($tmp1,$c);
+ &mov($c,0);
+ &adc($c,$c);
+ &sub($tmp1,$tmp2);
+ &adc($c,0);
+ &dec($num) if ($i != 6);
+ &mov(&DWP($i*4,$r,"",0),$tmp1); # *a
+ &jz(&label("aw_end")) if ($i != 6);
+ }
+ &set_label("aw_end",0);
+
+# &mov("eax",$c); # $c is "eax"
+
+ &function_end($name);
+ }
+
+1;
diff --git a/openssl/trunk/crypto/bn/asm/x86_64-gcc.c b/openssl/trunk/crypto/bn/asm/x86_64-gcc.c
new file mode 100644
index 00000000..73783442
--- /dev/null
+++ b/openssl/trunk/crypto/bn/asm/x86_64-gcc.c
@@ -0,0 +1,593 @@
+/*
+ * x86_64 BIGNUM accelerator version 0.1, December 2002.
+ *
+ * Implemented by Andy Polyakov <appro@fy.chalmers.se> for the OpenSSL
+ * project.
+ *
+ * Rights for redistribution and usage in source and binary forms are
+ * granted according to the OpenSSL license. Warranty of any kind is
+ * disclaimed.
+ *
+ * Q. Version 0.1? It doesn't sound like Andy, he used to assign real
+ * versions, like 1.0...
+ * A. Well, that's because this code is basically a quick-n-dirty
+ * proof-of-concept hack. As you can see it's implemented with
+ * inline assembler, which means that you're bound to GCC and that
+ * there might be enough room for further improvement.
+ *
+ * Q. Why inline assembler?
+ * A. x86_64 features own ABI which I'm not familiar with. This is
+ * why I decided to let the compiler take care of subroutine
+ * prologue/epilogue as well as register allocation. For reference.
+ * Win64 implements different ABI for AMD64, different from Linux.
+ *
+ * Q. How much faster does it get?
+ * A. 'apps/openssl speed rsa dsa' output with no-asm:
+ *
+ * sign verify sign/s verify/s
+ * rsa 512 bits 0.0006s 0.0001s 1683.8 18456.2
+ * rsa 1024 bits 0.0028s 0.0002s 356.0 6407.0
+ * rsa 2048 bits 0.0172s 0.0005s 58.0 1957.8
+ * rsa 4096 bits 0.1155s 0.0018s 8.7 555.6
+ * sign verify sign/s verify/s
+ * dsa 512 bits 0.0005s 0.0006s 2100.8 1768.3
+ * dsa 1024 bits 0.0014s 0.0018s 692.3 559.2
+ * dsa 2048 bits 0.0049s 0.0061s 204.7 165.0
+ *
+ * 'apps/openssl speed rsa dsa' output with this module:
+ *
+ * sign verify sign/s verify/s
+ * rsa 512 bits 0.0004s 0.0000s 2767.1 33297.9
+ * rsa 1024 bits 0.0012s 0.0001s 867.4 14674.7
+ * rsa 2048 bits 0.0061s 0.0002s 164.0 5270.0
+ * rsa 4096 bits 0.0384s 0.0006s 26.1 1650.8
+ * sign verify sign/s verify/s
+ * dsa 512 bits 0.0002s 0.0003s 4442.2 3786.3
+ * dsa 1024 bits 0.0005s 0.0007s 1835.1 1497.4
+ * dsa 2048 bits 0.0016s 0.0020s 620.4 504.6
+ *
+ * For the reference. IA-32 assembler implementation performs
+ * very much like 64-bit code compiled with no-asm on the same
+ * machine.
+ */
+
+#define BN_ULONG unsigned long
+
+/*
+ * "m"(a), "+m"(r) is the way to favor DirectPath µ-code;
+ * "g"(0) let the compiler to decide where does it
+ * want to keep the value of zero;
+ */
+#define mul_add(r,a,word,carry) do { \
+ register BN_ULONG high,low; \
+ asm ("mulq %3" \
+ : "=a"(low),"=d"(high) \
+ : "a"(word),"m"(a) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+r"(carry),"+d"(high)\
+ : "a"(low),"g"(0) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+m"(r),"+d"(high) \
+ : "r"(carry),"g"(0) \
+ : "cc"); \
+ carry=high; \
+ } while (0)
+
+#define mul(r,a,word,carry) do { \
+ register BN_ULONG high,low; \
+ asm ("mulq %3" \
+ : "=a"(low),"=d"(high) \
+ : "a"(word),"g"(a) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+r"(carry),"+d"(high)\
+ : "a"(low),"g"(0) \
+ : "cc"); \
+ (r)=carry, carry=high; \
+ } while (0)
+
+#define sqr(r0,r1,a) \
+ asm ("mulq %2" \
+ : "=a"(r0),"=d"(r1) \
+ : "a"(a) \
+ : "cc");
+
+BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG c1=0;
+
+ if (num <= 0) return(c1);
+
+ while (num&~3)
+ {
+ mul_add(rp[0],ap[0],w,c1);
+ mul_add(rp[1],ap[1],w,c1);
+ mul_add(rp[2],ap[2],w,c1);
+ mul_add(rp[3],ap[3],w,c1);
+ ap+=4; rp+=4; num-=4;
+ }
+ if (num)
+ {
+ mul_add(rp[0],ap[0],w,c1); if (--num==0) return c1;
+ mul_add(rp[1],ap[1],w,c1); if (--num==0) return c1;
+ mul_add(rp[2],ap[2],w,c1); return c1;
+ }
+
+ return(c1);
+ }
+
+BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w)
+ {
+ BN_ULONG c1=0;
+
+ if (num <= 0) return(c1);
+
+ while (num&~3)
+ {
+ mul(rp[0],ap[0],w,c1);
+ mul(rp[1],ap[1],w,c1);
+ mul(rp[2],ap[2],w,c1);
+ mul(rp[3],ap[3],w,c1);
+ ap+=4; rp+=4; num-=4;
+ }
+ if (num)
+ {
+ mul(rp[0],ap[0],w,c1); if (--num == 0) return c1;
+ mul(rp[1],ap[1],w,c1); if (--num == 0) return c1;
+ mul(rp[2],ap[2],w,c1);
+ }
+ return(c1);
+ }
+
+void bn_sqr_words(BN_ULONG *r, BN_ULONG *a, int n)
+ {
+ if (n <= 0) return;
+
+ while (n&~3)
+ {
+ sqr(r[0],r[1],a[0]);
+ sqr(r[2],r[3],a[1]);
+ sqr(r[4],r[5],a[2]);
+ sqr(r[6],r[7],a[3]);
+ a+=4; r+=8; n-=4;
+ }
+ if (n)
+ {
+ sqr(r[0],r[1],a[0]); if (--n == 0) return;
+ sqr(r[2],r[3],a[1]); if (--n == 0) return;
+ sqr(r[4],r[5],a[2]);
+ }
+ }
+
+BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
+{ BN_ULONG ret,waste;
+
+ asm ("divq %4"
+ : "=a"(ret),"=d"(waste)
+ : "a"(l),"d"(h),"g"(d)
+ : "cc");
+
+ return ret;
+}
+
+BN_ULONG bn_add_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n)
+{ BN_ULONG ret=0,i=0;
+
+ if (n <= 0) return 0;
+
+ asm (
+ " subq %2,%2 \n"
+ ".align 16 \n"
+ "1: movq (%4,%2,8),%0 \n"
+ " adcq (%5,%2,8),%0 \n"
+ " movq %0,(%3,%2,8) \n"
+ " leaq 1(%2),%2 \n"
+ " loop 1b \n"
+ " sbbq %0,%0 \n"
+ : "=&a"(ret),"+c"(n),"=&r"(i)
+ : "r"(rp),"r"(ap),"r"(bp)
+ : "cc"
+ );
+
+ return ret&1;
+}
+
+#ifndef SIMICS
+BN_ULONG bn_sub_words (BN_ULONG *rp, BN_ULONG *ap, BN_ULONG *bp,int n)
+{ BN_ULONG ret=0,i=0;
+
+ if (n <= 0) return 0;
+
+ asm (
+ " subq %2,%2 \n"
+ ".align 16 \n"
+ "1: movq (%4,%2,8),%0 \n"
+ " sbbq (%5,%2,8),%0 \n"
+ " movq %0,(%3,%2,8) \n"
+ " leaq 1(%2),%2 \n"
+ " loop 1b \n"
+ " sbbq %0,%0 \n"
+ : "=&a"(ret),"+c"(n),"=&r"(i)
+ : "r"(rp),"r"(ap),"r"(bp)
+ : "cc"
+ );
+
+ return ret&1;
+}
+#else
+/* Simics 1.4<7 has buggy sbbq:-( */
+#define BN_MASK2 0xffffffffffffffffL
+BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n)
+ {
+ BN_ULONG t1,t2;
+ int c=0;
+
+ if (n <= 0) return((BN_ULONG)0);
+
+ for (;;)
+ {
+ t1=a[0]; t2=b[0];
+ r[0]=(t1-t2-c)&BN_MASK2;
+ if (t1 != t2) c=(t1 < t2);
+ if (--n <= 0) break;
+
+ t1=a[1]; t2=b[1];
+ r[1]=(t1-t2-c)&BN_MASK2;
+ if (t1 != t2) c=(t1 < t2);
+ if (--n <= 0) break;
+
+ t1=a[2]; t2=b[2];
+ r[2]=(t1-t2-c)&BN_MASK2;
+ if (t1 != t2) c=(t1 < t2);
+ if (--n <= 0) break;
+
+ t1=a[3]; t2=b[3];
+ r[3]=(t1-t2-c)&BN_MASK2;
+ if (t1 != t2) c=(t1 < t2);
+ if (--n <= 0) break;
+
+ a+=4;
+ b+=4;
+ r+=4;
+ }
+ return(c);
+ }
+#endif
+
+/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */
+/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */
+/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */
+/* sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number c=(c2,c1,c0) */
+
+#if 0
+/* original macros are kept for reference purposes */
+#define mul_add_c(a,b,c0,c1,c2) { \
+ BN_ULONG ta=(a),tb=(b); \
+ t1 = ta * tb; \
+ t2 = BN_UMULT_HIGH(ta,tb); \
+ c0 += t1; t2 += (c0<t1)?1:0; \
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ }
+
+#define mul_add_c2(a,b,c0,c1,c2) { \
+ BN_ULONG ta=(a),tb=(b),t0; \
+ t1 = BN_UMULT_HIGH(ta,tb); \
+ t0 = ta * tb; \
+ t2 = t1+t1; c2 += (t2<t1)?1:0; \
+ t1 = t0+t0; t2 += (t1<t0)?1:0; \
+ c0 += t1; t2 += (c0<t1)?1:0; \
+ c1 += t2; c2 += (c1<t2)?1:0; \
+ }
+#else
+#define mul_add_c(a,b,c0,c1,c2) do { \
+ asm ("mulq %3" \
+ : "=a"(t1),"=d"(t2) \
+ : "a"(a),"m"(b) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+r"(c0),"+d"(t2) \
+ : "a"(t1),"g"(0) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+r"(c1),"+r"(c2) \
+ : "d"(t2),"g"(0) \
+ : "cc"); \
+ } while (0)
+
+#define sqr_add_c(a,i,c0,c1,c2) do { \
+ asm ("mulq %2" \
+ : "=a"(t1),"=d"(t2) \
+ : "a"(a[i]) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+r"(c0),"+d"(t2) \
+ : "a"(t1),"g"(0) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+r"(c1),"+r"(c2) \
+ : "d"(t2),"g"(0) \
+ : "cc"); \
+ } while (0)
+
+#define mul_add_c2(a,b,c0,c1,c2) do { \
+ asm ("mulq %3" \
+ : "=a"(t1),"=d"(t2) \
+ : "a"(a),"m"(b) \
+ : "cc"); \
+ asm ("addq %0,%0; adcq %2,%1" \
+ : "+d"(t2),"+r"(c2) \
+ : "g"(0) \
+ : "cc"); \
+ asm ("addq %0,%0; adcq %2,%1" \
+ : "+a"(t1),"+d"(t2) \
+ : "g"(0) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+r"(c0),"+d"(t2) \
+ : "a"(t1),"g"(0) \
+ : "cc"); \
+ asm ("addq %2,%0; adcq %3,%1" \
+ : "+r"(c1),"+r"(c2) \
+ : "d"(t2),"g"(0) \
+ : "cc"); \
+ } while (0)
+#endif
+
+#define sqr_add_c2(a,i,j,c0,c1,c2) \
+ mul_add_c2((a)[i],(a)[j],c0,c1,c2)
+
+void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+ {
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ mul_add_c(a[0],b[0],c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ mul_add_c(a[0],b[1],c2,c3,c1);
+ mul_add_c(a[1],b[0],c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ mul_add_c(a[2],b[0],c3,c1,c2);
+ mul_add_c(a[1],b[1],c3,c1,c2);
+ mul_add_c(a[0],b[2],c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ mul_add_c(a[0],b[3],c1,c2,c3);
+ mul_add_c(a[1],b[2],c1,c2,c3);
+ mul_add_c(a[2],b[1],c1,c2,c3);
+ mul_add_c(a[3],b[0],c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ mul_add_c(a[4],b[0],c2,c3,c1);
+ mul_add_c(a[3],b[1],c2,c3,c1);
+ mul_add_c(a[2],b[2],c2,c3,c1);
+ mul_add_c(a[1],b[3],c2,c3,c1);
+ mul_add_c(a[0],b[4],c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ mul_add_c(a[0],b[5],c3,c1,c2);
+ mul_add_c(a[1],b[4],c3,c1,c2);
+ mul_add_c(a[2],b[3],c3,c1,c2);
+ mul_add_c(a[3],b[2],c3,c1,c2);
+ mul_add_c(a[4],b[1],c3,c1,c2);
+ mul_add_c(a[5],b[0],c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ mul_add_c(a[6],b[0],c1,c2,c3);
+ mul_add_c(a[5],b[1],c1,c2,c3);
+ mul_add_c(a[4],b[2],c1,c2,c3);
+ mul_add_c(a[3],b[3],c1,c2,c3);
+ mul_add_c(a[2],b[4],c1,c2,c3);
+ mul_add_c(a[1],b[5],c1,c2,c3);
+ mul_add_c(a[0],b[6],c1,c2,c3);
+ r[6]=c1;
+ c1=0;
+ mul_add_c(a[0],b[7],c2,c3,c1);
+ mul_add_c(a[1],b[6],c2,c3,c1);
+ mul_add_c(a[2],b[5],c2,c3,c1);
+ mul_add_c(a[3],b[4],c2,c3,c1);
+ mul_add_c(a[4],b[3],c2,c3,c1);
+ mul_add_c(a[5],b[2],c2,c3,c1);
+ mul_add_c(a[6],b[1],c2,c3,c1);
+ mul_add_c(a[7],b[0],c2,c3,c1);
+ r[7]=c2;
+ c2=0;
+ mul_add_c(a[7],b[1],c3,c1,c2);
+ mul_add_c(a[6],b[2],c3,c1,c2);
+ mul_add_c(a[5],b[3],c3,c1,c2);
+ mul_add_c(a[4],b[4],c3,c1,c2);
+ mul_add_c(a[3],b[5],c3,c1,c2);
+ mul_add_c(a[2],b[6],c3,c1,c2);
+ mul_add_c(a[1],b[7],c3,c1,c2);
+ r[8]=c3;
+ c3=0;
+ mul_add_c(a[2],b[7],c1,c2,c3);
+ mul_add_c(a[3],b[6],c1,c2,c3);
+ mul_add_c(a[4],b[5],c1,c2,c3);
+ mul_add_c(a[5],b[4],c1,c2,c3);
+ mul_add_c(a[6],b[3],c1,c2,c3);
+ mul_add_c(a[7],b[2],c1,c2,c3);
+ r[9]=c1;
+ c1=0;
+ mul_add_c(a[7],b[3],c2,c3,c1);
+ mul_add_c(a[6],b[4],c2,c3,c1);
+ mul_add_c(a[5],b[5],c2,c3,c1);
+ mul_add_c(a[4],b[6],c2,c3,c1);
+ mul_add_c(a[3],b[7],c2,c3,c1);
+ r[10]=c2;
+ c2=0;
+ mul_add_c(a[4],b[7],c3,c1,c2);
+ mul_add_c(a[5],b[6],c3,c1,c2);
+ mul_add_c(a[6],b[5],c3,c1,c2);
+ mul_add_c(a[7],b[4],c3,c1,c2);
+ r[11]=c3;
+ c3=0;
+ mul_add_c(a[7],b[5],c1,c2,c3);
+ mul_add_c(a[6],b[6],c1,c2,c3);
+ mul_add_c(a[5],b[7],c1,c2,c3);
+ r[12]=c1;
+ c1=0;
+ mul_add_c(a[6],b[7],c2,c3,c1);
+ mul_add_c(a[7],b[6],c2,c3,c1);
+ r[13]=c2;
+ c2=0;
+ mul_add_c(a[7],b[7],c3,c1,c2);
+ r[14]=c3;
+ r[15]=c1;
+ }
+
+void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b)
+ {
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ mul_add_c(a[0],b[0],c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ mul_add_c(a[0],b[1],c2,c3,c1);
+ mul_add_c(a[1],b[0],c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ mul_add_c(a[2],b[0],c3,c1,c2);
+ mul_add_c(a[1],b[1],c3,c1,c2);
+ mul_add_c(a[0],b[2],c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ mul_add_c(a[0],b[3],c1,c2,c3);
+ mul_add_c(a[1],b[2],c1,c2,c3);
+ mul_add_c(a[2],b[1],c1,c2,c3);
+ mul_add_c(a[3],b[0],c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ mul_add_c(a[3],b[1],c2,c3,c1);
+ mul_add_c(a[2],b[2],c2,c3,c1);
+ mul_add_c(a[1],b[3],c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ mul_add_c(a[2],b[3],c3,c1,c2);
+ mul_add_c(a[3],b[2],c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ mul_add_c(a[3],b[3],c1,c2,c3);
+ r[6]=c1;
+ r[7]=c2;
+ }
+
+void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a)
+ {
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ sqr_add_c(a,0,c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ sqr_add_c2(a,1,0,c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ sqr_add_c(a,1,c3,c1,c2);
+ sqr_add_c2(a,2,0,c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ sqr_add_c2(a,3,0,c1,c2,c3);
+ sqr_add_c2(a,2,1,c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ sqr_add_c(a,2,c2,c3,c1);
+ sqr_add_c2(a,3,1,c2,c3,c1);
+ sqr_add_c2(a,4,0,c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ sqr_add_c2(a,5,0,c3,c1,c2);
+ sqr_add_c2(a,4,1,c3,c1,c2);
+ sqr_add_c2(a,3,2,c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ sqr_add_c(a,3,c1,c2,c3);
+ sqr_add_c2(a,4,2,c1,c2,c3);
+ sqr_add_c2(a,5,1,c1,c2,c3);
+ sqr_add_c2(a,6,0,c1,c2,c3);
+ r[6]=c1;
+ c1=0;
+ sqr_add_c2(a,7,0,c2,c3,c1);
+ sqr_add_c2(a,6,1,c2,c3,c1);
+ sqr_add_c2(a,5,2,c2,c3,c1);
+ sqr_add_c2(a,4,3,c2,c3,c1);
+ r[7]=c2;
+ c2=0;
+ sqr_add_c(a,4,c3,c1,c2);
+ sqr_add_c2(a,5,3,c3,c1,c2);
+ sqr_add_c2(a,6,2,c3,c1,c2);
+ sqr_add_c2(a,7,1,c3,c1,c2);
+ r[8]=c3;
+ c3=0;
+ sqr_add_c2(a,7,2,c1,c2,c3);
+ sqr_add_c2(a,6,3,c1,c2,c3);
+ sqr_add_c2(a,5,4,c1,c2,c3);
+ r[9]=c1;
+ c1=0;
+ sqr_add_c(a,5,c2,c3,c1);
+ sqr_add_c2(a,6,4,c2,c3,c1);
+ sqr_add_c2(a,7,3,c2,c3,c1);
+ r[10]=c2;
+ c2=0;
+ sqr_add_c2(a,7,4,c3,c1,c2);
+ sqr_add_c2(a,6,5,c3,c1,c2);
+ r[11]=c3;
+ c3=0;
+ sqr_add_c(a,6,c1,c2,c3);
+ sqr_add_c2(a,7,5,c1,c2,c3);
+ r[12]=c1;
+ c1=0;
+ sqr_add_c2(a,7,6,c2,c3,c1);
+ r[13]=c2;
+ c2=0;
+ sqr_add_c(a,7,c3,c1,c2);
+ r[14]=c3;
+ r[15]=c1;
+ }
+
+void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a)
+ {
+ BN_ULONG t1,t2;
+ BN_ULONG c1,c2,c3;
+
+ c1=0;
+ c2=0;
+ c3=0;
+ sqr_add_c(a,0,c1,c2,c3);
+ r[0]=c1;
+ c1=0;
+ sqr_add_c2(a,1,0,c2,c3,c1);
+ r[1]=c2;
+ c2=0;
+ sqr_add_c(a,1,c3,c1,c2);
+ sqr_add_c2(a,2,0,c3,c1,c2);
+ r[2]=c3;
+ c3=0;
+ sqr_add_c2(a,3,0,c1,c2,c3);
+ sqr_add_c2(a,2,1,c1,c2,c3);
+ r[3]=c1;
+ c1=0;
+ sqr_add_c(a,2,c2,c3,c1);
+ sqr_add_c2(a,3,1,c2,c3,c1);
+ r[4]=c2;
+ c2=0;
+ sqr_add_c2(a,3,2,c3,c1,c2);
+ r[5]=c3;
+ c3=0;
+ sqr_add_c(a,3,c1,c2,c3);
+ r[6]=c1;
+ r[7]=c2;
+ }