Following the license change, modify the boilerplates in crypto/bn/
[openssl.git] / crypto / bn / asm / co-586.pl
1 #! /usr/bin/env perl
2 # Copyright 1995-2016 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;
10 push(@INC,"${dir}","${dir}../../perlasm");
11 require "x86asm.pl";
12
13 $output = pop;
14 open 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
25 close STDOUT;
26
27 sub 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;        # laod 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;        # laod next b
47          &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1;        # laod 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;         # laod next a
53         }
54
55 sub 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
84 sub 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
116 sub 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
207 sub 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         }