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