aboutsummaryrefslogtreecommitdiffstats
path: root/crypto
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2014-02-14 17:24:12 +0100
committerAndy Polyakov <appro@openssl.org>2014-02-14 17:24:12 +0100
commitf4d456408d9d7bca31f34765d1a05fbd9fa55826 (patch)
treee52d1370e39be0b3d428d0b34b5a0c281a589e85 /crypto
parent5599c7331b90d9d29c9914c2a95c16d91485415a (diff)
downloadopenssl-f4d456408d9d7bca31f34765d1a05fbd9fa55826.tar.gz
x86[_64]cpuid.pl: add low-level RDSEED.
Diffstat (limited to 'crypto')
-rwxr-xr-xcrypto/perlasm/x86_64-xlate.pl13
-rw-r--r--crypto/perlasm/x86asm.pl8
-rw-r--r--crypto/x86_64cpuid.pl15
-rw-r--r--crypto/x86cpuid.pl12
4 files changed, 48 insertions, 0 deletions
diff --git a/crypto/perlasm/x86_64-xlate.pl b/crypto/perlasm/x86_64-xlate.pl
index ed74b85ac9..4dd7f5252d 100755
--- a/crypto/perlasm/x86_64-xlate.pl
+++ b/crypto/perlasm/x86_64-xlate.pl
@@ -778,6 +778,19 @@ my $rdrand = sub {
}
};
+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)=@_;
diff --git a/crypto/perlasm/x86asm.pl b/crypto/perlasm/x86asm.pl
index 17abf92297..dcbc738516 100644
--- a/crypto/perlasm/x86asm.pl
+++ b/crypto/perlasm/x86asm.pl
@@ -131,6 +131,14 @@ sub ::rdrand
{ &::generic("rdrand",@_); }
}
+sub ::rdseed
+{ my ($dst)=@_;
+ if ($dst =~ /(e[a-dsd][ixp])/)
+ { &::data_byte(0x0f,0xc7,0xf8|$regrm{$dst}); }
+ else
+ { &::generic("rdrand",@_); }
+}
+
sub rxb {
local *opcode=shift;
my ($dst,$src1,$src2,$rxb)=@_;
diff --git a/crypto/x86_64cpuid.pl b/crypto/x86_64cpuid.pl
index 0cf68f1360..db5aa4aa36 100644
--- a/crypto/x86_64cpuid.pl
+++ b/crypto/x86_64cpuid.pl
@@ -379,6 +379,21 @@ OPENSSL_ia32_rdrand:
cmove %rcx,%rax
ret
.size OPENSSL_ia32_rdrand,.-OPENSSL_ia32_rdrand
+
+.globl OPENSSL_ia32_rdseed
+.type OPENSSL_ia32_rdseed,\@abi-omnipotent
+.align 16
+OPENSSL_ia32_rdseed:
+ mov \$8,%ecx
+.Loop_rdseed:
+ rdseed %rax
+ jc .Lbreak_rdseed
+ loop .Loop_rdseed
+.Lbreak_rdseed:
+ cmp \$0,%rax
+ cmove %rcx,%rax
+ ret
+.size OPENSSL_ia32_rdseed,.-OPENSSL_ia32_rdseed
___
close STDOUT; # flush
diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl
index ef1216a8b2..86772329bc 100644
--- a/crypto/x86cpuid.pl
+++ b/crypto/x86cpuid.pl
@@ -469,6 +469,18 @@ my $max = "ebp";
&ret ();
&function_end_B("OPENSSL_ia32_rdrand");
+&function_begin_B("OPENSSL_ia32_rdseed");
+ &mov ("ecx",8);
+&set_label("loop");
+ &rdseed ("eax");
+ &jc (&label("break"));
+ &loop (&label("loop"));
+&set_label("break");
+ &cmp ("eax",0);
+ &cmove ("eax","ecx");
+ &ret ();
+&function_end_B("OPENSSL_ia32_rdseed");
+
&initseg("OPENSSL_cpuid_setup");
&hidden("OPENSSL_cpuid_setup");