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