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.pl365
1 files changed, 365 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..206452341d
--- /dev/null
+++ b/src/lib/libcrypto/perlasm/x86ms.pl
@@ -0,0 +1,365 @@
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 $reg1="$regs{$reg1}" if defined($regs{$reg1});
96 $reg2="$regs{$reg2}" if defined($regs{$reg2});
97 if (($addr ne "") && ($addr ne 0))
98 {
99 if ($addr !~ /^-/)
100 { $ret.=$addr; }
101 else { $post=$addr; }
102 }
103 if ($reg2 ne "")
104 {
105 $t="";
106 $t="*$idx" if ($idx != 0);
107 $reg1="+".$reg1 if ("$reg1$post" ne "");
108 $ret.="[$reg2$t$reg1$post]";
109 }
110 else
111 {
112 $ret.="[$reg1$post]"
113 }
114 return($ret);
115 }
116
117sub main'mov { &out2("mov",@_); }
118sub main'movb { &out2("mov",@_); }
119sub main'and { &out2("and",@_); }
120sub main'or { &out2("or",@_); }
121sub main'shl { &out2("shl",@_); }
122sub main'shr { &out2("shr",@_); }
123sub main'xor { &out2("xor",@_); }
124sub main'xorb { &out2("xor",@_); }
125sub main'add { &out2("add",@_); }
126sub main'adc { &out2("adc",@_); }
127sub main'sub { &out2("sub",@_); }
128sub main'rotl { &out2("rol",@_); }
129sub main'rotr { &out2("ror",@_); }
130sub main'exch { &out2("xchg",@_); }
131sub main'cmp { &out2("cmp",@_); }
132sub main'lea { &out2("lea",@_); }
133sub main'mul { &out1("mul",@_); }
134sub main'div { &out1("div",@_); }
135sub main'dec { &out1("dec",@_); }
136sub main'inc { &out1("inc",@_); }
137sub main'jmp { &out1("jmp",@_); }
138sub main'jmp_ptr { &out1p("jmp",@_); }
139sub main'je { &out1("je",@_); }
140sub main'jle { &out1("jle",@_); }
141sub main'jz { &out1("jz",@_); }
142sub main'jge { &out1("jge",@_); }
143sub main'jl { &out1("jl",@_); }
144sub main'jb { &out1("jb",@_); }
145sub main'jc { &out1("jc",@_); }
146sub main'jnc { &out1("jnc",@_); }
147sub main'jnz { &out1("jnz",@_); }
148sub main'jne { &out1("jne",@_); }
149sub main'jno { &out1("jno",@_); }
150sub main'push { &out1("push",@_); $stack+=4; }
151sub main'pop { &out1("pop",@_); $stack-=4; }
152sub main'bswap { &out1("bswap",@_); &using486(); }
153sub main'not { &out1("not",@_); }
154sub main'call { &out1("call",'_'.$_[0]); }
155sub main'ret { &out0("ret"); }
156sub main'nop { &out0("nop"); }
157
158sub out2
159 {
160 local($name,$p1,$p2)=@_;
161 local($l,$t);
162
163 push(@out,"\t$name\t");
164 $t=&conv($p1).",";
165 $l=length($t);
166 push(@out,$t);
167 $l=4-($l+9)/8;
168 push(@out,"\t" x $l);
169 push(@out,&conv($p2));
170 push(@out,"\n");
171 }
172
173sub out0
174 {
175 local($name)=@_;
176
177 push(@out,"\t$name\n");
178 }
179
180sub out1
181 {
182 local($name,$p1)=@_;
183 local($l,$t);
184
185 push(@out,"\t$name\t".&conv($p1)."\n");
186 }
187
188sub conv
189 {
190 local($p)=@_;
191
192 $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
193 return $p;
194 }
195
196sub using486
197 {
198 return if $using486;
199 $using486++;
200 grep(s/\.386/\.486/,@out);
201 }
202
203sub main'file
204 {
205 local($file)=@_;
206
207 local($tmp)=<<"EOF";
208 TITLE $file.asm
209 .386
210.model FLAT
211EOF
212 push(@out,$tmp);
213 }
214
215sub main'function_begin
216 {
217 local($func,$extra)=@_;
218
219 push(@labels,$func);
220
221 local($tmp)=<<"EOF";
222_TEXT SEGMENT
223PUBLIC _$func
224$extra
225_$func PROC NEAR
226 push ebp
227 push ebx
228 push esi
229 push edi
230EOF
231 push(@out,$tmp);
232 $stack=20;
233 }
234
235sub main'function_begin_B
236 {
237 local($func,$extra)=@_;
238
239 local($tmp)=<<"EOF";
240_TEXT SEGMENT
241PUBLIC _$func
242$extra
243_$func PROC NEAR
244EOF
245 push(@out,$tmp);
246 $stack=4;
247 }
248
249sub main'function_end
250 {
251 local($func)=@_;
252
253 local($tmp)=<<"EOF";
254 pop edi
255 pop esi
256 pop ebx
257 pop ebp
258 ret
259_$func ENDP
260_TEXT ENDS
261EOF
262 push(@out,$tmp);
263 $stack=0;
264 %label=();
265 }
266
267sub main'function_end_B
268 {
269 local($func)=@_;
270
271 local($tmp)=<<"EOF";
272_$func ENDP
273_TEXT ENDS
274EOF
275 push(@out,$tmp);
276 $stack=0;
277 %label=();
278 }
279
280sub main'function_end_A
281 {
282 local($func)=@_;
283
284 local($tmp)=<<"EOF";
285 pop edi
286 pop esi
287 pop ebx
288 pop ebp
289 ret
290EOF
291 push(@out,$tmp);
292 }
293
294sub main'file_end
295 {
296 push(@out,"END\n");
297 }
298
299sub main'wparam
300 {
301 local($num)=@_;
302
303 return(&main'DWP($stack+$num*4,"esp","",0));
304 }
305
306sub main'swtmp
307 {
308 return(&main'DWP($_[0]*4,"esp","",0));
309 }
310
311# Should use swtmp, which is above esp. Linix can trash the stack above esp
312#sub main'wtmp
313# {
314# local($num)=@_;
315#
316# return(&main'DWP(-(($num+1)*4),"esp","",0));
317# }
318
319sub main'comment
320 {
321 foreach (@_)
322 {
323 push(@out,"\t; $_\n");
324 }
325 }
326
327sub main'label
328 {
329 if (!defined($label{$_[0]}))
330 {
331 $label{$_[0]}="\$${label}${_[0]}";
332 $label++;
333 }
334 return($label{$_[0]});
335 }
336
337sub main'set_label
338 {
339 if (!defined($label{$_[0]}))
340 {
341 $label{$_[0]}="${label}${_[0]}";
342 $label++;
343 }
344 if((defined $_[2]) && ($_[2] == 1))
345 {
346 push(@out,"$label{$_[0]}::\n");
347 }
348 else
349 {
350 push(@out,"$label{$_[0]}:\n");
351 }
352 }
353
354sub main'data_word
355 {
356 push(@out,"\tDD\t$_[0]\n");
357 }
358
359sub out1p
360 {
361 local($name,$p1)=@_;
362 local($l,$t);
363
364 push(@out,"\t$name\t ".&conv($p1)."\n");
365 }