This commit was generated by cvs2svn to track changes on a CVS vendor
[openssl.git] / crypto / bn / asm / bn-586.pl
1 #!/usr/local/bin/perl
2 #
3
4 #!/usr/local/bin/perl
5
6 push(@INC,"perlasm","../../perlasm");
7 require "x86asm.pl";
8
9 &asm_init($ARGV[0],"bn-586.pl");
10
11 &bn_mul_add_words("bn_mul_add_words");
12 &bn_mul_words("bn_mul_words");
13 &bn_sqr_words("bn_sqr_words");
14 &bn_div64("bn_div64");
15 &bn_add_words("bn_add_words");
16
17 &asm_finish();
18
19 sub bn_mul_add_words
20         {
21         local($name)=@_;
22
23         &function_begin($name,"");
24
25         &comment("");
26         $Low="eax";
27         $High="edx";
28         $a="ebx";
29         $w="ebp";
30         $r="edi";
31         $c="esi";
32
33         &xor($c,$c);            # clear carry
34         &mov($r,&wparam(0));    #
35
36         &mov("ecx",&wparam(2)); #
37         &mov($a,&wparam(1));    #
38
39         &and("ecx",0xfffffff8); # num / 8
40         &mov($w,&wparam(3));    #
41
42         &push("ecx");           # Up the stack for a tmp variable
43
44         &jz(&label("maw_finish"));
45
46         &set_label("maw_loop",0);
47
48         &mov(&swtmp(0),"ecx");  #
49
50         for ($i=0; $i<32; $i+=4)
51                 {
52                 &comment("Round $i");
53
54                  &mov("eax",&DWP($i,$a,"",0));  # *a
55                 &mul($w);                       # *a * w
56                 &add("eax",$c);         # L(t)+= *r
57                  &mov($c,&DWP($i,$r,"",0));     # L(t)+= *r
58                 &adc("edx",0);                  # H(t)+=carry
59                  &add("eax",$c);                # L(t)+=c
60                 &adc("edx",0);                  # H(t)+=carry
61                  &mov(&DWP($i,$r,"",0),"eax");  # *r= L(t);
62                 &mov($c,"edx");                 # c=  H(t);
63                 }
64
65         &comment("");
66         &mov("ecx",&swtmp(0));  #
67         &add($a,32);
68         &add($r,32);
69         &sub("ecx",8);
70         &jnz(&label("maw_loop"));
71
72         &set_label("maw_finish",0);
73         &mov("ecx",&wparam(2)); # get num
74         &and("ecx",7);
75         &jnz(&label("maw_finish2"));    # helps branch prediction
76         &jmp(&label("maw_end"));
77
78         &set_label("maw_finish2",1);
79         for ($i=0; $i<7; $i++)
80                 {
81                 &comment("Tail Round $i");
82                  &mov("eax",&DWP($i*4,$a,"",0));# *a
83                 &mul($w);                       # *a * w
84                 &add("eax",$c);                 # L(t)+=c
85                  &mov($c,&DWP($i*4,$r,"",0));   # L(t)+= *r
86                 &adc("edx",0);                  # H(t)+=carry
87                  &add("eax",$c);
88                 &adc("edx",0);                  # H(t)+=carry
89                  &dec("ecx") if ($i != 7-1);
90                 &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t);
91                  &mov($c,"edx");                        # c=  H(t);
92                 &jz(&label("maw_end")) if ($i != 7-1);
93                 }
94         &set_label("maw_end",0);
95         &mov("eax",$c);
96
97         &pop("ecx");    # clear variable from
98
99         &function_end($name);
100         }
101
102 sub bn_mul_words
103         {
104         local($name)=@_;
105
106         &function_begin($name,"");
107
108         &comment("");
109         $Low="eax";
110         $High="edx";
111         $a="ebx";
112         $w="ecx";
113         $r="edi";
114         $c="esi";
115         $num="ebp";
116
117         &xor($c,$c);            # clear carry
118         &mov($r,&wparam(0));    #
119         &mov($a,&wparam(1));    #
120         &mov($num,&wparam(2));  #
121         &mov($w,&wparam(3));    #
122
123         &and($num,0xfffffff8);  # num / 8
124         &jz(&label("mw_finish"));
125
126         &set_label("mw_loop",0);
127         for ($i=0; $i<32; $i+=4)
128                 {
129                 &comment("Round $i");
130
131                  &mov("eax",&DWP($i,$a,"",0));  # *a
132                 &mul($w);                       # *a * w
133                 &add("eax",$c);                 # L(t)+=c
134                  # XXX
135
136                 &adc("edx",0);                  # H(t)+=carry
137                  &mov(&DWP($i,$r,"",0),"eax");  # *r= L(t);
138
139                 &mov($c,"edx");                 # c=  H(t);
140                 }
141
142         &comment("");
143         &add($a,32);
144         &add($r,32);
145         &sub($num,8);
146         &jz(&label("mw_finish"));
147         &jmp(&label("mw_loop"));
148
149         &set_label("mw_finish",0);
150         &mov($num,&wparam(2));  # get num
151         &and($num,7);
152         &jnz(&label("mw_finish2"));
153         &jmp(&label("mw_end"));
154
155         &set_label("mw_finish2",1);
156         for ($i=0; $i<7; $i++)
157                 {
158                 &comment("Tail Round $i");
159                  &mov("eax",&DWP($i*4,$a,"",0));# *a
160                 &mul($w);                       # *a * w
161                 &add("eax",$c);                 # L(t)+=c
162                  # XXX
163                 &adc("edx",0);                  # H(t)+=carry
164                  &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t);
165                 &mov($c,"edx");                 # c=  H(t);
166                  &dec($num) if ($i != 7-1);
167                 &jz(&label("mw_end")) if ($i != 7-1);
168                 }
169         &set_label("mw_end",0);
170         &mov("eax",$c);
171
172         &function_end($name);
173         }
174
175 sub bn_sqr_words
176         {
177         local($name)=@_;
178
179         &function_begin($name,"");
180
181         &comment("");
182         $r="esi";
183         $a="edi";
184         $num="ebx";
185
186         &mov($r,&wparam(0));    #
187         &mov($a,&wparam(1));    #
188         &mov($num,&wparam(2));  #
189
190         &and($num,0xfffffff8);  # num / 8
191         &jz(&label("sw_finish"));
192
193         &set_label("sw_loop",0);
194         for ($i=0; $i<32; $i+=4)
195                 {
196                 &comment("Round $i");
197                 &mov("eax",&DWP($i,$a,"",0));   # *a
198                  # XXX
199                 &mul("eax");                    # *a * *a
200                 &mov(&DWP($i*2,$r,"",0),"eax"); #
201                  &mov(&DWP($i*2+4,$r,"",0),"edx");#
202                 }
203
204         &comment("");
205         &add($a,32);
206         &add($r,64);
207         &sub($num,8);
208         &jnz(&label("sw_loop"));
209
210         &set_label("sw_finish",0);
211         &mov($num,&wparam(2));  # get num
212         &and($num,7);
213         &jz(&label("sw_end"));
214
215         for ($i=0; $i<7; $i++)
216                 {
217                 &comment("Tail Round $i");
218                 &mov("eax",&DWP($i*4,$a,"",0)); # *a
219                  # XXX
220                 &mul("eax");                    # *a * *a
221                 &mov(&DWP($i*8,$r,"",0),"eax"); #
222                  &dec($num) if ($i != 7-1);
223                 &mov(&DWP($i*8+4,$r,"",0),"edx");
224                  &jz(&label("sw_end")) if ($i != 7-1);
225                 }
226         &set_label("sw_end",0);
227
228         &function_end($name);
229         }
230
231 sub bn_div64
232         {
233         local($name)=@_;
234
235         &function_begin($name,"");
236         &mov("edx",&wparam(0)); #
237         &mov("eax",&wparam(1)); #
238         &mov("ebx",&wparam(2)); #
239         &div("ebx");
240         &function_end($name);
241         }
242
243 sub bn_add_words
244         {
245         local($name)=@_;
246
247         &function_begin($name,"");
248
249         &comment("");
250         $a="esi";
251         $b="edi";
252         $c="eax";
253         $r="ebx";
254         $tmp1="ecx";
255         $tmp2="edx";
256         $num="ebp";
257
258         &mov($r,&wparam(0));    # get r
259          &mov($a,&wparam(1));   # get a
260         &mov($b,&wparam(2));    # get b
261          &mov($num,&wparam(3)); # get num
262         &xor($c,$c);            # clear carry
263          &and($num,0xfffffff8); # num / 8
264
265         &jz(&label("aw_finish"));
266
267         &set_label("aw_loop",0);
268         for ($i=0; $i<8; $i++)
269                 {
270                 &comment("Round $i");
271
272                 &mov($tmp1,&DWP($i*4,$a,"",0));         # *a
273                  &mov($tmp2,&DWP($i*4,$b,"",0));        # *b
274                 &add($tmp1,$c);
275                  &mov($c,0);
276                 &adc($c,$c);
277                  &add($tmp1,$tmp2);
278                 &adc($c,0);
279                  &mov(&DWP($i*4,$r,"",0),$tmp1);        # *r
280                 }
281
282         &comment("");
283         &add($a,32);
284          &add($b,32);
285         &add($r,32);
286          &sub($num,8);
287         &jnz(&label("aw_loop"));
288
289         &set_label("aw_finish",0);
290         &mov($num,&wparam(3));  # get num
291         &and($num,7);
292          &jz(&label("aw_end"));
293
294         for ($i=0; $i<7; $i++)
295                 {
296                 &comment("Tail Round $i");
297                 &mov($tmp1,&DWP($i*4,$a,"",0)); # *a
298                  &mov($tmp2,&DWP($i*4,$b,"",0));# *b
299                 &add($tmp1,$c);
300                  &mov($c,0);
301                 &adc($c,$c);
302                  &add($tmp1,$tmp2);
303                 &adc($c,0);
304                  &dec($num) if ($i != 6);
305                 &mov(&DWP($i*4,$r,"",0),$tmp1); # *a
306                  &jz(&label("aw_end")) if ($i != 6);
307                 }
308         &set_label("aw_end",0);
309
310         &mov("eax",$c);
311
312         &function_end($name);
313         }
314