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