]>
Commit | Line | Data |
---|---|---|
e0a65194 RS |
1 | #! /usr/bin/env perl |
2 | # Copyright 1995-2016 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 | |
dfeab068 | 8 | |
4d1f3f7a DSH |
9 | $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; |
10 | push(@INC,"${dir}","${dir}../../perlasm"); | |
dfeab068 RE |
11 | require "x86asm.pl"; |
12 | ||
6bd7a4d9 RL |
13 | $output = pop; |
14 | open STDOUT,">$output"; | |
15 | ||
65b8ca07 | 16 | &asm_init($ARGV[0],$0); |
dfeab068 RE |
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 | ||
6bd7a4d9 RL |
25 | close STDOUT; |
26 | ||
dfeab068 RE |
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 | } |