diff options
author | 2008-09-06 12:17:47 +0000 | |
---|---|---|
committer | 2008-09-06 12:17:47 +0000 | |
commit | 4fcf65c5c59fcf6124cf9f1fd81aa546850f974c (patch) | |
tree | 3c0b4c46d91bcb87c8eef7a1e84711159b17f71b /lib/libssl/src/crypto/perlasm | |
parent | import of OpenSSL 0.9.8h (diff) | |
download | wireguard-openbsd-4fcf65c5c59fcf6124cf9f1fd81aa546850f974c.tar.xz wireguard-openbsd-4fcf65c5c59fcf6124cf9f1fd81aa546850f974c.zip |
resolve conflicts
Diffstat (limited to 'lib/libssl/src/crypto/perlasm')
-rw-r--r-- | lib/libssl/src/crypto/perlasm/cbc.pl | 4 | ||||
-rw-r--r-- | lib/libssl/src/crypto/perlasm/x86asm.pl | 27 | ||||
-rw-r--r-- | lib/libssl/src/crypto/perlasm/x86ms.pl | 122 | ||||
-rw-r--r-- | lib/libssl/src/crypto/perlasm/x86nasm.pl | 153 | ||||
-rw-r--r-- | lib/libssl/src/crypto/perlasm/x86unix.pl | 234 |
5 files changed, 427 insertions, 113 deletions
diff --git a/lib/libssl/src/crypto/perlasm/cbc.pl b/lib/libssl/src/crypto/perlasm/cbc.pl index 22149c680ec..e43dc9ae15e 100644 --- a/lib/libssl/src/crypto/perlasm/cbc.pl +++ b/lib/libssl/src/crypto/perlasm/cbc.pl @@ -322,7 +322,8 @@ sub cbc &function_end_A($name); - &set_label("cbc_enc_jmp_table",1); + &align(64); + &set_label("cbc_enc_jmp_table"); &data_word("0"); &data_word(&label("ej1")."-".&label("PIC_point")); &data_word(&label("ej2")."-".&label("PIC_point")); @@ -341,6 +342,7 @@ sub cbc #&data_word(&label("dj5")."-".&label("PIC_point")); #&data_word(&label("dj6")."-".&label("PIC_point")); #&data_word(&label("dj7")."-".&label("PIC_point")); + &align(64); &function_end_B($name); diff --git a/lib/libssl/src/crypto/perlasm/x86asm.pl b/lib/libssl/src/crypto/perlasm/x86asm.pl index c3de90c65d7..f535c9c7fab 100644 --- a/lib/libssl/src/crypto/perlasm/x86asm.pl +++ b/lib/libssl/src/crypto/perlasm/x86asm.pl @@ -18,7 +18,7 @@ sub main'asm_init ($type,$fn,$i386)=@_; $filename=$fn; - $elf=$cpp=$sol=$aout=$win32=$gaswin=$openbsd=0; + $elf=$cpp=$coff=$aout=$win32=$netware=$mwerks=$openbsd=0; if ( ($type eq "elf")) { $elf=1; require "x86unix.pl"; } elsif ( ($type eq "openbsd-elf")) @@ -27,28 +27,31 @@ sub main'asm_init { $openbsd=1; require "x86unix.pl"; } elsif ( ($type eq "a.out")) { $aout=1; require "x86unix.pl"; } - elsif ( ($type eq "gaswin")) - { $gaswin=1; $aout=1; require "x86unix.pl"; } - elsif ( ($type eq "sol")) - { $sol=1; require "x86unix.pl"; } + elsif ( ($type eq "coff" or $type eq "gaswin")) + { $coff=1; require "x86unix.pl"; } elsif ( ($type eq "cpp")) { $cpp=1; require "x86unix.pl"; } elsif ( ($type eq "win32")) { $win32=1; require "x86ms.pl"; } elsif ( ($type eq "win32n")) { $win32=1; require "x86nasm.pl"; } + elsif ( ($type eq "nw-nasm")) + { $netware=1; require "x86nasm.pl"; } + elsif ( ($type eq "nw-mwasm")) + { $netware=1; $mwerks=1; require "x86nasm.pl"; } else { print STDERR <<"EOF"; Pick one target type from - elf - linux, FreeBSD etc - a.out - old linux - sol - x86 solaris - cpp - format so x86unix.cpp can be used + elf - Linux, FreeBSD, Solaris x86, etc. + a.out - OpenBSD, DJGPP, etc. + coff - GAS/COFF such as Win32 targets win32 - Windows 95/Windows NT win32n - Windows 95/Windows NT NASM format openbsd-elf - OpenBSD elf openbsd-a.out - OpenBSD a.out + nw-nasm - NetWare NASM format + nw-mwasm- NetWare Metrowerks Assembler EOF exit(1); } @@ -61,7 +64,7 @@ EOF &comment("Don't even think of reading this code"); &comment("It was automatically generated by $filename"); &comment("Which is a perl program used to generate the x86 assember for"); -&comment("any of elf, a.out, BSDI, Win32, gaswin (for GNU as on Win32) or Solaris"); +&comment("any of ELF, a.out, COFF, Win32, ..."); &comment("eric <eay\@cryptsoft.com>"); &comment(""); @@ -96,7 +99,7 @@ $tmp #ifdef OUT #define OK 1 #define ALIGN 4 -#if defined(__CYGWIN__) || defined(__DJGPP__) || defined(__MINGW32__) +#if defined(__CYGWIN__) || defined(__DJGPP__) || (__MINGW32__) #undef SIZE #undef TYPE #define SIZE(a,b) @@ -130,6 +133,4 @@ BSDI - a.out with a very primative version of as. EOF } -sub main'align() {} # swallow align statements in 0.9.7 context - 1; diff --git a/lib/libssl/src/crypto/perlasm/x86ms.pl b/lib/libssl/src/crypto/perlasm/x86ms.pl index b6bd744057e..a0be2934c20 100644 --- a/lib/libssl/src/crypto/perlasm/x86ms.pl +++ b/lib/libssl/src/crypto/perlasm/x86ms.pl @@ -27,7 +27,13 @@ $label="L000"; sub main'asm_init_output { @out=(); } sub main'asm_get_output { return(@out); } sub main'get_labels { return(@labels); } -sub main'external_label { push(@labels,@_); } +sub main'external_label +{ + push(@labels,@_); + foreach (@_) { + push(@out, "EXTRN\t_$_:DWORD\n"); + } +} sub main'LB { @@ -51,6 +57,11 @@ sub main'DWP &get_mem("DWORD",@_); } +sub main'QWP + { + &get_mem("QWORD",@_); + } + sub main'BC { return @_; @@ -87,7 +98,7 @@ sub get_mem $reg2=&conv($1); $addr="_$2"; } - elsif ($addr =~ /^[_a-zA-Z]/) + elsif ($addr =~ /^[_a-z][_a-z0-9]*$/i) { $addr="_$addr"; } @@ -128,12 +139,14 @@ sub main'xorb { &out2("xor",@_); } sub main'add { &out2("add",@_); } sub main'adc { &out2("adc",@_); } sub main'sub { &out2("sub",@_); } +sub main'sbb { &out2("sbb",@_); } sub main'rotl { &out2("rol",@_); } sub main'rotr { &out2("ror",@_); } sub main'exch { &out2("xchg",@_); } sub main'cmp { &out2("cmp",@_); } sub main'lea { &out2("lea",@_); } sub main'mul { &out1("mul",@_); } +sub main'imul { &out2("imul",@_); } sub main'div { &out1("div",@_); } sub main'dec { &out1("dec",@_); } sub main'inc { &out1("inc",@_); } @@ -155,26 +168,54 @@ sub main'jne { &out1("jne",@_); } sub main'jno { &out1("jno",@_); } sub main'push { &out1("push",@_); $stack+=4; } sub main'pop { &out1("pop",@_); $stack-=4; } +sub main'pushf { &out0("pushfd"); $stack+=4; } +sub main'popf { &out0("popfd"); $stack-=4; } sub main'bswap { &out1("bswap",@_); &using486(); } sub main'not { &out1("not",@_); } sub main'call { &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); } +sub main'call_ptr { &out1p("call",@_); } sub main'ret { &out0("ret"); } sub main'nop { &out0("nop"); } +sub main'test { &out2("test",@_); } +sub main'bt { &out2("bt",@_); } +sub main'leave { &out0("leave"); } +sub main'cpuid { &out0("DW\t0A20Fh"); } +sub main'rdtsc { &out0("DW\t0310Fh"); } +sub main'halt { &out0("hlt"); } sub main'movz { &out2("movzx",@_); } +sub main'neg { &out1("neg",@_); } +sub main'cld { &out0("cld"); } + +# SSE2 +sub main'emms { &out0("emms"); } +sub main'movd { &out2("movd",@_); } +sub main'movq { &out2("movq",@_); } +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 out2 { local($name,$p1,$p2)=@_; - local($l,$t); + local($l,$t,$line); - push(@out,"\t$name\t"); + $line="\t$name\t"; $t=&conv($p1).","; $l=length($t); - push(@out,$t); + $line.="$t"; $l=4-($l+9)/8; - push(@out,"\t" x $l); - push(@out,&conv($p2)); - push(@out,"\n"); + $line.="\t" x $l; + $line.=&conv($p2); + if ($line=~/\bxmm[0-7]\b/i) { $line=~s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i; } + push(@out,$line."\n"); } sub out0 @@ -214,7 +255,9 @@ sub main'file local($tmp)=<<"EOF"; TITLE $file.asm .386 -.model FLAT +.model FLAT +_TEXT\$ SEGMENT PAGE 'CODE' + EOF push(@out,$tmp); } @@ -226,7 +269,6 @@ sub main'function_begin push(@labels,$func); local($tmp)=<<"EOF"; -_TEXT SEGMENT PUBLIC _$func $extra _$func PROC NEAR @@ -244,7 +286,6 @@ sub main'function_begin_B local($func,$extra)=@_; local($tmp)=<<"EOF"; -_TEXT SEGMENT PUBLIC _$func $extra _$func PROC NEAR @@ -264,7 +305,6 @@ sub main'function_end pop ebp ret _$func ENDP -_TEXT ENDS EOF push(@out,$tmp); $stack=0; @@ -277,7 +317,6 @@ sub main'function_end_B local($tmp)=<<"EOF"; _$func ENDP -_TEXT ENDS EOF push(@out,$tmp); $stack=0; @@ -300,6 +339,20 @@ EOF sub main'file_end { + # try to detect if SSE2 or MMX extensions were used... + my $xmmheader=<<___; +.686 +.XMM +IF \@Version LT 800 +XMMWORD STRUCT 16 + DQ 2 dup (?) +XMMWORD ENDS +ENDIF +___ + if (grep {/\b[x]?mm[0-7]\b/i} @out) { + grep {s/\.[3-7]86/$xmmheader/} @out; + } + push(@out,"_TEXT\$ ENDS\n"); push(@out,"END\n"); } @@ -331,6 +384,12 @@ sub main'comment } } +sub main'public_label + { + $label{$_[0]}="_$_[0]" if (!defined($label{$_[0]})); + push(@out,"PUBLIC\t$label{$_[0]}\n"); + } + sub main'label { if (!defined($label{$_[0]})) @@ -348,19 +407,37 @@ sub main'set_label $label{$_[0]}="\$${label}${_[0]}"; $label++; } + if ($_[1]!=0 && $_[1]>1) + { + main'align($_[1]); + } if((defined $_[2]) && ($_[2] == 1)) { push(@out,"$label{$_[0]}::\n"); } + elsif ($label{$_[0]} !~ /^\$/) + { + push(@out,"$label{$_[0]}\tLABEL PTR\n"); + } else { push(@out,"$label{$_[0]}:\n"); } } +sub main'data_byte + { + push(@out,"\tDB\t".join(',',@_)."\n"); + } + sub main'data_word { - push(@out,"\tDD\t$_[0]\n"); + push(@out,"\tDD\t".join(',',@_)."\n"); + } + +sub main'align + { + push(@out,"\tALIGN\t$_[0]\n"); } sub out1p @@ -368,7 +445,7 @@ sub out1p local($name,$p1)=@_; local($l,$t); - push(@out,"\t$name\t ".&conv($p1)."\n"); + push(@out,"\t$name\t".&conv($p1)."\n"); } sub main'picmeup @@ -378,3 +455,18 @@ sub main'picmeup } sub main'blindpop { &out1("pop",@_); } + +sub main'initseg + { + local($f)=@_; + local($tmp)=<<___; +OPTION DOTNAME +.CRT\$XCU SEGMENT DWORD PUBLIC 'DATA' +EXTRN _$f:NEAR +DD _$f +.CRT\$XCU ENDS +___ + push(@out,$tmp); + } + +1; diff --git a/lib/libssl/src/crypto/perlasm/x86nasm.pl b/lib/libssl/src/crypto/perlasm/x86nasm.pl index 4bdb3fe1809..fa38f89c09f 100644 --- a/lib/libssl/src/crypto/perlasm/x86nasm.pl +++ b/lib/libssl/src/crypto/perlasm/x86nasm.pl @@ -3,6 +3,7 @@ package x86nasm; $label="L000"; +$under=($main'netware)?'':'_'; %lb=( 'eax', 'al', 'ebx', 'bl', @@ -32,7 +33,8 @@ sub main'external_label { push(@labels,@_); foreach (@_) { - push(@out, "extern\t_$_\n"); + push(@out,".") if ($main'mwerks); + push(@out, "extern\t${under}$_\n"); } } @@ -58,14 +60,19 @@ sub main'DWP &get_mem("DWORD",@_); } +sub main'QWP + { + &get_mem("",@_); + } + sub main'BC { - return "BYTE @_"; + return (($main'mwerks)?"":"BYTE ")."@_"; } sub main'DWC { - return "DWORD @_"; + return (($main'mwerks)?"":"DWORD ")."@_"; } sub main'stack_push @@ -86,16 +93,22 @@ sub get_mem { my($size,$addr,$reg1,$reg2,$idx)=@_; my($t,$post); - my($ret)="$size ["; + my($ret)=$size; + if ($ret ne "") + { + $ret .= " PTR" if ($main'mwerks); + $ret .= " "; + } + $ret .= "["; $addr =~ s/^\s+//; if ($addr =~ /^(.+)\+(.+)$/) { $reg2=&conv($1); - $addr="_$2"; + $addr="$under$2"; } - elsif ($addr =~ /^[_a-zA-Z]/) + elsif ($addr =~ /^[_a-z][_a-z0-9]*$/i) { - $addr="_$addr"; + $addr="$under$addr"; } if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; } @@ -134,12 +147,14 @@ sub main'xorb { &out2("xor",@_); } sub main'add { &out2("add",@_); } sub main'adc { &out2("adc",@_); } sub main'sub { &out2("sub",@_); } +sub main'sbb { &out2("sbb",@_); } sub main'rotl { &out2("rol",@_); } sub main'rotr { &out2("ror",@_); } sub main'exch { &out2("xchg",@_); } sub main'cmp { &out2("cmp",@_); } sub main'lea { &out2("lea",@_); } sub main'mul { &out1("mul",@_); } +sub main'imul { &out2("imul",@_); } sub main'div { &out1("div",@_); } sub main'dec { &out1("dec",@_); } sub main'inc { &out1("inc",@_); } @@ -147,29 +162,57 @@ sub main'jmp { &out1("jmp",@_); } sub main'jmp_ptr { &out1p("jmp",@_); } # This is a bit of a kludge: declare all branches as NEAR. -sub main'je { &out1("je NEAR",@_); } -sub main'jle { &out1("jle NEAR",@_); } -sub main'jz { &out1("jz NEAR",@_); } -sub main'jge { &out1("jge NEAR",@_); } -sub main'jl { &out1("jl NEAR",@_); } -sub main'ja { &out1("ja NEAR",@_); } -sub main'jae { &out1("jae NEAR",@_); } -sub main'jb { &out1("jb NEAR",@_); } -sub main'jbe { &out1("jbe NEAR",@_); } -sub main'jc { &out1("jc NEAR",@_); } -sub main'jnc { &out1("jnc NEAR",@_); } -sub main'jnz { &out1("jnz NEAR",@_); } -sub main'jne { &out1("jne NEAR",@_); } -sub main'jno { &out1("jno NEAR",@_); } +$near=($main'mwerks)?'':'NEAR'; +sub main'je { &out1("je $near",@_); } +sub main'jle { &out1("jle $near",@_); } +sub main'jz { &out1("jz $near",@_); } +sub main'jge { &out1("jge $near",@_); } +sub main'jl { &out1("jl $near",@_); } +sub main'ja { &out1("ja $near",@_); } +sub main'jae { &out1("jae $near",@_); } +sub main'jb { &out1("jb $near",@_); } +sub main'jbe { &out1("jbe $near",@_); } +sub main'jc { &out1("jc $near",@_); } +sub main'jnc { &out1("jnc $near",@_); } +sub main'jnz { &out1("jnz $near",@_); } +sub main'jne { &out1("jne $near",@_); } +sub main'jno { &out1("jno $near",@_); } sub main'push { &out1("push",@_); $stack+=4; } sub main'pop { &out1("pop",@_); $stack-=4; } +sub main'pushf { &out0("pushfd"); $stack+=4; } +sub main'popf { &out0("popfd"); $stack-=4; } sub main'bswap { &out1("bswap",@_); &using486(); } sub main'not { &out1("not",@_); } -sub main'call { &out1("call",($_[0]=~/^\$L/?'':'_').$_[0]); } +sub main'call { &out1("call",($_[0]=~/^\@L/?'':$under).$_[0]); } +sub main'call_ptr { &out1p("call",@_); } sub main'ret { &out0("ret"); } sub main'nop { &out0("nop"); } +sub main'test { &out2("test",@_); } +sub main'bt { &out2("bt",@_); } +sub main'leave { &out0("leave"); } +sub main'cpuid { &out0("cpuid"); } +sub main'rdtsc { &out0("rdtsc"); } +sub main'halt { &out0("hlt"); } sub main'movz { &out2("movzx",@_); } +sub main'neg { &out1("neg",@_); } +sub main'cld { &out0("cld"); } + +# SSE2 +sub main'emms { &out0("emms"); } +sub main'movd { &out2("movd",@_); } +sub main'movq { &out2("movq",@_); } +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 out2 { @@ -177,7 +220,7 @@ sub out2 my($l,$t); push(@out,"\t$name\t"); - if ($name eq "lea") + if (!$main'mwerks and $name eq "lea") { $p1 =~ s/^[^\[]*\[/\[/; $p2 =~ s/^[^\[]*\[/\[/; @@ -221,15 +264,17 @@ sub using486 sub main'file { - local $tmp; - $tmp=<<___; + if ($main'mwerks) { push(@out,".section\t.text\n"); } + else { + local $tmp=<<___; %ifdef __omf__ section code use32 class=code %else section .text %endif ___ - push(@out,$tmp); + push(@out,$tmp); + } } sub main'function_begin @@ -237,9 +282,10 @@ sub main'function_begin my($func,$extra)=@_; push(@labels,$func); + push(@out,".") if ($main'mwerks); my($tmp)=<<"EOF"; -global _$func -_$func: +global $under$func +$under$func: push ebp push ebx push esi @@ -252,9 +298,10 @@ EOF sub main'function_begin_B { my($func,$extra)=@_; + push(@out,".") if ($main'mwerks); my($tmp)=<<"EOF"; -global _$func -_$func: +global $under$func +$under$func: EOF push(@out,$tmp); $stack=4; @@ -328,11 +375,18 @@ sub main'comment } } +sub main'public_label + { + $label{$_[0]}="${under}${_[0]}" if (!defined($label{$_[0]})); + push(@out,".") if ($main'mwerks); + push(@out,"global\t$label{$_[0]}\n"); + } + sub main'label { if (!defined($label{$_[0]})) { - $label{$_[0]}="\$${label}${_[0]}"; + $label{$_[0]}="\@${label}${_[0]}"; $label++; } return($label{$_[0]}); @@ -342,15 +396,30 @@ sub main'set_label { if (!defined($label{$_[0]})) { - $label{$_[0]}="\$${label}${_[0]}"; + $label{$_[0]}="\@${label}${_[0]}"; $label++; } + if ($_[1]!=0 && $_[1]>1) + { + main'align($_[1]); + } push(@out,"$label{$_[0]}:\n"); } +sub main'data_byte + { + push(@out,(($main'mwerks)?".byte\t":"DB\t").join(',',@_)."\n"); + } + sub main'data_word { - push(@out,"\tDD\t$_[0]\n"); + push(@out,(($main'mwerks)?".long\t":"DD\t").join(',',@_)."\n"); + } + +sub main'align + { + push(@out,".") if ($main'mwerks); + push(@out,"align\t$_[0]\n"); } sub out1p @@ -358,7 +427,7 @@ sub out1p my($name,$p1)=@_; my($l,$t); - push(@out,"\t$name\t ".&conv($p1)."\n"); + push(@out,"\t$name\t".&conv($p1)."\n"); } sub main'picmeup @@ -368,3 +437,19 @@ sub main'picmeup } sub main'blindpop { &out1("pop",@_); } + +sub main'initseg + { + local($f)=@_; + if ($main'win32) + { + local($tmp)=<<___; +segment .CRT\$XCU data +extern $under$f +DD $under$f +___ + push(@out,$tmp); + } + } + +1; diff --git a/lib/libssl/src/crypto/perlasm/x86unix.pl b/lib/libssl/src/crypto/perlasm/x86unix.pl index b61425e9519..02d72a32bcd 100644 --- a/lib/libssl/src/crypto/perlasm/x86unix.pl +++ b/lib/libssl/src/crypto/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; |