1c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#!/usr/local/bin/perl
2c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
3480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.org$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
4480da75abf485e7e2a6be5acc0f71842368792c0jnd@chromium.orgpush(@INC,"${dir}","${dir}../../perlasm");
5c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgrequire "x86asm.pl";
6c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
7c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org&asm_init($ARGV[0],$0);
8c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
9c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org&bn_mul_comba("bn_mul_comba8",8);
10c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org&bn_mul_comba("bn_mul_comba4",4);
11c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org&bn_sqr_comba("bn_sqr_comba8",8);
12c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org&bn_sqr_comba("bn_sqr_comba4",4);
13c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
14c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org&asm_finish();
15c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
16c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgsub mul_add_c
17c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
18c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
19c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
20c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
21c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# words, and 1 if load return value
22c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
23c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&comment("mul a[$ai]*b[$bi]");
24c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
25c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# "eax" and "edx" will always be pre-loaded.
26c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
27c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# &mov("edx",&DWP($bi*4,$b,"",0));
28c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
29c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&mul("edx");
30c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&add($c0,"eax");
31c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# laod next a
32c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("eax",&wparam(0)) if $pos > 0;			# load r[]
33c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 ###
34c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&adc($c1,"edx");
35c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0;	# laod next b
36c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;	# laod next b
37c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 ###
38c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&adc($c2,0);
39c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 # is pos > 1, it means it is the last loop
40c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0;		# save r[];
41c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# laod next a
42c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
43c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
44c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgsub sqr_add_c
45c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
46c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
47c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
48c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
49c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# words, and 1 if load return value
50c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
51c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&comment("sqr a[$ai]*a[$bi]");
52c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
53c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# "eax" and "edx" will always be pre-loaded.
54c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
55c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# &mov("edx",&DWP($bi*4,$b,"",0));
56c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
57c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if ($ai == $bi)
58c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{ &mul("eax");}
59c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
60c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{ &mul("edx");}
61c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&add($c0,"eax");
62c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
63c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 ###
64c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&adc($c1,"edx");
65c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb);
66c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 ###
67c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&adc($c2,0);
68c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 # is pos > 1, it means it is the last loop
69c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
70c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;		# load next b
71c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
72c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
73c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgsub sqr_add_c2
74c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
75c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_;
76c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
77c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# pos == -1 if eax and edx are pre-loaded, 0 to load from next
78c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# words, and 1 if load return value
79c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
80c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&comment("sqr a[$ai]*a[$bi]");
81c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
82c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# "eax" and "edx" will always be pre-loaded.
83c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# &mov("eax",&DWP($ai*4,$a,"",0)) ;
84c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# &mov("edx",&DWP($bi*4,$a,"",0));
85c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
86c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	if ($ai == $bi)
87c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{ &mul("eax");}
88c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	else
89c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{ &mul("edx");}
90c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&add("eax","eax");
91c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 ###
92c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&adc("edx","edx");
93c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 ###
94c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&adc($c2,0);
95c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &add($c0,"eax");
96c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&adc($c1,"edx");
97c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0;	# load next a
98c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1;	# load next b
99c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&adc($c2,0);
100c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0;		# save r[];
101c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb);
102c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 ###
103c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
104c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
105c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgsub bn_mul_comba
106c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
107c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($name,$num)=@_;
108c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($a,$b,$c0,$c1,$c2);
109c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($i,$as,$ae,$bs,$be,$ai,$bi);
110c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($tot,$end);
111c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
112c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&function_begin_B($name,"");
113c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
114c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$c0="ebx";
115c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$c1="ecx";
116c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$c2="ebp";
117c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$a="esi";
118c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$b="edi";
119c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
120c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$as=0;
121c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$ae=0;
122c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$bs=0;
123c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$be=0;
124c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$tot=$num+$num-1;
125c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
126c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&push("esi");
127c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov($a,&wparam(1));
128c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&push("edi");
129c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov($b,&wparam(2));
130c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&push("ebp");
131c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &push("ebx");
132c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
133c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&xor($c0,$c0);
134c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("eax",&DWP(0,$a,"",0));	# load the first word
135c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&xor($c1,$c1);
136c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov("edx",&DWP(0,$b,"",0));	# load the first second
137c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
138c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for ($i=0; $i<$tot; $i++)
139c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
140c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$ai=$as;
141c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$bi=$bs;
142c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$end=$be+1;
143c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
144c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		&comment("################## Calculate word $i");
145c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
146c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		for ($j=$bs; $j<$end; $j++)
147c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
148c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			&xor($c2,$c2) if ($j == $bs);
149c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (($j+1) == $end)
150c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
151c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$v=1;
152c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$v=2 if (($i+1) == $tot);
153c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
154c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
155c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{ $v=0; }
156c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (($j+1) != $end)
157c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
158c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$na=($ai-1);
159c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$nb=($bi+1);
160c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
161c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
162c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
163c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$na=$as+($i < ($num-1));
164c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$nb=$bs+($i >= ($num-1));
165c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
166c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org#printf STDERR "[$ai,$bi] -> [$na,$nb]\n";
167c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			&mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb);
168c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ($v)
169c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
170c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				&comment("saved r[$i]");
171c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				# &mov("eax",&wparam(0));
172c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				# &mov(&DWP($i*4,"eax","",0),$c0);
173c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				($c0,$c1,$c2)=($c1,$c2,$c0);
174c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
175c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			$ai--;
176c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			$bi++;
177c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
178c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$as++ if ($i < ($num-1));
179c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$ae++ if ($i >= ($num-1));
180c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
181c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$bs++ if ($i >= ($num-1));
182c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$be++ if ($i < ($num-1));
183c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
184c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&comment("save r[$i]");
185c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	# &mov("eax",&wparam(0));
186c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&mov(&DWP($i*4,"eax","",0),$c0);
187c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
188c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&pop("ebx");
189c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&pop("ebp");
190c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&pop("edi");
191c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&pop("esi");
192c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&ret();
193c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&function_end_B($name);
194c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
195c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
196c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.orgsub bn_sqr_comba
197c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	{
198c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($name,$num)=@_;
199c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($r,$a,$c0,$c1,$c2)=@_;
200c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($i,$as,$ae,$bs,$be,$ai,$bi);
201c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	local($b,$tot,$end,$half);
202c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
203c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&function_begin_B($name,"");
204c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
205c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$c0="ebx";
206c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$c1="ecx";
207c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$c2="ebp";
208c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$a="esi";
209c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$r="edi";
210c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
211c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&push("esi");
212c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &push("edi");
213c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&push("ebp");
214c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &push("ebx");
215c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&mov($r,&wparam(0));
216c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &mov($a,&wparam(1));
217c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&xor($c0,$c0);
218c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	 &xor($c1,$c1);
219c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&mov("eax",&DWP(0,$a,"",0)); # load the first word
220c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
221c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$as=0;
222c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$ae=0;
223c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$bs=0;
224c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$be=0;
225c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	$tot=$num+$num-1;
226c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
227c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	for ($i=0; $i<$tot; $i++)
228c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		{
229c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$ai=$as;
230c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$bi=$bs;
231c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$end=$be+1;
232c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
233c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		&comment("############### Calculate word $i");
234c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		for ($j=$bs; $j<$end; $j++)
235c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			{
236c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			&xor($c2,$c2) if ($j == $bs);
237c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (($ai-1) < ($bi+1))
238c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
239c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$v=1;
240c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$v=2 if ($i+1) == $tot;
241c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
242c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
243c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{ $v=0; }
244c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if (!$v)
245c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
246c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$na=$ai-1;
247c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$nb=$bi+1;
248c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
249c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
250c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
251c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$na=$as+($i < ($num-1));
252c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				$nb=$bs+($i >= ($num-1));
253c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
254c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ($ai == $bi)
255c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
256c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				&sqr_add_c($r,$a,$ai,$bi,
257c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					$c0,$c1,$c2,$v,$i,$na,$nb);
258c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
259c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			else
260c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
261c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				&sqr_add_c2($r,$a,$ai,$bi,
262c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org					$c0,$c1,$c2,$v,$i,$na,$nb);
263c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
264c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			if ($v)
265c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				{
266c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				&comment("saved r[$i]");
267c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				#&mov(&DWP($i*4,$r,"",0),$c0);
268c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				($c0,$c1,$c2)=($c1,$c2,$c0);
269c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				last;
270c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org				}
271c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			$ai--;
272c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			$bi++;
273c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org			}
274c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$as++ if ($i < ($num-1));
275c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$ae++ if ($i >= ($num-1));
276c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org
277c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$bs++ if ($i >= ($num-1));
278c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		$be++ if ($i < ($num-1));
279c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org		}
280c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&mov(&DWP($i*4,$r,"",0),$c0);
281c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&pop("ebx");
282c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&pop("ebp");
283c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&pop("edi");
284c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&pop("esi");
285c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&ret();
286c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	&function_end_B($name);
287c9490d33b98b7affb729b5f1db13cb0a348471aagl@chromium.org	}
288