x86_64 assembly pack: improve masm support.
(Imported from upstream's 371feee876dd8b58531cb6e50fe79262db8e4ed7)
Change-Id: Id3b5ece6b5e5f0565060d5e598ea265d64dac9df
diff --git a/crypto/bn/asm/rsaz-x86_64.pl b/crypto/bn/asm/rsaz-x86_64.pl
index cd651f7..3a4f0c5 100644
--- a/crypto/bn/asm/rsaz-x86_64.pl
+++ b/crypto/bn/asm/rsaz-x86_64.pl
@@ -110,7 +110,7 @@
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=11);
+ $addx = ($1>=12);
}
if (!$addx && `$ENV{CC} -v 2>&1` =~ /(^clang version|based on LLVM) ([3-9])\.([0-9]+)/) {
diff --git a/crypto/bn/asm/x86_64-mont.pl b/crypto/bn/asm/x86_64-mont.pl
index 29c0f9c..39476ab 100644
--- a/crypto/bn/asm/x86_64-mont.pl
+++ b/crypto/bn/asm/x86_64-mont.pl
@@ -65,7 +65,7 @@
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=11);
+ $addx = ($1>=12);
}
# int bn_mul_mont(
@@ -741,9 +741,11 @@
my @A1=("%r12","%r13");
my ($a0,$a1,$ai)=("%r14","%r15","%rbx");
+$code.=<<___ if ($addx);
+.extern bn_sqrx8x_internal # see x86_64-mont5 module
+___
$code.=<<___;
.extern bn_sqr8x_internal # see x86_64-mont5 module
-.extern bn_sqrx8x_internal # see x86_64-mont5 module
.type bn_sqr8x_mont,\@function,6
.align 32
diff --git a/crypto/bn/asm/x86_64-mont5.pl b/crypto/bn/asm/x86_64-mont5.pl
index 85386c1..5037cab 100644
--- a/crypto/bn/asm/x86_64-mont5.pl
+++ b/crypto/bn/asm/x86_64-mont5.pl
@@ -50,7 +50,7 @@
if (!$addx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) &&
`ml64 2>&1` =~ /Version ([0-9]+)\./) {
- $addx = ($1>=11);
+ $addx = ($1>=12);
}
# int bn_mul_mont_gather5(
diff --git a/crypto/modes/asm/aesni-gcm-x86_64.pl b/crypto/modes/asm/aesni-gcm-x86_64.pl
index 5fb437c..cfc856c 100644
--- a/crypto/modes/asm/aesni-gcm-x86_64.pl
+++ b/crypto/modes/asm/aesni-gcm-x86_64.pl
@@ -92,7 +92,7 @@
.align 32
.Loop6x:
- add \$100663296,$counter
+ add \$`6<<24`,$counter
jc .Lhandle_ctr32 # discard $inout[1-5]?
vmovdqu 0x00-0x20($Xip),$Hkey # $Hkey^1
vpaddb $T2,$inout5,$T1 # next counter value
@@ -520,7 +520,7 @@
vmovups 0x10-0x80($key),$rndkey
lea 0x20-0x80($key),%r12
vpxor $Z0,$T1,$inout0
- add \$100663296,$counter
+ add \$`6<<24`,$counter
jc .Lhandle_ctr32_2
vpaddb $T2,$T1,$inout1
vpaddb $T2,$inout1,$inout2
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index 24ff1b4..686809b 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -112,7 +112,6 @@
$line = substr($line,@+[0]); $line =~ s/^\s+//;
undef $self->{sz};
- undef $self->{arg_sz};
if ($self->{op} =~ /^(movz)x?([bw]).*/) { # movz is pain...
$self->{op} = $1;
$self->{sz} = $2;
@@ -120,12 +119,6 @@
$self->{sz} = "";
} elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op|insrw)/) { # SSEn
$self->{sz} = "";
- } elsif ($self->{op} eq "vpbroadcastq") {
- $self->{arg_sz} = "q";
- } elsif ($self->{op} eq "vpbroadcastb") {
- $self->{arg_sz} = "b";
- } elsif ($self->{op} =~ /^vinserti128/) {
- $self->{arg_sz} = "x";
} elsif ($self->{op} =~ /^v/) { # VEX
$self->{sz} = "";
} elsif ($self->{op} =~ /movq/ && $line =~ /%xmm/) {
@@ -143,10 +136,6 @@
$self->{sz} = $sz if (defined($sz) && !defined($self->{sz}));
$self->{sz};
}
- sub arg_size {
- my $self = shift;
- $self->{arg_sz};
- }
sub out {
my $self = shift;
if ($gas) {
@@ -281,15 +270,20 @@
sprintf "%s%s(%%%s)", $self->{asterisk},$self->{label},$self->{base};
}
} else {
- %szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR",
- q=>"QWORD$PTR",o=>"OWORD$PTR",x=>"XMMWORD$PTR",
- y=>"YMMWORD$PTR" );
+ %szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR",
+ l=>"DWORD$PTR", d=>"DWORD$PTR",
+ q=>"QWORD$PTR", o=>"OWORD$PTR",
+ x=>"XMMWORD$PTR", y=>"YMMWORD$PTR", z=>"ZMMWORD$PTR" );
$self->{label} =~ s/\./\$/g;
$self->{label} =~ s/(?<![\w\$\.])0x([0-9a-f]+)/0$1h/ig;
$self->{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/);
- $sz="q" if ($self->{asterisk} || opcode->mnemonic() =~ /^v?movq$/);
- $sz="l" if (opcode->mnemonic() =~ /^v?movd$/);
+
+ ($self->{asterisk}) && ($sz="q") ||
+ (opcode->mnemonic() =~ /^v?mov([qd])$/) && ($sz=$1) ||
+ (opcode->mnemonic() =~ /^v?pinsr([qdwb])$/) && ($sz=$1) ||
+ (opcode->mnemonic() =~ /^vpbroadcast([qdwb])$/) && ($sz=$1) ||
+ (opcode->mnemonic() =~ /^vinsert[fi]128$/) && ($sz="x");
if (defined($self->{index})) {
sprintf "%s[%s%s*%d%s]",$szmap{$sz},
@@ -547,7 +541,7 @@
$v="$current_segment\tENDS\n" if ($current_segment);
$current_segment = ".text\$";
$v.="$current_segment\tSEGMENT ";
- $v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE";
+ $v.=$masm>=$masmref ? "ALIGN(256)" : "PAGE";
$v.=" 'CODE'";
}
$self->{value} = $v;
@@ -789,6 +783,19 @@
}
};
+my $rdseed = sub {
+ if (shift =~ /%[er](\w+)/) {
+ my @opcode=();
+ my $dst=$1;
+ if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; }
+ rex(\@opcode,0,$1,8);
+ push @opcode,0x0f,0xc7,0xf8|($dst&7);
+ @opcode;
+ } else {
+ ();
+ }
+};
+
sub rxb {
local *opcode=shift;
my ($dst,$src1,$src2,$rxb)=@_;
@@ -832,6 +839,8 @@
print <<___;
default rel
%define XMMWORD
+%define YMMWORD
+%define ZMMWORD
___
} elsif ($masm) {
print <<___;
@@ -886,7 +895,6 @@
if ($#args>=0) {
my $insn;
my $sz=opcode->size();
- my $arg_sz=opcode->arg_size();
if ($gas) {
$insn = $opcode->out($#args>=1?$args[$#args]->size():$sz);
@@ -899,18 +907,12 @@
# $insn.=$sz compensates for movq, pinsrw, ...
if ($arg =~ /^xmm[0-9]+$/) { $insn.=$sz; $sz="x" if(!$sz); last; }
if ($arg =~ /^ymm[0-9]+$/) { $insn.=$sz; $sz="y" if(!$sz); last; }
+ if ($arg =~ /^zmm[0-9]+$/) { $insn.=$sz; $sz="z" if(!$sz); last; }
if ($arg =~ /^mm[0-9]+$/) { $insn.=$sz; $sz="q" if(!$sz); last; }
}
- $sz=$arg_sz if($arg_sz);
@args = reverse(@args);
undef $sz if ($nasm && $opcode->mnemonic() eq "lea");
-
- if ($insn eq "movq" && $#args == 1 && $args[0]->out($sz) eq "xmm0" && $args[1]->out($sz) eq "rax") {
- # I have no clue why MASM can't parse this instruction.
- printf "DB 66h, 48h, 0fh, 6eh, 0c0h";
- } else {
- printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
- }
+ printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args));
}
} else {
printf "\t%s",$opcode->out();