155714Skris#!/usr/local/bin/perl
255714Skris# x86 assember
355714Skris
455714Skrissub mul_add_c
555714Skris	{
655714Skris	local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
755714Skris
855714Skris	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
955714Skris	# words, and 1 if load return value
1055714Skris
1155714Skris	&comment("mul a[$ai]*b[$bi]");
1255714Skris
1355714Skris	# "eax" and "edx" will always be pre-loaded.
1455714Skris	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
1555714Skris	# &mov("edx",&DWP($bi*4,$b,"",0));
1655714Skris
1755714Skris	&mul("edx");
1855714Skris	&add($c0,"eax");
1955714Skris	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# laod next a
2055714Skris	 &mov("eax",&wparam(0)) if $pos > 0;			# load r[]
2155714Skris	 ###
2255714Skris	&adc($c1,"edx");
2355714Skris	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0;	# laod next b
2455714Skris	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;	# laod next b
2555714Skris	 ###
2655714Skris	&adc($c2,0);
2755714Skris	 # is pos > 1, it means it is the last loop
2855714Skris	 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0;		# save r[];
2955714Skris	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# laod next a
3055714Skris	}
3155714Skris
3255714Skrissub sqr_add_c
3355714Skris	{
3455714Skris	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
3555714Skris
3655714Skris	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
3755714Skris	# words, and 1 if load return value
3855714Skris
3955714Skris	&comment("sqr a[$ai]*a[$bi]");
4055714Skris
4155714Skris	# "eax" and "edx" will always be pre-loaded.
4255714Skris	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
4355714Skris	# &mov("edx",&DWP($bi*4,$b,"",0));
4455714Skris
4555714Skris	if ($ai == $bi)
4655714Skris		{ &mul("eax");}
4755714Skris	else
4855714Skris		{ &mul("edx");}
4955714Skris	&add($c0,"eax");
5055714Skris	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
5155714Skris	 ###
5255714Skris	&adc($c1,"edx");
5355714Skris	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
5455714Skris	 ###
5555714Skris	&adc($c2,0);
5655714Skris	 # is pos > 1, it means it is the last loop
5755714Skris	 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
5855714Skris	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next b
5955714Skris	}
6055714Skris
6155714Skrissub sqr_add_c2
6255714Skris	{
6355714Skris	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
6455714Skris
6555714Skris	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
6655714Skris	# words, and 1 if load return value
6755714Skris
6855714Skris	&comment("sqr a[$ai]*a[$bi]");
6955714Skris
7055714Skris	# "eax" and "edx" will always be pre-loaded.
7155714Skris	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
7255714Skris	# &mov("edx",&DWP($bi*4,$a,"",0));
7355714Skris
7455714Skris	if ($ai == $bi)
7555714Skris		{ &mul("eax");}
7655714Skris	else
7755714Skris		{ &mul("edx");}
7855714Skris	&add("eax","eax");
7955714Skris	 ###
8055714Skris	&adc("edx","edx");
8155714Skris	 ###
8255714Skris	&adc($c2,0);
8355714Skris	 &add($c0,"eax");
8455714Skris	&adc($c1,"edx");
8555714Skris	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
8655714Skris	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;	# load next b
8755714Skris	&adc($c2,0);
8855714Skris	&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
8955714Skris	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
9055714Skris	 ###
9155714Skris	}
9255714Skris
9355714Skrissub bn_mul_comba
9455714Skris	{
9555714Skris	local($name,$num)=@_;
9655714Skris	local($a,$b,$c0,$c1,$c2);
9755714Skris	local($i,$as,$ae,$bs,$be,$ai,$bi);
9855714Skris	local($tot,$end);
9955714Skris
10055714Skris	&function_begin_B($name,"");
10155714Skris
10255714Skris	$c0="ebx";
10355714Skris	$c1="ecx";
10455714Skris	$c2="ebp";
10555714Skris	$a="esi";
10655714Skris	$b="edi";
10755714Skris
10855714Skris	$as=0;
10955714Skris	$ae=0;
11055714Skris	$bs=0;
11155714Skris	$be=0;
11255714Skris	$tot=$num+$num-1;
11355714Skris
11455714Skris	&push("esi");
11555714Skris	 &mov($a,&wparam(1));
11655714Skris	&push("edi");
11755714Skris	 &mov($b,&wparam(2));
11855714Skris	&push("ebp");
11955714Skris	 &push("ebx");
12055714Skris
12155714Skris	&xor($c0,$c0);
12255714Skris	 &mov("eax",&DWP(0,$a,"",0));	# load the first word
12355714Skris	&xor($c1,$c1);
12455714Skris	 &mov("edx",&DWP(0,$b,"",0));	# load the first second
12555714Skris
12655714Skris	for ($i=0; $i<$tot; $i++)
12755714Skris		{
12855714Skris		$ai=$as;
12955714Skris		$bi=$bs;
13055714Skris		$end=$be+1;
13155714Skris
13255714Skris		&comment("################## Calculate word $i");
13355714Skris
13455714Skris		for ($j=$bs; $j<$end; $j++)
13555714Skris			{
13655714Skris			&xor($c2,$c2) if ($j == $bs);
13755714Skris			if (($j+1) == $end)
13855714Skris				{
13955714Skris				$v=1;
14055714Skris				$v=2 if (($i+1) == $tot);
14155714Skris				}
14255714Skris			else
14355714Skris				{ $v=0; }
14455714Skris			if (($j+1) != $end)
14555714Skris				{
14655714Skris				$na=($ai-1);
14755714Skris				$nb=($bi+1);
14855714Skris				}
14955714Skris			else
15055714Skris				{
15155714Skris				$na=$as+($i < ($num-1));
15255714Skris				$nb=$bs+($i >= ($num-1));
15355714Skris				}
15455714Skris#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
15555714Skris			&mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
15655714Skris			if ($v)
15755714Skris				{
15855714Skris				&comment("saved r[$i]");
15955714Skris				# &mov("eax",&wparam(0));
16055714Skris				# &mov(&DWP($i*4,"eax","",0),$c0);
16155714Skris				($c0,$c1,$c2)=($c1,$c2,$c0);
16255714Skris				}
16355714Skris			$ai--;
16455714Skris			$bi++;
16555714Skris			}
16655714Skris		$as++ if ($i < ($num-1));
16755714Skris		$ae++ if ($i >= ($num-1));
16855714Skris
16955714Skris		$bs++ if ($i >= ($num-1));
17055714Skris		$be++ if ($i < ($num-1));
17155714Skris		}
17255714Skris	&comment("save r[$i]");
17355714Skris	# &mov("eax",&wparam(0));
17455714Skris	&mov(&DWP($i*4,"eax","",0),$c0);
17555714Skris
17655714Skris	&pop("ebx");
17755714Skris	&pop("ebp");
17855714Skris	&pop("edi");
17955714Skris	&pop("esi");
18055714Skris	&ret();
18155714Skris	&function_end_B($name);
18255714Skris	}
18355714Skris
18455714Skrissub bn_sqr_comba
18555714Skris	{
18655714Skris	local($name,$num)=@_;
18755714Skris	local($r,$a,$c0,$c1,$c2)=@_;
18855714Skris	local($i,$as,$ae,$bs,$be,$ai,$bi);
18955714Skris	local($b,$tot,$end,$half);
19055714Skris
19155714Skris	&function_begin_B($name,"");
19255714Skris
19355714Skris	$c0="ebx";
19455714Skris	$c1="ecx";
19555714Skris	$c2="ebp";
19655714Skris	$a="esi";
19755714Skris	$r="edi";
19855714Skris
19955714Skris	&push("esi");
20055714Skris	 &push("edi");
20155714Skris	&push("ebp");
20255714Skris	 &push("ebx");
20355714Skris	&mov($r,&wparam(0));
20455714Skris	 &mov($a,&wparam(1));
20555714Skris	&xor($c0,$c0);
20655714Skris	 &xor($c1,$c1);
20755714Skris	&mov("eax",&DWP(0,$a,"",0)); # load the first word
20855714Skris
20955714Skris	$as=0;
21055714Skris	$ae=0;
21155714Skris	$bs=0;
21255714Skris	$be=0;
21355714Skris	$tot=$num+$num-1;
21455714Skris
21555714Skris	for ($i=0; $i<$tot; $i++)
21655714Skris		{
21755714Skris		$ai=$as;
21855714Skris		$bi=$bs;
21955714Skris		$end=$be+1;
22055714Skris
22155714Skris		&comment("############### Calculate word $i");
22255714Skris		for ($j=$bs; $j<$end; $j++)
22355714Skris			{
22455714Skris			&xor($c2,$c2) if ($j == $bs);
22555714Skris			if (($ai-1) < ($bi+1))
22655714Skris				{
22755714Skris				$v=1;
22855714Skris				$v=2 if ($i+1) == $tot;
22955714Skris				}
23055714Skris			else
23155714Skris				{ $v=0; }
23255714Skris			if (!$v)
23355714Skris				{
23455714Skris				$na=$ai-1;
23555714Skris				$nb=$bi+1;
23655714Skris				}
23755714Skris			else
23855714Skris				{
23955714Skris				$na=$as+($i < ($num-1));
24055714Skris				$nb=$bs+($i >= ($num-1));
24155714Skris				}
24255714Skris			if ($ai == $bi)
24355714Skris				{
24455714Skris				&sqr_add_c($r,$a,$ai,$bi,
24555714Skris					$c0,$c1,$c2,$v,$i,$na,$nb);
24655714Skris				}
24755714Skris			else
24855714Skris				{
24955714Skris				&sqr_add_c2($r,$a,$ai,$bi,
25055714Skris					$c0,$c1,$c2,$v,$i,$na,$nb);
25155714Skris				}
25255714Skris			if ($v)
25355714Skris				{
25455714Skris				&comment("saved r[$i]");
25555714Skris				#&mov(&DWP($i*4,$r,"",0),$c0);
25655714Skris				($c0,$c1,$c2)=($c1,$c2,$c0);
25755714Skris				last;
25855714Skris				}
25955714Skris			$ai--;
26055714Skris			$bi++;
26155714Skris			}
26255714Skris		$as++ if ($i < ($num-1));
26355714Skris		$ae++ if ($i >= ($num-1));
26455714Skris
26555714Skris		$bs++ if ($i >= ($num-1));
26655714Skris		$be++ if ($i < ($num-1));
26755714Skris		}
26855714Skris	&mov(&DWP($i*4,$r,"",0),$c0);
26955714Skris	&pop("ebx");
27055714Skris	&pop("ebp");
27155714Skris	&pop("edi");
27255714Skris	&pop("esi");
27355714Skris	&ret();
27455714Skris	&function_end_B($name);
27555714Skris	}
27655714Skris
27755714Skris1;
278