summaryrefslogtreecommitdiffstats
path: root/crypto/x86cpuid.pl
diff options
context:
space:
mode:
authorAndy Polyakov <appro@openssl.org>2016-07-10 12:05:43 +0200
committerAndy Polyakov <appro@openssl.org>2016-07-15 13:20:52 +0200
commit9c940446f614d1294fa197ffd4128206296b04da (patch)
treed5fe003438949d0fbd62a18a8892fe023f2d082e /crypto/x86cpuid.pl
parentb1837abd674f62a04f1191c68ca7e5c3101ce5a0 (diff)
crypto/x86[_64]cpuid.pl: add OPENSSL_ia32_rd[rand|seed]_bytes.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Diffstat (limited to 'crypto/x86cpuid.pl')
-rw-r--r--crypto/x86cpuid.pl53
1 files changed, 44 insertions, 9 deletions
diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl
index 99ffa1d2fb..c45b18356b 100644
--- a/crypto/x86cpuid.pl
+++ b/crypto/x86cpuid.pl
@@ -492,29 +492,64 @@ my $max = "ebp";
&function_end("OPENSSL_instrument_bus2");
}
-&function_begin_B("OPENSSL_ia32_rdrand");
+sub gen_random {
+my $rdop = shift;
+&function_begin_B("OPENSSL_ia32_${rdop}");
&mov ("ecx",8);
&set_label("loop");
- &rdrand ("eax");
+ &${rdop}("eax");
&jc (&label("break"));
&loop (&label("loop"));
&set_label("break");
&cmp ("eax",0);
&cmove ("eax","ecx");
&ret ();
-&function_end_B("OPENSSL_ia32_rdrand");
+&function_end_B("OPENSSL_ia32_${rdop}");
+
+&function_begin_B("OPENSSL_ia32_${rdop}_bytes");
+ &push ("edi");
+ &push ("ebx");
+ &xor ("eax","eax"); # return value
+ &mov ("edi",&wparam(0));
+ &mov ("ebx",&wparam(1));
+
+ &cmp ("ebx",0);
+ &je (&label("done"));
-&function_begin_B("OPENSSL_ia32_rdseed");
&mov ("ecx",8);
&set_label("loop");
- &rdseed ("eax");
+ &${rdop}("edx");
&jc (&label("break"));
&loop (&label("loop"));
-&set_label("break");
- &cmp ("eax",0);
- &cmove ("eax","ecx");
+ &jmp (&label("done"));
+
+&set_label("break",16);
+ &cmp ("ebx",4);
+ &jb (&label("tail"));
+ &mov (&DWP(0,"edi"),"edx");
+ &lea ("edi",&DWP(4,"edi"));
+ &add ("eax",4);
+ &sub ("ebx",4);
+ &jz (&label("done"));
+ &mov ("ecx",8);
+ &jmp (&label("loop"));
+
+&set_label("tail",16);
+ &mov (&BP(0,"edi"),"dl");
+ &lea ("edi",&DWP(1,"edi"));
+ &inc ("eax");
+ &shr ("edx",8);
+ &dec ("ebx");
+ &jnz (&label("tail"));
+
+&set_label("done");
+ &pop ("ebx");
+ &pop ("edi");
&ret ();
-&function_end_B("OPENSSL_ia32_rdseed");
+&function_end_B("OPENSSL_ia32_${rdop}_bytes");
+}
+&gen_random("rdrand");
+&gen_random("rdseed");
&initseg("OPENSSL_cpuid_setup");