summaryrefslogtreecommitdiffstats
path: root/crypto/perlasm
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2011-05-18 16:26:03 +0000
committerAndy Polyakov <appro@openssl.org>2011-05-18 16:26:03 +0000
commitc7b903e01d4407a94470dfd2d442db0dba3acd57 (patch)
treef6de4ad38ec3aa36e9916b0f49d558adf3e3f604 /crypto/perlasm
parentddc20d4da9d770afeace2b4111d5d39d00e6c6b4 (diff)
x86_64-xlate.pl: add inter-register movq and make x86_64-gfm.s compile on
Solaris, MacOS X, elderly gas...
Diffstat (limited to 'crypto/perlasm')
-rwxr-xr-xcrypto/perlasm/x86_64-xlate.pl24
1 files changed, 24 insertions, 0 deletions
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index 6749783e29..91017c69f3 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -123,6 +123,8 @@ my %globals;
$self->{sz} = "";
} elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op|insrw)/) { # SSEn
$self->{sz} = "";
+ } elsif ($self->{op} =~ /movq/ && $line =~ /%xmm/) {
+ $self->{sz} = "";
} elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) {
$self->{op} = $1;
$self->{sz} = $2;
@@ -658,6 +660,28 @@ sub rex {
my %regrm = ( "%eax"=>0, "%ecx"=>1, "%edx"=>2, "%ebx"=>3,
"%esp"=>4, "%ebp"=>5, "%esi"=>6, "%edi"=>7 );
+my $movq = sub { # elderly gas can't handle inter-register movq
+ my $arg = shift;
+ my @opcode=(0x66);
+ if ($arg =~ /%xmm([0-9]+),%r(\w+)/) {
+ my ($src,$dst)=($1,$2);
+ if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
+ rex(\@opcode,$src,$dst,0x8);
+ push @opcode,0x0f,0x7e;
+ push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M
+ @opcode;
+ } elsif ($arg =~ /%r(\w+),%xmm([0-9]+)/) {
+ my ($src,$dst)=($2,$1);
+ if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
+ rex(\@opcode,$src,$dst,0x8);
+ push @opcode,0x0f,0x6e;
+ push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M
+ @opcode;
+ } else {
+ ();
+ }
+};
+
my $pextrd = sub {
if (shift =~ /\$([0-9]+),%xmm([0-9]+),(%\w+)/) {
my @opcode=(0x66);