summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/perlasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/perlasm')
-rw-r--r--src/lib/libcrypto/perlasm/x86ms.pl348
-rw-r--r--src/lib/libcrypto/perlasm/x86unix.pl429
2 files changed, 777 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 }
diff --git a/src/lib/libcrypto/perlasm/x86unix.pl b/src/lib/libcrypto/perlasm/x86unix.pl
new file mode 100644
index 0000000000..6ee4dd3245
--- /dev/null
+++ b/src/lib/libcrypto/perlasm/x86unix.pl
@@ -0,0 +1,429 @@
1#!/usr/bin/perl
2
3# Because the bswapl instruction is not supported for old assembers
4# (it was a new instruction for the 486), I've added .byte xxxx code
5# to put it in.
6# eric 24-Apr-1998
7#
8
9package x86unix;
10
11$label="L000";
12
13$align=($main'aout)?"4":"16";
14$under=($main'aout)?"_":"";
15$com_start=($main'sol)?"/":"#";
16
17sub main'asm_init_output { @out=(); }
18sub main'asm_get_output { return(@out); }
19sub main'get_labels { return(@labels); }
20sub main'external_label { push(@labels,@_); }
21
22if ($main'cpp)
23 {
24 $align="ALIGN";
25 $under="";
26 $com_start='/*';
27 $com_end='*/';
28 }
29
30%lb=( 'eax', '%al',
31 'ebx', '%bl',
32 'ecx', '%cl',
33 'edx', '%dl',
34 'ax', '%al',
35 'bx', '%bl',
36 'cx', '%cl',
37 'dx', '%dl',
38 );
39
40%hb=( 'eax', '%ah',
41 'ebx', '%bh',
42 'ecx', '%ch',
43 'edx', '%dh',
44 'ax', '%ah',
45 'bx', '%bh',
46 'cx', '%ch',
47 'dx', '%dh',
48 );
49
50%regs=( 'eax', '%eax',
51 'ebx', '%ebx',
52 'ecx', '%ecx',
53 'edx', '%edx',
54 'esi', '%esi',
55 'edi', '%edi',
56 'ebp', '%ebp',
57 'esp', '%esp',
58 );
59
60%reg_val=(
61 'eax', 0x00,
62 'ebx', 0x03,
63 'ecx', 0x01,
64 'edx', 0x02,
65 'esi', 0x06,
66 'edi', 0x07,
67 'ebp', 0x05,
68 'esp', 0x04,
69 );
70
71sub main'LB
72 {
73 (defined($lb{$_[0]})) || die "$_[0] does not have a 'low byte'\n";
74 return($lb{$_[0]});
75 }
76
77sub main'HB
78 {
79 (defined($hb{$_[0]})) || die "$_[0] does not have a 'high byte'\n";
80 return($hb{$_[0]});
81 }
82
83sub main'DWP
84 {
85 local($addr,$reg1,$reg2,$idx)=@_;
86
87 $ret="";
88 $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
89 $reg1="$regs{$reg1}" if defined($regs{$reg1});
90 $reg2="$regs{$reg2}" if defined($regs{$reg2});
91 $ret.=$addr if ($addr ne "") && ($addr ne 0);
92 if ($reg2 ne "")
93 { $ret.="($reg1,$reg2,$idx)"; }
94 else
95 { $ret.="($reg1)" }
96 return($ret);
97 }
98
99sub main'BP
100 {
101 return(&main'DWP(@_));
102 }
103
104#sub main'BP
105# {
106# local($addr,$reg1,$reg2,$idx)=@_;
107#
108# $ret="";
109#
110# $addr =~ s/(^|[+ \t])([A-Za-z_]+)($|[+ \t])/$1$under$2$3/;
111# $reg1="$regs{$reg1}" if defined($regs{$reg1});
112# $reg2="$regs{$reg2}" if defined($regs{$reg2});
113# $ret.=$addr if ($addr ne "") && ($addr ne 0);
114# if ($reg2 ne "")
115# { $ret.="($reg1,$reg2,$idx)"; }
116# else
117# { $ret.="($reg1)" }
118# return($ret);
119# }
120
121sub main'mov { &out2("movl",@_); }
122sub main'movb { &out2("movb",@_); }
123sub main'and { &out2("andl",@_); }
124sub main'or { &out2("orl",@_); }
125sub main'shl { &out2("sall",@_); }
126sub main'shr { &out2("shrl",@_); }
127sub main'xor { &out2("xorl",@_); }
128sub main'xorb { &out2("xorb",@_); }
129sub main'add { &out2("addl",@_); }
130sub main'adc { &out2("adcl",@_); }
131sub main'sub { &out2("subl",@_); }
132sub main'rotl { &out2("roll",@_); }
133sub main'rotr { &out2("rorl",@_); }
134sub main'exch { &out2("xchg",@_); }
135sub main'cmp { &out2("cmpl",@_); }
136sub main'lea { &out2("leal",@_); }
137sub main'mul { &out1("mull",@_); }
138sub main'div { &out1("divl",@_); }
139sub main'jmp { &out1("jmp",@_); }
140sub main'jmp_ptr { &out1p("jmp",@_); }
141sub main'je { &out1("je",@_); }
142sub main'jle { &out1("jle",@_); }
143sub main'jne { &out1("jne",@_); }
144sub main'jnz { &out1("jnz",@_); }
145sub main'jz { &out1("jz",@_); }
146sub main'jge { &out1("jge",@_); }
147sub main'jl { &out1("jl",@_); }
148sub main'jb { &out1("jb",@_); }
149sub main'jc { &out1("jc",@_); }
150sub main'jnc { &out1("jnc",@_); }
151sub main'jno { &out1("jno",@_); }
152sub main'dec { &out1("decl",@_); }
153sub main'inc { &out1("incl",@_); }
154sub main'push { &out1("pushl",@_); $stack+=4; }
155sub main'pop { &out1("popl",@_); $stack-=4; }
156sub main'bswap { &out1("bswapl",@_); }
157sub main'not { &out1("notl",@_); }
158sub main'call { &out1("call",$under.$_[0]); }
159sub main'ret { &out0("ret"); }
160sub main'nop { &out0("nop"); }
161
162sub out2
163 {
164 local($name,$p1,$p2)=@_;
165 local($l,$ll,$t);
166 local(%special)=( "roll",0xD1C0,"rorl",0xD1C8,
167 "rcll",0xD1D0,"rcrl",0xD1D8,
168 "shll",0xD1E0,"shrl",0xD1E8,
169 "sarl",0xD1F8);
170
171 if ((defined($special{$name})) && defined($regs{$p1}) && ($p2 == 1))
172 {
173 $op=$special{$name}|$reg_val{$p1};
174 $tmp1=sprintf(".byte %d\n",($op>>8)&0xff);
175 $tmp2=sprintf(".byte %d\t",$op &0xff);
176 push(@out,$tmp1);
177 push(@out,$tmp2);
178
179 $p2=&conv($p2);
180 $p1=&conv($p1);
181 &main'comment("$name $p2 $p1");
182 return;
183 }
184
185 push(@out,"\t$name\t");
186 $t=&conv($p2).",";
187 $l=length($t);
188 push(@out,$t);
189 $ll=4-($l+9)/8;
190 $tmp1=sprintf("\t" x $ll);
191 push(@out,$tmp1);
192 push(@out,&conv($p1)."\n");
193 }
194
195sub out1
196 {
197 local($name,$p1)=@_;
198 local($l,$t);
199 local(%special)=("bswapl",0x0FC8);
200
201 if ((defined($special{$name})) && defined($regs{$p1}))
202 {
203 $op=$special{$name}|$reg_val{$p1};
204 $tmp1=sprintf(".byte %d\n",($op>>8)&0xff);
205 $tmp2=sprintf(".byte %d\t",$op &0xff);
206 push(@out,$tmp1);
207 push(@out,$tmp2);
208
209 $p2=&conv($p2);
210 $p1=&conv($p1);
211 &main'comment("$name $p2 $p1");
212 return;
213 }
214
215 push(@out,"\t$name\t".&conv($p1)."\n");
216 }
217
218sub out1p
219 {
220 local($name,$p1)=@_;
221 local($l,$t);
222
223 push(@out,"\t$name\t*".&conv($p1)."\n");
224 }
225
226sub out0
227 {
228 push(@out,"\t$_[0]\n");
229 }
230
231sub conv
232 {
233 local($p)=@_;
234
235# $p =~ s/0x([0-9A-Fa-f]+)/0$1h/;
236
237 $p=$regs{$p} if (defined($regs{$p}));
238
239 $p =~ s/^(-{0,1}[0-9A-Fa-f]+)$/\$$1/;
240 $p =~ s/^(0x[0-9A-Fa-f]+)$/\$$1/;
241 return $p;
242 }
243
244sub main'file
245 {
246 local($file)=@_;
247
248 local($tmp)=<<"EOF";
249 .file "$file.s"
250 .version "01.01"
251gcc2_compiled.:
252EOF
253 push(@out,$tmp);
254 }
255
256sub main'function_begin
257 {
258 local($func)=@_;
259
260 &main'external_label($func);
261 $func=$under.$func;
262
263 local($tmp)=<<"EOF";
264.text
265 .align $align
266.globl $func
267EOF
268 push(@out,$tmp);
269 if ($main'cpp)
270 { $tmp=push(@out,"\tTYPE($func,\@function)\n"); }
271 else { $tmp=push(@out,"\t.type\t$func,\@function\n"); }
272 push(@out,"$func:\n");
273 $tmp=<<"EOF";
274 pushl %ebp
275 pushl %ebx
276 pushl %esi
277 pushl %edi
278
279EOF
280 push(@out,$tmp);
281 $stack=20;
282 }
283
284sub main'function_begin_B
285 {
286 local($func,$extra)=@_;
287
288 &main'external_label($func);
289 $func=$under.$func;
290
291 local($tmp)=<<"EOF";
292.text
293 .align $align
294.globl $func
295EOF
296 push(@out,$tmp);
297 if ($main'cpp)
298 { push(@out,"\tTYPE($func,\@function)\n"); }
299 else { push(@out,"\t.type $func,\@function\n"); }
300 push(@out,"$func:\n");
301 $stack=4;
302 }
303
304sub main'function_end
305 {
306 local($func)=@_;
307
308 $func=$under.$func;
309
310 local($tmp)=<<"EOF";
311 popl %edi
312 popl %esi
313 popl %ebx
314 popl %ebp
315 ret
316.${func}_end:
317EOF
318 push(@out,$tmp);
319 if ($main'cpp)
320 { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
321 else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
322 push(@out,".ident \"$func\"\n");
323 $stack=0;
324 %label=();
325 }
326
327sub main'function_end_A
328 {
329 local($func)=@_;
330
331 local($tmp)=<<"EOF";
332 popl %edi
333 popl %esi
334 popl %ebx
335 popl %ebp
336 ret
337EOF
338 push(@out,$tmp);
339 }
340
341sub main'function_end_B
342 {
343 local($func)=@_;
344
345 $func=$under.$func;
346
347 push(@out,".${func}_end:\n");
348 if ($main'cpp)
349 { push(@out,"\tSIZE($func,.${func}_end-$func)\n"); }
350 else { push(@out,"\t.size\t$func,.${func}_end-$func\n"); }
351 push(@out,".ident \"desasm.pl\"\n");
352 $stack=0;
353 %label=();
354 }
355
356sub main'wparam
357 {
358 local($num)=@_;
359
360 return(&main'DWP($stack+$num*4,"esp","",0));
361 }
362
363sub main'stack_push
364 {
365 local($num)=@_;
366 $stack+=$num*4;
367 &main'sub("esp",$num*4);
368 }
369
370sub main'stack_pop
371 {
372 local($num)=@_;
373 $stack-=$num*4;
374 &main'add("esp",$num*4);
375 }
376
377sub main'swtmp
378 {
379 return(&main'DWP($_[0]*4,"esp","",0));
380 }
381
382# Should use swtmp, which is above esp. Linix can trash the stack above esp
383#sub main'wtmp
384# {
385# local($num)=@_;
386#
387# return(&main'DWP(-($num+1)*4,"esp","",0));
388# }
389
390sub main'comment
391 {
392 foreach (@_)
393 {
394 if (/^\s*$/)
395 { push(@out,"\n"); }
396 else
397 { push(@out,"\t$com_start $_ $com_end\n"); }
398 }
399 }
400
401sub main'label
402 {
403 if (!defined($label{$_[0]}))
404 {
405 $label{$_[0]}=".${label}${_[0]}";
406 $label++;
407 }
408 return($label{$_[0]});
409 }
410
411sub main'set_label
412 {
413 if (!defined($label{$_[0]}))
414 {
415 $label{$_[0]}=".${label}${_[0]}";
416 $label++;
417 }
418 push(@out,".align $align\n") if ($_[1] != 0);
419 push(@out,"$label{$_[0]}:\n");
420 }
421
422sub main'file_end
423 {
424 }
425
426sub main'data_word
427 {
428 push(@out,"\t.long $_[0]\n");
429 }