(no commit message)
[strongswan.git] / src / libfreeswan / libcrypto / libdes / asm / perlasm / x86ms.pl
1 #!/usr/bin/perl
2
3 package x86ms;
4
5 $label="L000";
6
7 %lb=( 'eax', 'al',
8 'ebx', 'bl',
9 'ecx', 'cl',
10 'edx', 'dl',
11 'ax', 'al',
12 'bx', 'bl',
13 'cx', 'cl',
14 'dx', 'dl',
15 );
16
17 %hb=( 'eax', 'ah',
18 'ebx', 'bh',
19 'ecx', 'ch',
20 'edx', 'dh',
21 'ax', 'ah',
22 'bx', 'bh',
23 'cx', 'ch',
24 'dx', 'dh',
25 );
26
27 sub main'asm_init_output { @out=(); }
28 sub main'asm_get_output { return(@out); }
29 sub main'get_labels { return(@labels); }
30 sub main'external_label { push(@labels,@_); }
31
32 sub main'LB
33 {
34 (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
35 return($lb{$_[0]});
36 }
37
38 sub main'HB
39 {
40 (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
41 return($hb{$_[0]});
42 }
43
44 sub main'BP
45 {
46 &get_mem("BYTE",@_);
47 }
48
49 sub main'DWP
50 {
51 &get_mem("DWORD",@_);
52 }
53
54 sub main'stack_push
55 {
56 local($num)=@_;
57 $stack+=$num*4;
58 &main'sub("esp",$num*4);
59 }
60
61 sub main'stack_pop
62 {
63 local($num)=@_;
64 $stack-=$num*4;
65 &main'add("esp",$num*4);
66 }
67
68 sub get_mem
69 {
70 local($size,$addr,$reg1,$reg2,$idx)=@_;
71 local($t,$post);
72 local($ret)="$size PTR ";
73
74 $addr =~ s/^\s+//;
75 if ($addr =~ /^(.+)\+(.+)$/)
76 {
77 $reg2=&conv($1);
78 $addr="_$2";
79 }
80 elsif ($addr =~ /^[_a-zA-Z]/)
81 {
82 $addr="_$addr";
83 }
84
85 $reg1="$regs{$reg1}" if defined($regs{$reg1});
86 $reg2="$regs{$reg2}" if defined($regs{$reg2});
87 if (($addr ne "") && ($addr ne 0))
88 {
89 if ($addr !~ /^-/)
90 { $ret.=$addr; }
91 else { $post=$addr; }
92 }
93 if ($reg2 ne "")
94 {
95 $t="";
96 $t="*$idx" if ($idx != 0);
97 $reg1="+".$reg1 if ("$reg1$post" ne "");
98 $ret.="[$reg2$t$reg1$post]";
99 }
100 else
101 {
102 $ret.="[$reg1$post]"
103 }
104 return($ret);
105 }
106
107 sub main'mov { &out2("mov",@_); }
108 sub main'movb { &out2("mov",@_); }
109 sub main'and { &out2("and",@_); }
110 sub main'or { &out2("or",@_); }
111 sub main'shl { &out2("shl",@_); }
112 sub main'shr { &out2("shr",@_); }
113 sub main'xor { &out2("xor",@_); }
114 sub main'xorb { &out2("xor",@_); }
115 sub main'add { &out2("add",@_); }
116 sub main'adc { &out2("adc",@_); }
117 sub main'sub { &out2("sub",@_); }
118 sub main'rotl { &out2("rol",@_); }
119 sub main'rotr { &out2("ror",@_); }
120 sub main'exch { &out2("xchg",@_); }
121 sub main'cmp { &out2("cmp",@_); }
122 sub main'lea { &out2("lea",@_); }
123 sub main'mul { &out1("mul",@_); }
124 sub main'div { &out1("div",@_); }
125 sub main'dec { &out1("dec",@_); }
126 sub main'inc { &out1("inc",@_); }
127 sub main'jmp { &out1("jmp",@_); }
128 sub main'jmp_ptr { &out1p("jmp",@_); }
129 sub main'je { &out1("je",@_); }
130 sub main'jle { &out1("jle",@_); }
131 sub main'jz { &out1("jz",@_); }
132 sub main'jge { &out1("jge",@_); }
133 sub main'jl { &out1("jl",@_); }
134 sub main'jb { &out1("jb",@_); }
135 sub main'jnz { &out1("jnz",@_); }
136 sub main'jne { &out1("jne",@_); }
137 sub main'push { &out1("push",@_); $stack+=4; }
138 sub main'pop { &out1("pop",@_); $stack-=4; }
139 sub main'bswap { &out1("bswap",@_); &using486(); }
140 sub main'not { &out1("not",@_); }
141 sub main'call { &out1("call",'_'.$_[0]); }
142 sub main'ret { &out0("ret"); }
143 sub main'nop { &out0("nop"); }
144
145 sub out2
146 {
147 local($name,$p1,$p2)=@_;
148 local($l,$t);
149
150 push(@out,"\t$name\t");
151 $t=&conv($p1).",";
152 $l=length($t);
153 push(@out,$t);
154 $l=4-($l+9)/8;
155 push(@out,"\t" x $l);
156 push(@out,&conv($p2));
157 push(@out,"\n");
158 }
159
160 sub out0
161 {
162 local($name)=@_;
163
164 push(@out,"\t$name\n");
165 }
166
167 sub out1
168 {
169 local($name,$p1)=@_;
170 local($l,$t);
171
172 push(@out,"\t$name\t".&conv($p1)."\n");
173 }
174
175 sub conv
176 {
177 local($p)=@_;
178
179 $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
180 return $p;
181 }
182
183 sub using486
184 {
185 return if $using486;
186 $using486++;
187 grep(s/\.386/\.486/,@out);
188 }
189
190 sub main'file
191 {
192 local($file)=@_;
193
194 local($tmp)=<<"EOF";
195 TITLE $file.asm
196 .386
197 .model FLAT
198 EOF
199 push(@out,$tmp);
200 }
201
202 sub main'function_begin
203 {
204 local($func,$extra)=@_;
205
206 push(@labels,$func);
207
208 local($tmp)=<<"EOF";
209 _TEXT SEGMENT
210 PUBLIC _$func
211 $extra
212 _$func PROC NEAR
213 push ebp
214 push ebx
215 push esi
216 push edi
217 EOF
218 push(@out,$tmp);
219 $stack=20;
220 }
221
222 sub main'function_begin_B
223 {
224 local($func,$extra)=@_;
225
226 local($tmp)=<<"EOF";
227 _TEXT SEGMENT
228 PUBLIC _$func
229 $extra
230 _$func PROC NEAR
231 EOF
232 push(@out,$tmp);
233 $stack=4;
234 }
235
236 sub main'function_end
237 {
238 local($func)=@_;
239
240 local($tmp)=<<"EOF";
241 pop edi
242 pop esi
243 pop ebx
244 pop ebp
245 ret
246 _$func ENDP
247 _TEXT ENDS
248 EOF
249 push(@out,$tmp);
250 $stack=0;
251 %label=();
252 }
253
254 sub main'function_end_B
255 {
256 local($func)=@_;
257
258 local($tmp)=<<"EOF";
259 _$func ENDP
260 _TEXT ENDS
261 EOF
262 push(@out,$tmp);
263 $stack=0;
264 %label=();
265 }
266
267 sub main'function_end_A
268 {
269 local($func)=@_;
270
271 local($tmp)=<<"EOF";
272 pop edi
273 pop esi
274 pop ebx
275 pop ebp
276 ret
277 EOF
278 push(@out,$tmp);
279 }
280
281 sub main'file_end
282 {
283 push(@out,"END\n");
284 }
285
286 sub main'wparam
287 {
288 local($num)=@_;
289
290 return(&main'DWP($stack+$num*4,"esp","",0));
291 }
292
293 sub main'swtmp
294 {
295 return(&main'DWP($_[0]*4,"esp","",0));
296 }
297
298 # Should use swtmp, which is above esp. Linix can trash the stack above esp
299 #sub main'wtmp
300 # {
301 # local($num)=@_;
302 #
303 # return(&main'DWP(-(($num+1)*4),"esp","",0));
304 # }
305
306 sub main'comment
307 {
308 foreach (@_)
309 {
310 push(@out,"\t; $_\n");
311 }
312 }
313
314 sub main'label
315 {
316 if (!defined($label{$_[0]}))
317 {
318 $label{$_[0]}="\$${label}${_[0]}";
319 $label++;
320 }
321 return($label{$_[0]});
322 }
323
324 sub main'set_label
325 {
326 if (!defined($label{$_[0]}))
327 {
328 $label{$_[0]}="${label}${_[0]}";
329 $label++;
330 }
331 push(@out,"$label{$_[0]}:\n");
332 }
333
334 sub main'data_word
335 {
336 push(@out,"\tDD\t$_[0]\n");
337 }
338
339 sub out1p
340 {
341 local($name,$p1)=@_;
342 local($l,$t);
343
344 push(@out,"\t$name\t ".&conv($p1)."\n");
345 }