From 38ce604e3cc97706b876b0525ddff0121115456d Mon Sep 17 00:00:00 2001 From: djm <> Date: Sat, 6 Sep 2008 12:17:54 +0000 Subject: resolve conflicts --- src/lib/libcrypto/perlasm/x86unix.pl | 234 +++++++++++++++++++++++++++-------- 1 file changed, 184 insertions(+), 50 deletions(-) (limited to 'src/lib/libcrypto/perlasm/x86unix.pl') 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 @@ #!/usr/local/bin/perl -package x86unix; +package x86unix; # GAS actually... $label="L000"; $const=""; $constl=0; $align=($main'aout)?"4":"16"; -$under=($main'aout)?"_":""; -$com_start=($main'sol)?"/":"#"; +$under=($main'aout or $main'coff)?"_":""; +$dot=($main'aout)?"":"."; +$com_start="#" if ($main'aout or $main'coff); sub main'asm_init_output { @out=(); } sub main'asm_get_output { return(@out); } @@ -57,6 +58,24 @@ if ($main'cpp) 'edi', '%edi', 'ebp', '%ebp', 'esp', '%esp', + + 'mm0', '%mm0', + 'mm1', '%mm1', + 'mm2', '%mm2', + 'mm3', '%mm3', + 'mm4', '%mm4', + 'mm5', '%mm5', + 'mm6', '%mm6', + 'mm7', '%mm7', + + 'xmm0', '%xmm0', + 'xmm1', '%xmm1', + 'xmm2', '%xmm2', + 'xmm3', '%xmm3', + 'xmm4', '%xmm4', + 'xmm5', '%xmm5', + 'xmm6', '%xmm6', + 'xmm7', '%xmm7', ); %reg_val=( @@ -103,6 +122,11 @@ sub main'DWP return($ret); } +sub main'QWP + { + return(&main'DWP(@_)); + } + sub main'BP { return(&main'DWP(@_)); @@ -146,12 +170,14 @@ sub main'xorb { &out2("xorb",@_); } sub main'add { &out2($_[0]=~/%[a-d][lh]/?"addb":"addl",@_); } sub main'adc { &out2("adcl",@_); } sub main'sub { &out2("subl",@_); } +sub main'sbb { &out2("sbbl",@_); } sub main'rotl { &out2("roll",@_); } sub main'rotr { &out2("rorl",@_); } sub main'exch { &out2($_[0]=~/%[a-d][lh]/?"xchgb":"xchgl",@_); } sub main'cmp { &out2("cmpl",@_); } sub main'lea { &out2("leal",@_); } sub main'mul { &out1("mull",@_); } +sub main'imul { &out2("imull",@_); } sub main'div { &out1("divl",@_); } sub main'jmp { &out1("jmp",@_); } sub main'jmp_ptr { &out1p("jmp",@_); } @@ -173,15 +199,48 @@ sub main'dec { &out1("decl",@_); } sub main'inc { &out1($_[0]=~/%[a-d][hl]/?"incb":"incl",@_); } sub main'push { &out1("pushl",@_); $stack+=4; } sub main'pop { &out1("popl",@_); $stack-=4; } -sub main'pushf { &out0("pushf"); $stack+=4; } -sub main'popf { &out0("popf"); $stack-=4; } +sub main'pushf { &out0("pushfl"); $stack+=4; } +sub main'popf { &out0("popfl"); $stack-=4; } sub main'not { &out1("notl",@_); } -sub main'call { &out1("call",($_[0]=~/^\.L/?'':$under).$_[0]); } +sub main'call { my $pre=$under; + foreach $i (%label) + { if ($label{$i} eq $_[0]) { $pre=''; last; } } + &out1("call",$pre.$_[0]); + } +sub main'call_ptr { &out1p("call",@_); } sub main'ret { &out0("ret"); } sub main'nop { &out0("nop"); } -sub main'test { &out2("testl",@_); } +sub main'test { &out2("testl",@_); } +sub main'bt { &out2("btl",@_); } +sub main'leave { &out0("leave"); } +sub main'cpuid { &out0(".byte\t0x0f,0xa2"); } +sub main'rdtsc { &out0(".byte\t0x0f,0x31"); } +sub main'halt { &out0("hlt"); } sub main'movz { &out2("movzbl",@_); } -sub main'neg { &out1("negl",@_); } +sub main'neg { &out1("negl",@_); } +sub main'cld { &out0("cld"); } + +# SSE2 +sub main'emms { &out0("emms"); } +sub main'movd { &out2("movd",@_); } +sub main'movdqu { &out2("movdqu",@_); } +sub main'movdqa { &out2("movdqa",@_); } +sub main'movdq2q{ &out2("movdq2q",@_); } +sub main'movq2dq{ &out2("movq2dq",@_); } +sub main'paddq { &out2("paddq",@_); } +sub main'pmuludq{ &out2("pmuludq",@_); } +sub main'psrlq { &out2("psrlq",@_); } +sub main'psllq { &out2("psllq",@_); } +sub main'pxor { &out2("pxor",@_); } +sub main'por { &out2("por",@_); } +sub main'pand { &out2("pand",@_); } +sub main'movq { + local($p1,$p2,$optimize)=@_; + if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/) + # movq between mmx registers can sink Intel CPUs + { push(@out,"\tpshufw\t\$0xe4,%$p2,%$p1\n"); } + else { &out2("movq",@_); } + } # The bswapl instruction is new for the 486. Emulate if i386. sub main'bswap @@ -290,8 +349,6 @@ sub main'file local($tmp)=<<"EOF"; .file "$file.s" - .version "01.01" -gcc2_compiled.: EOF push(@out,$tmp); } @@ -308,15 +365,17 @@ sub main'function_begin local($tmp)=<<"EOF"; .text - .align $align -.globl $func +.globl $func EOF push(@out,$tmp); if ($main'cpp) - { $tmp=push(@out,"\tTYPE($func,\@function)\n"); } - elsif ($main'gaswin) - { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } - else { $tmp=push(@out,"\t.type\t$func,\@function\n"); } + { $tmp=push(@out,"TYPE($func,\@function)\n"); } + elsif ($main'coff) + { $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } + elsif ($main'aout and !$main'pic) + { } + else { $tmp=push(@out,".type\t$func,\@function\n"); } + push(@out,".align\t$align\n"); push(@out,"$func:\n"); skip: $tmp=<<"EOF"; @@ -342,15 +401,17 @@ sub main'function_begin_B local($tmp)=<<"EOF"; .text - .align $align -.globl $func +.globl $func EOF push(@out,$tmp); if ($main'cpp) - { push(@out,"\tTYPE($func,\@function)\n"); } - elsif ($main'gaswin) - { $tmp=push(@out,"\t.def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } - else { push(@out,"\t.type $func,\@function\n"); } + { push(@out,"TYPE($func,\@function)\n"); } + elsif ($main'coff) + { $tmp=push(@out,".def\t$func;\t.scl\t2;\t.type\t32;\t.endef\n"); } + elsif ($main'aout and !$main'pic) + { } + else { push(@out,".type $func,\@function\n"); } + push(@out,".align\t$align\n"); push(@out,"$func:\n"); skip: $stack=4; @@ -368,15 +429,15 @@ sub main'function_end popl %ebx popl %ebp ret -.L_${func}_end: +${dot}L_${func}_end: EOF push(@out,$tmp); if ($main'cpp) - { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } - elsif ($main'gaswin) - { $tmp=push(@out,"\t.align 4\n"); } - else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } + { push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); } + elsif ($main'coff or $main'aout) + { } + else { push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); } push(@out,".ident \"$func\"\n"); $stack=0; %label=(); @@ -402,13 +463,13 @@ sub main'function_end_B $func=$under.$func; - push(@out,".L_${func}_end:\n"); + push(@out,"${dot}L_${func}_end:\n"); if ($main'cpp) - { push(@out,"\tSIZE($func,.L_${func}_end-$func)\n"); } - elsif ($main'gaswin) - { push(@out,"\t.align 4\n"); } - else { push(@out,"\t.size\t$func,.L_${func}_end-$func\n"); } - push(@out,".ident \"desasm.pl\"\n"); + { push(@out,"SIZE($func,${dot}L_${func}_end-$func)\n"); } + elsif ($main'coff or $main'aout) + { } + else { push(@out,".size\t$func,${dot}L_${func}_end-$func\n"); } + push(@out,".ident \"$func\"\n"); $stack=0; %label=(); } @@ -449,10 +510,10 @@ sub main'swtmp sub main'comment { - if (!$main'openbsd && $main'elf) + if (!defined($com_start) or $main'elf) + { # Regarding $main'elf above... # GNU and SVR4 as'es use different comment delimiters, - { # so we just skip comments... - push(@out,"\n"); + push(@out,"\n"); # so we just skip ELF comments... return; } foreach (@_) @@ -465,16 +526,16 @@ sub main'comment } sub main'public_label - { - $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]})); - push(@out,".globl\t$label{$_[0]}\n"); - } + { + $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]})); + push(@out,".globl\t$label{$_[0]}\n"); + } sub main'label { if (!defined($label{$_[0]})) { - $label{$_[0]}=".${label}${_[0]}"; + $label{$_[0]}="${dot}${label}${_[0]}"; $label++; } return($label{$_[0]}); @@ -484,18 +545,35 @@ sub main'set_label { if (!defined($label{$_[0]})) { - $label{$_[0]}=".${label}${_[0]}"; + $label{$_[0]}="${dot}${label}${_[0]}"; $label++; } - if ($main'openbsd) - { push(@out,"_ALIGN_TEXT\n") if ($_[1] != 0); } - else - { push(@out,".align $align\n") if ($_[1] != 0); } + if ($_[1]!=0) + { + if ($_[1]>1) { main'align($_[1]); } + else + { + if ($main'openbsd) + { push(@out,"_ALIGN_TEXT\n"); } + else + { push(@out,".align $align\n"); } + } + } push(@out,"$label{$_[0]}:\n"); } sub main'file_end { + # try to detect if SSE2 or MMX extensions were used on ELF platform... + if ($main'elf && grep {/\b%[x]*mm[0-7]\b|OPENSSL_ia32cap_P\b/i} @out) { + local($tmp); + + push (@out,"\n.section\t.bss\n"); + push (@out,".comm\t${under}OPENSSL_ia32cap_P,4,4\n"); + + return; + } + if ($const ne "") { push(@out,".section .rodata\n"); @@ -504,11 +582,31 @@ sub main'file_end } } +sub main'data_byte + { + push(@out,"\t.byte\t".join(',',@_)."\n"); + } + sub main'data_word { push(@out,"\t.long\t".join(',',@_)."\n"); } +sub main'align + { + my $val=$_[0],$p2,$i; + if ($main'aout) { + for ($p2=0;$val!=0;$val>>=1) { $p2++; } + $val=$p2-1; + $val.=",0x90"; + } + push(@out,".align\t$val\n"); + if ($main'openbsd) + { push(@out,"_ALIGN_TEXT\n"); } + else + { push(@out,".align $tval\n"); } + } + # debug output functions: puts, putx, printf sub main'puts @@ -588,7 +686,6 @@ sub main'picmeup { local($tmp)=<<___; #if (defined(ELF) || defined(SOL)) && defined(PIC) - .align 8 call 1f 1: popl $regs{$dst} addl \$_GLOBAL_OFFSET_TABLE_+[.-1b],$regs{$dst} @@ -611,13 +708,12 @@ ___ } elsif ($main'pic && ($main'elf || $main'aout)) { - push(@out,"\t.align\t8\n"); &main'call(&main'label("PIC_me_up")); &main'set_label("PIC_me_up"); &main'blindpop($dst); - &main'add($dst,"\$$under"."_GLOBAL_OFFSET_TABLE_+[.-". + &main'add($dst,"\$${under}_GLOBAL_OFFSET_TABLE_+[.-". &main'label("PIC_me_up") . "]"); - &main'mov($dst,&main'DWP($sym."\@GOT",$dst)); + &main'mov($dst,&main'DWP($under.$sym."\@GOT",$dst)); } else { @@ -626,3 +722,41 @@ ___ } sub main'blindpop { &out1("popl",@_); } + +sub main'initseg + { + local($f)=@_; + local($tmp); + if ($main'elf) + { + $tmp=<<___; +.section .init + call $under$f + jmp .Linitalign +.align $align +.Linitalign: +___ + } + elsif ($main'coff) + { + $tmp=<<___; # applies to both Cygwin and Mingw +.section .ctors +.long $under$f +___ + } + elsif ($main'aout) + { + local($ctor)="${under}_GLOBAL_\$I\$$f"; + $tmp=".text\n"; + $tmp.=".type $ctor,\@function\n" if ($main'pic); + $tmp.=<<___; # OpenBSD way... +.globl $ctor +.align 2 +$ctor: + jmp $under$f +___ + } + push(@out,$tmp) if ($tmp); + } + +1; -- cgit v1.2.3-55-g6feb