perlasm/x86* update: support for 3 and 4 argument instructions.
authorAndy Polyakov <appro@openssl.org>
Wed, 17 Dec 2008 19:56:48 +0000 (19:56 +0000)
committerAndy Polyakov <appro@openssl.org>
Wed, 17 Dec 2008 19:56:48 +0000 (19:56 +0000)
crypto/perlasm/x86_64-xlate.pl
crypto/perlasm/x86asm.pl
crypto/perlasm/x86gas.pl
crypto/perlasm/x86masm.pl

index 7194b29..3ed7fcd 100755 (executable)
@@ -627,44 +627,42 @@ while($line=<>) {
 
     undef $label;
     undef $opcode;
-    undef $dst;
-    undef $src;
     undef $sz;
+    undef @args;
 
     if ($label=label->re(\$line))      { print $label->out(); }
 
     if (directive->re(\$line)) {
        printf "%s",directive->out();
-    } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: {
+    } elsif ($opcode=opcode->re(\$line)) { ARGUMENT: while (1) {
+       my $arg;
 
-       if ($src=register->re(\$line))  { opcode->size($src->size()); }
-       elsif ($src=const->re(\$line))  { }
-       elsif ($src=ea->re(\$line))     { }
-       elsif ($src=expr->re(\$line))   { }
+       if ($arg=register->re(\$line))  { opcode->size($arg->size()); }
+       elsif ($arg=const->re(\$line))  { }
+       elsif ($arg=ea->re(\$line))     { }
+       elsif ($arg=expr->re(\$line))   { }
+       else                            { last ARGUMENT; }
 
-       last ARGUMENT if ($line !~ /^,/);
-
-       $line = substr($line,1); $line =~ s/^\s+//;
+       push @args,$arg;
 
-       if ($dst=register->re(\$line))  { opcode->size($dst->size()); }
-       elsif ($dst=const->re(\$line))  { }
-       elsif ($dst=ea->re(\$line))     { }
+       last ARGUMENT if ($line !~ /^,/);
 
+       $line =~ s/^,\s*//;
        } # ARGUMENT:
 
        $sz=opcode->size();
 
-       if (defined($dst)) {
+       if ($#args>=0) {
+           my $insn;
            if ($gas) {
-               printf "\t%s\t%s,%s",   $opcode->out($dst->size()),
-                                       $src->out($sz),$dst->out($sz);
+               $insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
            } else {
+               $insn = $opcode->out();
+               @args = reverse(@args);
                undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
-               printf "\t%s\t%s,%s",   $opcode->out(),
-                                       $dst->out($sz),$src->out($sz);
            }
-       } elsif (defined($src)) {
-           printf "\t%s\t%s",$opcode->out(),$src->out($sz);
+           for (@args) { $_ = $_->out($sz); }
+           printf "\t%s\t%s", $insn, join(",",@args);
        } else {
            printf "\t%s",$opcode->out();
        }
index 3ec9722..28080ca 100644 (file)
@@ -17,7 +17,7 @@ $i386=0;
 sub ::AUTOLOAD
 { my $opcode = $AUTOLOAD;
 
-    die "more than 2 arguments passed to $opcode" if ($#_>1);
+    die "more than 4 arguments passed to $opcode" if ($#_>3);
 
     $opcode =~ s/.*:://;
     if    ($opcode =~ /^push/) { $stack+=4; }
@@ -66,8 +66,8 @@ sub ::rotr    { &ror(@_);     }
 sub ::exch     { &xchg(@_);    }
 sub ::halt     { &hlt;         }
 sub ::movz     { &movzx(@_);   }
-sub ::pushf    { &::pushfd;    }
-sub ::popf     { &::popfd;     }
+sub ::pushf    { &pushfd;      }
+sub ::popf     { &popfd;       }
 
 # 3 argument instructions
 sub ::movq
@@ -79,9 +79,6 @@ sub ::movq
     else
     {  &::generic("movq",@_);                  }
 }
-sub ::pshufw   { &::emit("pshufw",@_); }
-sub ::shld     { &::emit("shld",@_);   }
-sub ::shrd     { &::emit("shrd",@_);   }
 
 # label management
 $lbdecor="L";          # local label decoration, set by package
index e3fbb94..6eab727 100644 (file)
@@ -25,24 +25,20 @@ sub opsize()
 # expand opcode with size suffix;
 # prefix numeric constants with $;
 sub ::generic
-{ my($opcode,$dst,$src)=@_;
-  my($tmp,$suffix,@arg);
-
-    if (defined($src))
-    {  $src =~ s/^(e?[a-dsixphl]{2})$/%$1/o;
-       $src =~ s/^(x?mm[0-7])$/%$1/o;
-       $src =~ s/^(\-?[0-9]+)$/\$$1/o;
-       $src =~ s/^(\-?0x[0-9a-f]+)$/\$$1/o;
-       push(@arg,$src);
-    }
-    if (defined($dst))
-    {  $dst =~ s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;
-       $dst =~ s/^(x?mm[0-7])$/%$1/o;
-       $dst =~ s/^(\-?[0-9]+)$/\$$1/o          if(!defined($src));
-       $dst =~ s/^(\-?0x[0-9a-f]+)$/\$$1/o     if(!defined($src));
-       push(@arg,$dst);
+{ my($opcode,@arg)=@_;
+  my($suffix,$dst,$src);
+
+    @arg=reverse(@arg);
+
+    for (@arg)
+    {  s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o;    # gp registers
+       s/^([xy]?mm[0-7])$/%$1/o;               # xmm/mmx registers
+       s/^(\-?[0-9]+)$/\$$1/o;                 # constants
+       s/^(\-?0x[0-9a-f]+)$/\$$1/o;            # constants
     }
 
+    $dst = $arg[$#arg]         if ($#arg>=0);
+    $src = $arg[$#arg-1]       if ($#arg>=1);
     if    ($dst =~ m/^%/o)     { $suffix=&opsize($dst); }
     elsif ($src =~ m/^%/o)     { $suffix=&opsize($src); }
     else                       { $suffix="l";           }
@@ -71,19 +67,6 @@ sub ::jmp_ptr        { &::generic("jmp","*$_[0]");   }
 
 *::bswap = sub { &::emit("bswap","%$_[0]");    } if (!$::i386);
 
-*::pshufw = sub
-{ my($dst,$src,$magic)=@_;
-    &::emit("pshufw","\$$magic","%$src","%$dst");
-};
-*::shld = sub
-{ my($dst,$src,$bits)=@_;
-    &::emit("shldl",$bits eq "cl"?"%cl":"\$$bits","%$src","%$dst");
-};
-*::shrd = sub
-{ my($dst,$src,$bits)=@_;
-    &::emit("shrdl",$bits eq "cl"?"%cl":"\$$bits","%$src","%$dst");
-};
-
 sub ::DWP
 { my($addr,$reg1,$reg2,$idx)=@_;
   my $ret="";
index cde38a1..4eca7bc 100644 (file)
@@ -14,8 +14,7 @@ sub ::generic
 { my ($opcode,@arg)=@_;
 
     # fix hexadecimal constants
-    $arg[0] =~ s/0x([0-9a-f]+)/0$1h/oi if (defined($arg[0]));
-    $arg[1] =~ s/0x([0-9a-f]+)/0$1h/oi if (defined($arg[1]));
+    for (@arg) { s/0x([0-9a-f]+)/0$1h/oi; }
 
     # fix xmm references
     $arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);