summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/perlasm/x86unix.pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/perlasm/x86unix.pl')
-rw-r--r--src/lib/libcrypto/perlasm/x86unix.pl220
1 files changed, 178 insertions, 42 deletions
diff --git a/src/lib/libcrypto/perlasm/x86unix.pl b/src/lib/libcrypto/perlasm/x86unix.pl
index a31a25c12b..a4c947165e 100644
--- a/src/lib/libcrypto/perlasm/x86unix.pl
+++ b/src/lib/libcrypto/perlasm/x86unix.pl
@@ -1,14 +1,15 @@
1#!/usr/local/bin/perl 1#!/usr/local/bin/perl
2 2
3package x86unix; 3package x86unix; # GAS actually...
4 4
5$label="L000"; 5$label="L000";
6$const=""; 6$const="";
7$constl=0; 7$constl=0;
8 8
9$align=($main'aout)?"4":"16"; 9$align=($main'aout)?"4":"16";
10$under=($main'aout)?"_":""; 10$under=($main'aout or $main'coff)?"_":"";
11$com_start=($main'sol)?"/":"#"; 11$dot=($main'aout)?"":".";
12$com_start="#" if ($main'aout or $main'coff);
12 13
13sub main'asm_init_output { @out=(); } 14sub main'asm_init_output { @out=(); }
14sub main'asm_get_output { return(@out); } 15sub main'asm_get_output { return(@out); }
@@ -51,6 +52,24 @@ if ($main'cpp)
51 'edi', '%edi', 52 'edi', '%edi',
52 'ebp', '%ebp', 53 'ebp', '%ebp',
53 'esp', '%esp', 54 'esp', '%esp',
55
56 'mm0', '%mm0',
57 'mm1', '%mm1',
58 'mm2', '%mm2',
59 'mm3', '%mm3',
60 'mm4', '%mm4',
61 'mm5', '%mm5',
62 'mm6', '%mm6',
63 'mm7', '%mm7',
64
65 'xmm0', '%xmm0',
66 'xmm1', '%xmm1',
67 'xmm2', '%xmm2',
68 'xmm3', '%xmm3',
69 'xmm4', '%xmm4',
70 'xmm5', '%xmm5',
71 'xmm6', '%xmm6',
72 'xmm7', '%xmm7',
54 ); 73 );
55 74
56%reg_val=( 75%reg_val=(
@@ -97,6 +116,11 @@ sub main'DWP
97 return($ret); 116 return($ret);
98 } 117 }
99 118
119sub main'QWP
120 {
121 return(&main'DWP(@_));
122 }
123
100sub main'BP 124sub main'BP
101 { 125 {
102 return(&main'DWP(@_)); 126 return(&main'DWP(@_));
@@ -140,12 +164,14 @@ sub main'xorb { &out2("xorb",@_); }
140sub main'add { &out2($_[0]=~/%[a-d][lh]/?"addb":"addl",@_); } 164sub main'add { &out2($_[0]=~/%[a-d][lh]/?"addb":"addl",@_); }
141sub main'adc { &out2("adcl",@_); } 165sub main'adc { &out2("adcl",@_); }
142sub main'sub { &out2("subl",@_); } 166sub main'sub { &out2("subl",@_); }
167sub main'sbb { &out2("sbbl",@_); }
143sub main'rotl { &out2("roll",@_); } 168sub main'rotl { &out2("roll",@_); }
144sub main'rotr { &out2("rorl",@_); } 169sub main'rotr { &out2("rorl",@_); }
145sub main'exch { &out2($_[0]=~/%[a-d][lh]/?"xchgb":"xchgl",@_); } 170sub main'exch { &out2($_[0]=~/%[a-d][lh]/?"xchgb":"xchgl",@_); }
146sub main'cmp { &out2("cmpl",@_); } 171sub main'cmp { &out2("cmpl",@_); }
147sub main'lea { &out2("leal",@_); } 172sub main'lea { &out2("leal",@_); }
148sub main'mul { &out1("mull",@_); } 173sub main'mul { &out1("mull",@_); }
174sub main'imul { &out2("imull",@_); }
149sub main'div { &out1("divl",@_); } 175sub main'div { &out1("divl",@_); }
150sub main'jmp { &out1("jmp",@_); } 176sub main'jmp { &out1("jmp",@_); }
151sub main'jmp_ptr { &out1p("jmp",@_); } 177sub main'jmp_ptr { &out1p("jmp",@_); }
@@ -167,13 +193,48 @@ sub main'dec { &out1("decl",@_); }
167sub main'inc { &out1($_[0]=~/%[a-d][hl]/?"incb":"incl",@_); } 193sub main'inc { &out1($_[0]=~/%[a-d][hl]/?"incb":"incl",@_); }
168sub main'push { &out1("pushl",@_); $stack+=4; } 194sub main'push { &out1("pushl",@_); $stack+=4; }
169sub main'pop { &out1("popl",@_); $stack-=4; } 195sub main'pop { &out1("popl",@_); $stack-=4; }
170sub main'pushf { &out0("pushf"); $stack+=4; } 196sub main'pushf { &out0("pushfl"); $stack+=4; }
171sub main'popf { &out0("popf"); $stack-=4; } 197sub main'popf { &out0("popfl"); $stack-=4; }
172sub main'not { &out1("notl",@_); } 198sub main'not { &out1("notl",@_); }
173sub main'call { &out1("call",($_[0]=~/^\.L/?'':$under).$_[0]); } 199sub main'call { my $pre=$under;
200 foreach $i (%label)
201 { if ($label{$i} eq $_[0]) { $pre=''; last; } }
202 &out1("call",$pre.$_[0]);
203 }
204sub main'call_ptr { &out1p("call",@_); }
174sub main'ret { &out0("ret"); } 205sub main'ret { &out0("ret"); }
175sub main'nop { &out0("nop"); } 206sub main'nop { &out0("nop"); }
207sub main'test { &out2("testl",@_); }
208sub main'bt { &out2("btl",@_); }
209sub main'leave { &out0("leave"); }
210sub main'cpuid { &out0(".byte\t0x0f,0xa2"); }
211sub main'rdtsc { &out0(".byte\t0x0f,0x31"); }
212sub main'halt { &out0("hlt"); }
176sub main'movz { &out2("movzbl",@_); } 213sub main'movz { &out2("movzbl",@_); }
214sub main'neg { &out1("negl",@_); }
215sub main'cld { &out0("cld"); }
216
217# SSE2
218sub main'emms { &out0("emms"); }
219sub main'movd { &out2("movd",@_); }
220sub main'movdqu { &out2("movdqu",@_); }
221sub main'movdqa { &out2("movdqa",@_); }
222sub main'movdq2q{ &out2("movdq2q",@_); }
223sub main'movq2dq{ &out2("movq2dq",@_); }
224sub main'paddq { &out2("paddq",@_); }
225sub main'pmuludq{ &out2("pmuludq",@_); }
226sub main'psrlq { &out2("psrlq",@_); }
227sub main'psllq { &out2("psllq",@_); }
228sub main'pxor { &out2("pxor",@_); }
229sub main'por { &out2("por",@_); }
230sub main'pand { &out2("pand",@_); }
231sub main'movq {
232 local($p1,$p2,$optimize)=@_;
233 if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
234 # movq between mmx registers can sink Intel CPUs
235 { push(@out,"\tpshufw\t\$0xe4,%$p2,%$p1\n"); }
236 else { &out2("movq",@_); }
237 }
177 238
178# The bswapl instruction is new for the 486. Emulate if i386. 239# The bswapl instruction is new for the 486. Emulate if i386.
179sub main'bswap 240sub main'bswap
@@ -279,8 +340,6 @@ sub main'file
279 340
280 local($tmp)=<<"EOF"; 341 local($tmp)=<<"EOF";
281 .file "$file.s" 342 .file "$file.s"
282 .version "01.01"
283gcc2_compiled.:
284EOF 343EOF
285 push(@out,$tmp); 344 push(@out,$tmp);
286 } 345 }
@@ -294,15 +353,17 @@ sub main'function_begin
294 353
295 local($tmp)=<<"EOF"; 354 local($tmp)=<<"EOF";
296.text 355.text
297 .align $align 356.globl $func
298.globl $func
299EOF 357EOF
300 push(@out,$tmp); 358 push(@out,$tmp);
301 if ($main'cpp) 359 if ($main'cpp)
302 { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } 360 { $tmp=push(@out,"TYPE($func,\@function)\n"); }
303 elsif ($main'gaswin) 361 elsif ($main'coff)
304 { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } 362 { $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
305 else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } 363 elsif ($main'aout and !$main'pic)
364 { }
365 else { $tmp=push(@out,".type\t$func,\@function\n"); }
366 push(@out,".align\t$align\n");
306 push(@out,"$func:\n"); 367 push(@out,"$func:\n");
307 $tmp=<<"EOF"; 368 $tmp=<<"EOF";
308 pushl %ebp 369 pushl %ebp
@@ -324,15 +385,17 @@ sub main'function_begin_B
324 385
325 local($tmp)=<<"EOF"; 386 local($tmp)=<<"EOF";
326.text 387.text
327 .align $align 388.globl $func
328.globl $func
329EOF 389EOF
330 push(@out,$tmp); 390 push(@out,$tmp);
331 if ($main'cpp) 391 if ($main'cpp)
332 { push(@out,"\tTYPE($func,\@function)\n"); } 392 { push(@out,"TYPE($func,\@function)\n"); }
333 elsif ($main'gaswin) 393 elsif ($main'coff)
334 { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } 394 { $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
335 else { push(@out,"\t.type $func,\@function\n"); } 395 elsif ($main'aout and !$main'pic)
396 { }
397 else { push(@out,".type $func,\@function\n"); }
398 push(@out,".align\t$align\n");
336 push(@out,"$func:\n"); 399 push(@out,"$func:\n");
337 $stack=4; 400 $stack=4;
338 } 401 }
@@ -349,15 +412,15 @@ sub main'function_end
349 popl %ebx 412 popl %ebx
350 popl %ebp 413 popl %ebp
351 ret 414 ret
352.L_${func}_end: 415${dot}L_${func}_end:
353EOF 416EOF
354 push(@out,$tmp); 417 push(@out,$tmp);
355 418
356 if ($main'cpp) 419 if ($main'cpp)
357 { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } 420 { push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); }
358 elsif ($main'gaswin) 421 elsif ($main'coff or $main'aout)
359 { $tmp=push(@out,"\t.align 4\n"); } 422 { }
360 else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } 423 else { push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); }
361 push(@out,".ident \"$func\"\n"); 424 push(@out,".ident \"$func\"\n");
362 $stack=0; 425 $stack=0;
363 %label=(); 426 %label=();
@@ -383,13 +446,13 @@ sub main'function_end_B
383 446
384 $func=$under.$func; 447 $func=$under.$func;
385 448
386 push(@out,".L_${func}_end:\n"); 449 push(@out,"${dot}L_${func}_end:\n");
387 if ($main'cpp) 450 if ($main'cpp)
388 { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } 451 { push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); }
389 elsif ($main'gaswin) 452 elsif ($main'coff or $main'aout)
390 { push(@out,"\t.align 4\n"); } 453 { }
391 else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } 454 else { push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); }
392 push(@out,".ident \"desasm.pl\"\n"); 455 push(@out,".ident \"$func\"\n");
393 $stack=0; 456 $stack=0;
394 %label=(); 457 %label=();
395 } 458 }
@@ -430,9 +493,10 @@ sub main'swtmp
430 493
431sub main'comment 494sub main'comment
432 { 495 {
433 if ($main'elf) # GNU and SVR4 as'es use different comment delimiters, 496 if (!defined($com_start) or $main'elf)
434 { # so we just skip comments... 497 { # Regarding $main'elf above...
435 push(@out,"\n"); 498 # GNU and SVR4 as'es use different comment delimiters,
499 push(@out,"\n"); # so we just skip ELF comments...
436 return; 500 return;
437 } 501 }
438 foreach (@_) 502 foreach (@_)
@@ -444,11 +508,17 @@ sub main'comment
444 } 508 }
445 } 509 }
446 510
511sub main'public_label
512 {
513 $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]}));
514 push(@out,".globl\t$label{$_[0]}\n");
515 }
516
447sub main'label 517sub main'label
448 { 518 {
449 if (!defined($label{$_[0]})) 519 if (!defined($label{$_[0]}))
450 { 520 {
451 $label{$_[0]}=".${label}${_[0]}"; 521 $label{$_[0]}="${dot}${label}${_[0]}";
452 $label++; 522 $label++;
453 } 523 }
454 return($label{$_[0]}); 524 return($label{$_[0]});
@@ -458,15 +528,29 @@ sub main'set_label
458 { 528 {
459 if (!defined($label{$_[0]})) 529 if (!defined($label{$_[0]}))
460 { 530 {
461 $label{$_[0]}=".${label}${_[0]}"; 531 $label{$_[0]}="${dot}${label}${_[0]}";
462 $label++; 532 $label++;
463 } 533 }
464 push(@out,".align $align\n") if ($_[1] != 0); 534 if ($_[1]!=0)
535 {
536 if ($_[1]>1) { main'align($_[1]); }
537 else { push(@out,".align $align\n"); }
538 }
465 push(@out,"$label{$_[0]}:\n"); 539 push(@out,"$label{$_[0]}:\n");
466 } 540 }
467 541
468sub main'file_end 542sub main'file_end
469 { 543 {
544 # try to detect if SSE2 or MMX extensions were used on ELF platform...
545 if ($main'elf && grep {/\b%[x]*mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) {
546 local($tmp);
547
548 push (@out,"\n.section\t.bss\n");
549 push (@out,".comm\t${under}OPENSSL_ia32cap_P,4,4\n");
550
551 return;
552 }
553
470 if ($const ne "") 554 if ($const ne "")
471 { 555 {
472 push(@out,".section .rodata\n"); 556 push(@out,".section .rodata\n");
@@ -475,9 +559,25 @@ sub main'file_end
475 } 559 }
476 } 560 }
477 561
562sub main'data_byte
563 {
564 push(@out,"\t.byte\t".join(',',@_)."\n");
565 }
566
478sub main'data_word 567sub main'data_word
479 { 568 {
480 push(@out,"\t.long $_[0]\n"); 569 push(@out,"\t.long\t".join(',',@_)."\n");
570 }
571
572sub main'align
573 {
574 my $val=$_[0],$p2,$i;
575 if ($main'aout) {
576 for ($p2=0;$val!=0;$val>>=1) { $p2++; }
577 $val=$p2-1;
578 $val.=",0x90";
579 }
580 push(@out,".align\t$val\n");
481 } 581 }
482 582
483# debug output functions: puts, putx, printf 583# debug output functions: puts, putx, printf
@@ -559,7 +659,6 @@ sub main'picmeup
559 { 659 {
560 local($tmp)=<<___; 660 local($tmp)=<<___;
561#if (defined(ELF) || defined(SOL)) && defined(PIC) 661#if (defined(ELF) || defined(SOL)) && defined(PIC)
562 .align 8
563 call 1f 662 call 1f
5641: popl $regs{$dst} 6631: popl $regs{$dst}
565 addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst} 664 addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst}
@@ -572,13 +671,12 @@ ___
572 } 671 }
573 elsif ($main'pic && ($main'elf || $main'aout)) 672 elsif ($main'pic && ($main'elf || $main'aout))
574 { 673 {
575 push(@out,"\t.align\t8\n");
576 &main'call(&main'label("PIC_me_up")); 674 &main'call(&main'label("PIC_me_up"));
577 &main'set_label("PIC_me_up"); 675 &main'set_label("PIC_me_up");
578 &main'blindpop($dst); 676 &main'blindpop($dst);
579 &main'add($dst,"\$$under"."_GLOBAL_OFFSET_TABLE_+[.-". 677 &main'add($dst,"\$${under}_GLOBAL_OFFSET_TABLE_+[.-".
580 &main'label("PIC_me_up") . "]"); 678 &main'label("PIC_me_up") . "]");
581 &main'mov($dst,&main'DWP($sym."\@GOT",$dst)); 679 &main'mov($dst,&main'DWP($under.$sym."\@GOT",$dst));
582 } 680 }
583 else 681 else
584 { 682 {
@@ -587,3 +685,41 @@ ___
587 } 685 }
588 686
589sub main'blindpop { &out1("popl",@_); } 687sub main'blindpop { &out1("popl",@_); }
688
689sub main'initseg
690 {
691 local($f)=@_;
692 local($tmp);
693 if ($main'elf)
694 {
695 $tmp=<<___;
696.section .init
697 call $under$f
698 jmp .Linitalign
699.align $align
700.Linitalign:
701___
702 }
703 elsif ($main'coff)
704 {
705 $tmp=<<___; # applies to both Cygwin and Mingw
706.section .ctors
707.long $under$f
708___
709 }
710 elsif ($main'aout)
711 {
712 local($ctor)="${under}_GLOBAL_\$I\$$f";
713 $tmp=".text\n";
714 $tmp.=".type $ctor,\@function\n" if ($main'pic);
715 $tmp.=<<___; # OpenBSD way...
716.globl $ctor
717.align 2
718$ctor:
719 jmp $under$f
720___
721 }
722 push(@out,$tmp) if ($tmp);
723 }
724
7251;