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