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.pl234
1 files changed, 184 insertions, 50 deletions
diff --git a/src/lib/libcrypto/perlasm/x86unix.pl b/src/lib/libcrypto/perlasm/x86unix.pl
index b61425e951..02d72a32bc 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); }
@@ -57,6 +58,24 @@ if ($main'cpp)
57 'edi', '%edi', 58 'edi', '%edi',
58 'ebp', '%ebp', 59 'ebp', '%ebp',
59 'esp', '%esp', 60 'esp', '%esp',
61
62 'mm0', '%mm0',
63 'mm1', '%mm1',
64 'mm2', '%mm2',
65 'mm3', '%mm3',
66 'mm4', '%mm4',
67 'mm5', '%mm5',
68 'mm6', '%mm6',
69 'mm7', '%mm7',
70
71 'xmm0', '%xmm0',
72 'xmm1', '%xmm1',
73 'xmm2', '%xmm2',
74 'xmm3', '%xmm3',
75 'xmm4', '%xmm4',
76 'xmm5', '%xmm5',
77 'xmm6', '%xmm6',
78 'xmm7', '%xmm7',
60 ); 79 );
61 80
62%reg_val=( 81%reg_val=(
@@ -103,6 +122,11 @@ sub main'DWP
103 return($ret); 122 return($ret);
104 } 123 }
105 124
125sub main'QWP
126 {
127 return(&main'DWP(@_));
128 }
129
106sub main'BP 130sub main'BP
107 { 131 {
108 return(&main'DWP(@_)); 132 return(&main'DWP(@_));
@@ -146,12 +170,14 @@ sub main'xorb { &out2("xorb",@_); }
146sub main'add { &out2($_[0]=~/%[a-d][lh]/?"addb":"addl",@_); } 170sub main'add { &out2($_[0]=~/%[a-d][lh]/?"addb":"addl",@_); }
147sub main'adc { &out2("adcl",@_); } 171sub main'adc { &out2("adcl",@_); }
148sub main'sub { &out2("subl",@_); } 172sub main'sub { &out2("subl",@_); }
173sub main'sbb { &out2("sbbl",@_); }
149sub main'rotl { &out2("roll",@_); } 174sub main'rotl { &out2("roll",@_); }
150sub main'rotr { &out2("rorl",@_); } 175sub main'rotr { &out2("rorl",@_); }
151sub main'exch { &out2($_[0]=~/%[a-d][lh]/?"xchgb":"xchgl",@_); } 176sub main'exch { &out2($_[0]=~/%[a-d][lh]/?"xchgb":"xchgl",@_); }
152sub main'cmp { &out2("cmpl",@_); } 177sub main'cmp { &out2("cmpl",@_); }
153sub main'lea { &out2("leal",@_); } 178sub main'lea { &out2("leal",@_); }
154sub main'mul { &out1("mull",@_); } 179sub main'mul { &out1("mull",@_); }
180sub main'imul { &out2("imull",@_); }
155sub main'div { &out1("divl",@_); } 181sub main'div { &out1("divl",@_); }
156sub main'jmp { &out1("jmp",@_); } 182sub main'jmp { &out1("jmp",@_); }
157sub main'jmp_ptr { &out1p("jmp",@_); } 183sub main'jmp_ptr { &out1p("jmp",@_); }
@@ -173,15 +199,48 @@ sub main'dec { &out1("decl",@_); }
173sub main'inc { &out1($_[0]=~/%[a-d][hl]/?"incb":"incl",@_); } 199sub main'inc { &out1($_[0]=~/%[a-d][hl]/?"incb":"incl",@_); }
174sub main'push { &out1("pushl",@_); $stack+=4; } 200sub main'push { &out1("pushl",@_); $stack+=4; }
175sub main'pop { &out1("popl",@_); $stack-=4; } 201sub main'pop { &out1("popl",@_); $stack-=4; }
176sub main'pushf { &out0("pushf"); $stack+=4; } 202sub main'pushf { &out0("pushfl"); $stack+=4; }
177sub main'popf { &out0("popf"); $stack-=4; } 203sub main'popf { &out0("popfl"); $stack-=4; }
178sub main'not { &out1("notl",@_); } 204sub main'not { &out1("notl",@_); }
179sub main'call { &out1("call",($_[0]=~/^\.L/?'':$under).$_[0]); } 205sub main'call { my $pre=$under;
206 foreach $i (%label)
207 { if ($label{$i} eq $_[0]) { $pre=''; last; } }
208 &out1("call",$pre.$_[0]);
209 }
210sub main'call_ptr { &out1p("call",@_); }
180sub main'ret { &out0("ret"); } 211sub main'ret { &out0("ret"); }
181sub main'nop { &out0("nop"); } 212sub main'nop { &out0("nop"); }
182sub main'test { &out2("testl",@_); } 213sub main'test { &out2("testl",@_); }
214sub main'bt { &out2("btl",@_); }
215sub main'leave { &out0("leave"); }
216sub main'cpuid { &out0(".byte\t0x0f,0xa2"); }
217sub main'rdtsc { &out0(".byte\t0x0f,0x31"); }
218sub main'halt { &out0("hlt"); }
183sub main'movz { &out2("movzbl",@_); } 219sub main'movz { &out2("movzbl",@_); }
184sub main'neg { &out1("negl",@_); } 220sub main'neg { &out1("negl",@_); }
221sub main'cld { &out0("cld"); }
222
223# SSE2
224sub main'emms { &out0("emms"); }
225sub main'movd { &out2("movd",@_); }
226sub main'movdqu { &out2("movdqu",@_); }
227sub main'movdqa { &out2("movdqa",@_); }
228sub main'movdq2q{ &out2("movdq2q",@_); }
229sub main'movq2dq{ &out2("movq2dq",@_); }
230sub main'paddq { &out2("paddq",@_); }
231sub main'pmuludq{ &out2("pmuludq",@_); }
232sub main'psrlq { &out2("psrlq",@_); }
233sub main'psllq { &out2("psllq",@_); }
234sub main'pxor { &out2("pxor",@_); }
235sub main'por { &out2("por",@_); }
236sub main'pand { &out2("pand",@_); }
237sub main'movq {
238 local($p1,$p2,$optimize)=@_;
239 if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/)
240 # movq between mmx registers can sink Intel CPUs
241 { push(@out,"\tpshufw\t\$0xe4,%$p2,%$p1\n"); }
242 else { &out2("movq",@_); }
243 }
185 244
186# The bswapl instruction is new for the 486. Emulate if i386. 245# The bswapl instruction is new for the 486. Emulate if i386.
187sub main'bswap 246sub main'bswap
@@ -290,8 +349,6 @@ sub main'file
290 349
291 local($tmp)=<<"EOF"; 350 local($tmp)=<<"EOF";
292 .file "$file.s" 351 .file "$file.s"
293 .version "01.01"
294gcc2_compiled.:
295EOF 352EOF
296 push(@out,$tmp); 353 push(@out,$tmp);
297 } 354 }
@@ -308,15 +365,17 @@ sub main'function_begin
308 365
309 local($tmp)=<<"EOF"; 366 local($tmp)=<<"EOF";
310.text 367.text
311 .align $align 368.globl $func
312.globl $func
313EOF 369EOF
314 push(@out,$tmp); 370 push(@out,$tmp);
315 if ($main'cpp) 371 if ($main'cpp)
316 { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } 372 { $tmp=push(@out,"TYPE($func,\@function)\n"); }
317 elsif ($main'gaswin) 373 elsif ($main'coff)
318 { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } 374 { $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
319 else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } 375 elsif ($main'aout and !$main'pic)
376 { }
377 else { $tmp=push(@out,".type\t$func,\@function\n"); }
378 push(@out,".align\t$align\n");
320 push(@out,"$func:\n"); 379 push(@out,"$func:\n");
321skip: 380skip:
322 $tmp=<<"EOF"; 381 $tmp=<<"EOF";
@@ -342,15 +401,17 @@ sub main'function_begin_B
342 401
343 local($tmp)=<<"EOF"; 402 local($tmp)=<<"EOF";
344.text 403.text
345 .align $align 404.globl $func
346.globl $func
347EOF 405EOF
348 push(@out,$tmp); 406 push(@out,$tmp);
349 if ($main'cpp) 407 if ($main'cpp)
350 { push(@out,"\tTYPE($func,\@function)\n"); } 408 { push(@out,"TYPE($func,\@function)\n"); }
351 elsif ($main'gaswin) 409 elsif ($main'coff)
352 { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } 410 { $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); }
353 else { push(@out,"\t.type $func,\@function\n"); } 411 elsif ($main'aout and !$main'pic)
412 { }
413 else { push(@out,".type $func,\@function\n"); }
414 push(@out,".align\t$align\n");
354 push(@out,"$func:\n"); 415 push(@out,"$func:\n");
355skip: 416skip:
356 $stack=4; 417 $stack=4;
@@ -368,15 +429,15 @@ sub main'function_end
368 popl %ebx 429 popl %ebx
369 popl %ebp 430 popl %ebp
370 ret 431 ret
371.L_${func}_end: 432${dot}L_${func}_end:
372EOF 433EOF
373 push(@out,$tmp); 434 push(@out,$tmp);
374 435
375 if ($main'cpp) 436 if ($main'cpp)
376 { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } 437 { push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); }
377 elsif ($main'gaswin) 438 elsif ($main'coff or $main'aout)
378 { $tmp=push(@out,"\t.align 4\n"); } 439 { }
379 else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } 440 else { push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); }
380 push(@out,".ident \"$func\"\n"); 441 push(@out,".ident \"$func\"\n");
381 $stack=0; 442 $stack=0;
382 %label=(); 443 %label=();
@@ -402,13 +463,13 @@ sub main'function_end_B
402 463
403 $func=$under.$func; 464 $func=$under.$func;
404 465
405 push(@out,".L_${func}_end:\n"); 466 push(@out,"${dot}L_${func}_end:\n");
406 if ($main'cpp) 467 if ($main'cpp)
407 { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } 468 { push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); }
408 elsif ($main'gaswin) 469 elsif ($main'coff or $main'aout)
409 { push(@out,"\t.align 4\n"); } 470 { }
410 else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } 471 else { push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); }
411 push(@out,".ident \"desasm.pl\"\n"); 472 push(@out,".ident \"$func\"\n");
412 $stack=0; 473 $stack=0;
413 %label=(); 474 %label=();
414 } 475 }
@@ -449,10 +510,10 @@ sub main'swtmp
449 510
450sub main'comment 511sub main'comment
451 { 512 {
452 if (!$main'openbsd && $main'elf) 513 if (!defined($com_start) or $main'elf)
514 { # Regarding $main'elf above...
453 # GNU and SVR4 as'es use different comment delimiters, 515 # GNU and SVR4 as'es use different comment delimiters,
454 { # so we just skip comments... 516 push(@out,"\n"); # so we just skip ELF comments...
455 push(@out,"\n");
456 return; 517 return;
457 } 518 }
458 foreach (@_) 519 foreach (@_)
@@ -465,16 +526,16 @@ sub main'comment
465 } 526 }
466 527
467sub main'public_label 528sub main'public_label
468 { 529 {
469 $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]})); 530 $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]}));
470 push(@out,".globl\t$label{$_[0]}\n"); 531 push(@out,".globl\t$label{$_[0]}\n");
471 } 532 }
472 533
473sub main'label 534sub main'label
474 { 535 {
475 if (!defined($label{$_[0]})) 536 if (!defined($label{$_[0]}))
476 { 537 {
477 $label{$_[0]}=".${label}${_[0]}"; 538 $label{$_[0]}="${dot}${label}${_[0]}";
478 $label++; 539 $label++;
479 } 540 }
480 return($label{$_[0]}); 541 return($label{$_[0]});
@@ -484,18 +545,35 @@ sub main'set_label
484 { 545 {
485 if (!defined($label{$_[0]})) 546 if (!defined($label{$_[0]}))
486 { 547 {
487 $label{$_[0]}=".${label}${_[0]}"; 548 $label{$_[0]}="${dot}${label}${_[0]}";
488 $label++; 549 $label++;
489 } 550 }
490 if ($main'openbsd) 551 if ($_[1]!=0)
491 { push(@out,"_ALIGN_TEXT\n") if ($_[1] != 0); } 552 {
492 else 553 if ($_[1]>1) { main'align($_[1]); }
493 { push(@out,".align $align\n") if ($_[1] != 0); } 554 else
555 {
556 if ($main'openbsd)
557 { push(@out,"_ALIGN_TEXT\n"); }
558 else
559 { push(@out,".align $align\n"); }
560 }
561 }
494 push(@out,"$label{$_[0]}:\n"); 562 push(@out,"$label{$_[0]}:\n");
495 } 563 }
496 564
497sub main'file_end 565sub main'file_end
498 { 566 {
567 # try to detect if SSE2 or MMX extensions were used on ELF platform...
568 if ($main'elf && grep {/\b%[x]*mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) {
569 local($tmp);
570
571 push (@out,"\n.section\t.bss\n");
572 push (@out,".comm\t${under}OPENSSL_ia32cap_P,4,4\n");
573
574 return;
575 }
576
499 if ($const ne "") 577 if ($const ne "")
500 { 578 {
501 push(@out,".section .rodata\n"); 579 push(@out,".section .rodata\n");
@@ -504,11 +582,31 @@ sub main'file_end
504 } 582 }
505 } 583 }
506 584
585sub main'data_byte
586 {
587 push(@out,"\t.byte\t".join(',',@_)."\n");
588 }
589
507sub main'data_word 590sub main'data_word
508 { 591 {
509 push(@out,"\t.long\t".join(',',@_)."\n"); 592 push(@out,"\t.long\t".join(',',@_)."\n");
510 } 593 }
511 594
595sub main'align
596 {
597 my $val=$_[0],$p2,$i;
598 if ($main'aout) {
599 for ($p2=0;$val!=0;$val>>=1) { $p2++; }
600 $val=$p2-1;
601 $val.=",0x90";
602 }
603 push(@out,".align\t$val\n");
604 if ($main'openbsd)
605 { push(@out,"_ALIGN_TEXT\n"); }
606 else
607 { push(@out,".align $tval\n"); }
608 }
609
512# debug output functions: puts, putx, printf 610# debug output functions: puts, putx, printf
513 611
514sub main'puts 612sub main'puts
@@ -588,7 +686,6 @@ sub main'picmeup
588 { 686 {
589 local($tmp)=<<___; 687 local($tmp)=<<___;
590#if (defined(ELF) || defined(SOL)) && defined(PIC) 688#if (defined(ELF) || defined(SOL)) && defined(PIC)
591 .align 8
592 call 1f 689 call 1f
5931: popl $regs{$dst} 6901: popl $regs{$dst}
594 addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst} 691 addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst}
@@ -611,13 +708,12 @@ ___
611 } 708 }
612 elsif ($main'pic && ($main'elf || $main'aout)) 709 elsif ($main'pic && ($main'elf || $main'aout))
613 { 710 {
614 push(@out,"\t.align\t8\n");
615 &main'call(&main'label("PIC_me_up")); 711 &main'call(&main'label("PIC_me_up"));
616 &main'set_label("PIC_me_up"); 712 &main'set_label("PIC_me_up");
617 &main'blindpop($dst); 713 &main'blindpop($dst);
618 &main'add($dst,"\$$under"."_GLOBAL_OFFSET_TABLE_+[.-". 714 &main'add($dst,"\$${under}_GLOBAL_OFFSET_TABLE_+[.-".
619 &main'label("PIC_me_up") . "]"); 715 &main'label("PIC_me_up") . "]");
620 &main'mov($dst,&main'DWP($sym."\@GOT",$dst)); 716 &main'mov($dst,&main'DWP($under.$sym."\@GOT",$dst));
621 } 717 }
622 else 718 else
623 { 719 {
@@ -626,3 +722,41 @@ ___
626 } 722 }
627 723
628sub main'blindpop { &out1("popl",@_); } 724sub main'blindpop { &out1("popl",@_); }
725
726sub main'initseg
727 {
728 local($f)=@_;
729 local($tmp);
730 if ($main'elf)
731 {
732 $tmp=<<___;
733.section .init
734 call $under$f
735 jmp .Linitalign
736.align $align
737.Linitalign:
738___
739 }
740 elsif ($main'coff)
741 {
742 $tmp=<<___; # applies to both Cygwin and Mingw
743.section .ctors
744.long $under$f
745___
746 }
747 elsif ($main'aout)
748 {
749 local($ctor)="${under}_GLOBAL_\$I\$$f";
750 $tmp=".text\n";
751 $tmp.=".type $ctor,\@function\n" if ($main'pic);
752 $tmp.=<<___; # OpenBSD way...
753.globl $ctor
754.align 2
755$ctor:
756 jmp $under$f
757___
758 }
759 push(@out,$tmp) if ($tmp);
760 }
761
7621;