Proper support for OpenBSD-i386 shared build, including assember modules!
[oweals/openssl.git] / crypto / perlasm / x86nasm.pl
index 519d8a5867287aa962648ba1990f37631d5a8d9d..b02de6452a49c820fb249fecfcd6ff6741544dde 100644 (file)
@@ -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,18 +93,26 @@ sub get_mem
        {
        my($size,$addr,$reg1,$reg2,$idx)=@_;
        my($t,$post);
-       my($ret)="[";
+       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]/)
                {
-               $addr="_$addr";
+               $addr="$under$addr";
                }
 
+       if ($addr =~ /^.+\-.+$/) { $addr="($addr)"; }
+
        $reg1="$regs{$reg1}" if defined($regs{$reg1});
        $reg2="$regs{$reg2}" if defined($regs{$reg2});
        if (($addr ne "") && ($addr ne 0))
@@ -117,6 +132,7 @@ sub get_mem
                {
                $ret.="$reg1$post]"
                }
+       $ret =~ s/\+\]/]/; # in case $addr was the only argument
        return($ret);
        }
 
@@ -144,25 +160,52 @@ 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'jb    { &out1("jb 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("pushf"); $stack+=4; }
+sub main'popf  { &out0("popf"); $stack-=4; }
 sub main'bswap { &out1("bswap",@_); &using486(); }
 sub main'not   { &out1("not",@_); }
-sub main'call  { &out1("call",'_'.$_[0]); }
+sub main'call  { &out1("call",($_[0]=~/^\@L/?'':$under).$_[0]); }
 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"); }
+
+# 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
        {
@@ -170,6 +213,11 @@ sub out2
        my($l,$t);
 
        push(@out,"\t$name\t");
+       if (!$main'mwerks and $name eq "lea")
+               {
+               $p1 =~ s/^[^\[]*\[/\[/;
+               $p2 =~ s/^[^\[]*\[/\[/;
+               }
        $t=&conv($p1).",";
        $l=length($t);
        push(@out,$t);
@@ -209,7 +257,8 @@ sub using486
 
 sub main'file
        {
-       push(@out, "segment .text use32\n");
+       push(@out,".") if ($main'mwerks);
+       push(@out,"section\t.text\n");
        }
 
 sub main'function_begin
@@ -218,8 +267,8 @@ sub main'function_begin
 
        push(@labels,$func);
        my($tmp)=<<"EOF";
-global _$func
-_$func:
+global $under$func
+$under$func:
        push    ebp
        push    ebx
        push    esi
@@ -233,8 +282,8 @@ sub main'function_begin_B
        {
        my($func,$extra)=@_;
        my($tmp)=<<"EOF";
-global _$func
-_$func:
+global $under$func
+$under$func:
 EOF
        push(@out,$tmp);
        $stack=4;
@@ -312,7 +361,7 @@ sub main'label
        {
        if (!defined($label{$_[0]}))
                {
-               $label{$_[0]}="\$${label}${_[0]}";
+               $label{$_[0]}="\@${label}${_[0]}";
                $label++;
                }
        return($label{$_[0]});
@@ -322,7 +371,7 @@ sub main'set_label
        {
        if (!defined($label{$_[0]}))
                {
-               $label{$_[0]}="${label}${_[0]}";
+               $label{$_[0]}="\@${label}${_[0]}";
                $label++;
                }
        push(@out,"$label{$_[0]}:\n");
@@ -330,7 +379,13 @@ sub main'set_label
 
 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
@@ -340,3 +395,27 @@ sub out1p
 
        push(@out,"\t$name\t ".&conv($p1)."\n");
        }
+
+sub main'picmeup
+       {
+       local($dst,$sym)=@_;
+       &main'lea($dst,&main'DWP($sym));
+       }
+
+sub main'blindpop { &out1("pop",@_); }
+
+sub main'initseg
+       {
+       local($f)=@_;
+       if ($main'win32)
+               {
+               local($tmp)=<<___;
+segment        .CRT\$XIU data
+extern $under$f
+DD     $under$f
+___
+               push(@out,$tmp);
+               }
+       }
+
+1;