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.pl379
1 files changed, 379 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..fbb4afb9bd
--- /dev/null
+++ b/src/lib/libcrypto/perlasm/x86ms.pl
@@ -0,0 +1,379 @@
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"); }
163
164sub out2
165 {
166 local($name,$p1,$p2)=@_;
167 local($l,$t);
168
169 push(@out,"\t$name\t");
170 $t=&conv($p1).",";
171 $l=length($t);
172 push(@out,$t);
173 $l=4-($l+9)/8;
174 push(@out,"\t" x $l);
175 push(@out,&conv($p2));
176 push(@out,"\n");
177 }
178
179sub out0
180 {
181 local($name)=@_;
182
183 push(@out,"\t$name\n");
184 }
185
186sub out1
187 {
188 local($name,$p1)=@_;
189 local($l,$t);
190
191 push(@out,"\t$name\t".&conv($p1)."\n");
192 }
193
194sub conv
195 {
196 local($p)=@_;
197
198 $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
199 return $p;
200 }
201
202sub using486
203 {
204 return if $using486;
205 $using486++;
206 grep(s/\.386/\.486/,@out);
207 }
208
209sub main'file
210 {
211 local($file)=@_;
212
213 local($tmp)=<<"EOF";
214 TITLE $file.asm
215 .386
216.model FLAT
217EOF
218 push(@out,$tmp);
219 }
220
221sub main'function_begin
222 {
223 local($func,$extra)=@_;
224
225 push(@labels,$func);
226
227 local($tmp)=<<"EOF";
228_TEXT SEGMENT
229PUBLIC _$func
230$extra
231_$func PROC NEAR
232 push ebp
233 push ebx
234 push esi
235 push edi
236EOF
237 push(@out,$tmp);
238 $stack=20;
239 }
240
241sub main'function_begin_B
242 {
243 local($func,$extra)=@_;
244
245 local($tmp)=<<"EOF";
246_TEXT SEGMENT
247PUBLIC _$func
248$extra
249_$func PROC NEAR
250EOF
251 push(@out,$tmp);
252 $stack=4;
253 }
254
255sub main'function_end
256 {
257 local($func)=@_;
258
259 local($tmp)=<<"EOF";
260 pop edi
261 pop esi
262 pop ebx
263 pop ebp
264 ret
265_$func ENDP
266_TEXT ENDS
267EOF
268 push(@out,$tmp);
269 $stack=0;
270 %label=();
271 }
272
273sub main'function_end_B
274 {
275 local($func)=@_;
276
277 local($tmp)=<<"EOF";
278_$func ENDP
279_TEXT ENDS
280EOF
281 push(@out,$tmp);
282 $stack=0;
283 %label=();
284 }
285
286sub main'function_end_A
287 {
288 local($func)=@_;
289
290 local($tmp)=<<"EOF";
291 pop edi
292 pop esi
293 pop ebx
294 pop ebp
295 ret
296EOF
297 push(@out,$tmp);
298 }
299
300sub main'file_end
301 {
302 push(@out,"END\n");
303 }
304
305sub main'wparam
306 {
307 local($num)=@_;
308
309 return(&main'DWP($stack+$num*4,"esp","",0));
310 }
311
312sub main'swtmp
313 {
314 return(&main'DWP($_[0]*4,"esp","",0));
315 }
316
317# Should use swtmp, which is above esp. Linix can trash the stack above esp
318#sub main'wtmp
319# {
320# local($num)=@_;
321#
322# return(&main'DWP(-(($num+1)*4),"esp","",0));
323# }
324
325sub main'comment
326 {
327 foreach (@_)
328 {
329 push(@out,"\t; $_\n");
330 }
331 }
332
333sub main'label
334 {
335 if (!defined($label{$_[0]}))
336 {
337 $label{$_[0]}="\$${label}${_[0]}";
338 $label++;
339 }
340 return($label{$_[0]});
341 }
342
343sub main'set_label
344 {
345 if (!defined($label{$_[0]}))
346 {
347 $label{$_[0]}="\$${label}${_[0]}";
348 $label++;
349 }
350 if((defined $_[2]) && ($_[2] == 1))
351 {
352 push(@out,"$label{$_[0]}::\n");
353 }
354 else
355 {
356 push(@out,"$label{$_[0]}:\n");
357 }
358 }
359
360sub main'data_word
361 {
362 push(@out,"\tDD\t$_[0]\n");
363 }
364
365sub out1p
366 {
367 local($name,$p1)=@_;
368 local($l,$t);
369
370 push(@out,"\t$name\t ".&conv($p1)."\n");
371 }
372
373sub main'picmeup
374 {
375 local($dst,$sym)=@_;
376 &main'lea($dst,&main'DWP($sym));
377 }
378
379sub main'blindpop { &out1("pop",@_); }