Unified - adapt the generation of bignum assembler to use GENERATE
[openssl.git] / crypto / bn / asm / co-586.pl
1 #!/usr/local/bin/perl
2
3 $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
4 push(@INC,"${dir}","${dir}../../perlasm");
5 require "x86asm.pl";
6
7 $output = pop;
8 open STDOUT,">$output";
9
10 &asm_init($ARGV[0],$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
19 close STDOUT;
20
21 sub 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
49 sub 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
78 sub 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
110 sub 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
201 sub 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         }