From 4db4882402a79345a075c62a87f2fb7cfe89e283 Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Wed, 17 Dec 2008 19:56:48 +0000 Subject: [PATCH] perlasm/x86* update: support for 3 and 4 argument instructions. --- crypto/perlasm/x86_64-xlate.pl | 38 +++++++++++++++---------------- crypto/perlasm/x86asm.pl | 9 +++----- crypto/perlasm/x86gas.pl | 41 ++++++++++------------------------ crypto/perlasm/x86masm.pl | 3 +-- 4 files changed, 34 insertions(+), 57 deletions(-) diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl index 7194b29257..3ed7fcd494 100755 --- a/crypto/perlasm/x86_64-xlate.pl +++ b/crypto/perlasm/x86_64-xlate.pl @@ -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(); } diff --git a/crypto/perlasm/x86asm.pl b/crypto/perlasm/x86asm.pl index 3ec97221a9..28080caaa6 100644 --- a/crypto/perlasm/x86asm.pl +++ b/crypto/perlasm/x86asm.pl @@ -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 diff --git a/crypto/perlasm/x86gas.pl b/crypto/perlasm/x86gas.pl index e3fbb940f0..6eab727fd4 100644 --- a/crypto/perlasm/x86gas.pl +++ b/crypto/perlasm/x86gas.pl @@ -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=""; diff --git a/crypto/perlasm/x86masm.pl b/crypto/perlasm/x86masm.pl index cde38a11a4..4eca7bc367 100644 --- a/crypto/perlasm/x86masm.pl +++ b/crypto/perlasm/x86masm.pl @@ -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); -- 2.25.1