perlasm/x86* update: support for 3 and 4 argument instructions.
This commit is contained in:
parent
6786f52ada
commit
4db4882402
@ -627,44 +627,42 @@ while($line=<>) {
|
|||||||
|
|
||||||
undef $label;
|
undef $label;
|
||||||
undef $opcode;
|
undef $opcode;
|
||||||
undef $dst;
|
|
||||||
undef $src;
|
|
||||||
undef $sz;
|
undef $sz;
|
||||||
|
undef @args;
|
||||||
|
|
||||||
if ($label=label->re(\$line)) { print $label->out(); }
|
if ($label=label->re(\$line)) { print $label->out(); }
|
||||||
|
|
||||||
if (directive->re(\$line)) {
|
if (directive->re(\$line)) {
|
||||||
printf "%s",directive->out();
|
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()); }
|
if ($arg=register->re(\$line)) { opcode->size($arg->size()); }
|
||||||
elsif ($src=const->re(\$line)) { }
|
elsif ($arg=const->re(\$line)) { }
|
||||||
elsif ($src=ea->re(\$line)) { }
|
elsif ($arg=ea->re(\$line)) { }
|
||||||
elsif ($src=expr->re(\$line)) { }
|
elsif ($arg=expr->re(\$line)) { }
|
||||||
|
else { last ARGUMENT; }
|
||||||
|
|
||||||
|
push @args,$arg;
|
||||||
|
|
||||||
last ARGUMENT if ($line !~ /^,/);
|
last ARGUMENT if ($line !~ /^,/);
|
||||||
|
|
||||||
$line = substr($line,1); $line =~ s/^\s+//;
|
$line =~ s/^,\s*//;
|
||||||
|
|
||||||
if ($dst=register->re(\$line)) { opcode->size($dst->size()); }
|
|
||||||
elsif ($dst=const->re(\$line)) { }
|
|
||||||
elsif ($dst=ea->re(\$line)) { }
|
|
||||||
|
|
||||||
} # ARGUMENT:
|
} # ARGUMENT:
|
||||||
|
|
||||||
$sz=opcode->size();
|
$sz=opcode->size();
|
||||||
|
|
||||||
if (defined($dst)) {
|
if ($#args>=0) {
|
||||||
|
my $insn;
|
||||||
if ($gas) {
|
if ($gas) {
|
||||||
printf "\t%s\t%s,%s", $opcode->out($dst->size()),
|
$insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
|
||||||
$src->out($sz),$dst->out($sz);
|
|
||||||
} else {
|
} else {
|
||||||
|
$insn = $opcode->out();
|
||||||
|
@args = reverse(@args);
|
||||||
undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
|
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)) {
|
for (@args) { $_ = $_->out($sz); }
|
||||||
printf "\t%s\t%s",$opcode->out(),$src->out($sz);
|
printf "\t%s\t%s", $insn, join(",",@args);
|
||||||
} else {
|
} else {
|
||||||
printf "\t%s",$opcode->out();
|
printf "\t%s",$opcode->out();
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ $i386=0;
|
|||||||
sub ::AUTOLOAD
|
sub ::AUTOLOAD
|
||||||
{ my $opcode = $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/.*:://;
|
$opcode =~ s/.*:://;
|
||||||
if ($opcode =~ /^push/) { $stack+=4; }
|
if ($opcode =~ /^push/) { $stack+=4; }
|
||||||
@ -66,8 +66,8 @@ sub ::rotr { &ror(@_); }
|
|||||||
sub ::exch { &xchg(@_); }
|
sub ::exch { &xchg(@_); }
|
||||||
sub ::halt { &hlt; }
|
sub ::halt { &hlt; }
|
||||||
sub ::movz { &movzx(@_); }
|
sub ::movz { &movzx(@_); }
|
||||||
sub ::pushf { &::pushfd; }
|
sub ::pushf { &pushfd; }
|
||||||
sub ::popf { &::popfd; }
|
sub ::popf { &popfd; }
|
||||||
|
|
||||||
# 3 argument instructions
|
# 3 argument instructions
|
||||||
sub ::movq
|
sub ::movq
|
||||||
@ -79,9 +79,6 @@ sub ::movq
|
|||||||
else
|
else
|
||||||
{ &::generic("movq",@_); }
|
{ &::generic("movq",@_); }
|
||||||
}
|
}
|
||||||
sub ::pshufw { &::emit("pshufw",@_); }
|
|
||||||
sub ::shld { &::emit("shld",@_); }
|
|
||||||
sub ::shrd { &::emit("shrd",@_); }
|
|
||||||
|
|
||||||
# label management
|
# label management
|
||||||
$lbdecor="L"; # local label decoration, set by package
|
$lbdecor="L"; # local label decoration, set by package
|
||||||
|
@ -25,24 +25,20 @@ sub opsize()
|
|||||||
# expand opcode with size suffix;
|
# expand opcode with size suffix;
|
||||||
# prefix numeric constants with $;
|
# prefix numeric constants with $;
|
||||||
sub ::generic
|
sub ::generic
|
||||||
{ my($opcode,$dst,$src)=@_;
|
{ my($opcode,@arg)=@_;
|
||||||
my($tmp,$suffix,@arg);
|
my($suffix,$dst,$src);
|
||||||
|
|
||||||
if (defined($src))
|
@arg=reverse(@arg);
|
||||||
{ $src =~ s/^(e?[a-dsixphl]{2})$/%$1/o;
|
|
||||||
$src =~ s/^(x?mm[0-7])$/%$1/o;
|
for (@arg)
|
||||||
$src =~ s/^(\-?[0-9]+)$/\$$1/o;
|
{ s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o; # gp registers
|
||||||
$src =~ s/^(\-?0x[0-9a-f]+)$/\$$1/o;
|
s/^([xy]?mm[0-7])$/%$1/o; # xmm/mmx registers
|
||||||
push(@arg,$src);
|
s/^(\-?[0-9]+)$/\$$1/o; # constants
|
||||||
}
|
s/^(\-?0x[0-9a-f]+)$/\$$1/o; # constants
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$dst = $arg[$#arg] if ($#arg>=0);
|
||||||
|
$src = $arg[$#arg-1] if ($#arg>=1);
|
||||||
if ($dst =~ m/^%/o) { $suffix=&opsize($dst); }
|
if ($dst =~ m/^%/o) { $suffix=&opsize($dst); }
|
||||||
elsif ($src =~ m/^%/o) { $suffix=&opsize($src); }
|
elsif ($src =~ m/^%/o) { $suffix=&opsize($src); }
|
||||||
else { $suffix="l"; }
|
else { $suffix="l"; }
|
||||||
@ -71,19 +67,6 @@ sub ::jmp_ptr { &::generic("jmp","*$_[0]"); }
|
|||||||
|
|
||||||
*::bswap = sub { &::emit("bswap","%$_[0]"); } if (!$::i386);
|
*::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
|
sub ::DWP
|
||||||
{ my($addr,$reg1,$reg2,$idx)=@_;
|
{ my($addr,$reg1,$reg2,$idx)=@_;
|
||||||
my $ret="";
|
my $ret="";
|
||||||
|
@ -14,8 +14,7 @@ sub ::generic
|
|||||||
{ my ($opcode,@arg)=@_;
|
{ my ($opcode,@arg)=@_;
|
||||||
|
|
||||||
# fix hexadecimal constants
|
# fix hexadecimal constants
|
||||||
$arg[0] =~ s/0x([0-9a-f]+)/0$1h/oi if (defined($arg[0]));
|
for (@arg) { s/0x([0-9a-f]+)/0$1h/oi; }
|
||||||
$arg[1] =~ s/0x([0-9a-f]+)/0$1h/oi if (defined($arg[1]));
|
|
||||||
|
|
||||||
# fix xmm references
|
# fix xmm references
|
||||||
$arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);
|
$arg[0] =~ s/\b[A-Z]+WORD\s+PTR/XMMWORD PTR/i if ($arg[1]=~/\bxmm[0-7]\b/i);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user