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