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