#! /usr/bin/env perl
-# Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 2004-2018 The OpenSSL Project Authors. All Rights Reserved.
#
-# Licensed under the OpenSSL license (the "License"). You may not use
+# Licensed under the Apache License 2.0 (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
# in the file LICENSE in the source distribution or at
# https://www.openssl.org/source/license.html
open OUT,">$output";
*STDOUT=*OUT;
-&asm_init($ARGV[0],"x86cpuid");
+&asm_init($ARGV[0]);
for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
&pop ("eax");
&xor ("ecx","eax");
&xor ("eax","eax");
+ &mov ("esi",&wparam(0));
+ &mov (&DWP(8,"esi"),"eax"); # clear extended feature flags
&bt ("ecx",21);
&jnc (&label("nocpuid"));
- &mov ("esi",&wparam(0));
- &mov (&DWP(8,"esi"),"eax"); # clear 3rd word
&cpuid ();
&mov ("edi","eax"); # max value for standard query level
&jmp (&label("generic"));
&set_label("intel");
- &cmp ("edi",7);
- &jb (&label("cacheinfo"));
-
- &mov ("esi",&wparam(0));
- &mov ("eax",7);
- &xor ("ecx","ecx");
- &cpuid ();
- &mov (&DWP(8,"esi"),"ebx");
-
-&set_label("cacheinfo");
&cmp ("edi",4);
- &mov ("edi",-1);
+ &mov ("esi",-1);
&jb (&label("nocacheinfo"));
&mov ("eax",4);
&mov ("ecx",0); # query L1D
&cpuid ();
- &mov ("edi","eax");
- &shr ("edi",14);
- &and ("edi",0xfff); # number of cores -1 per L1D
+ &mov ("esi","eax");
+ &shr ("esi",14);
+ &and ("esi",0xfff); # number of cores -1 per L1D
&set_label("nocacheinfo");
&mov ("eax",1);
&cmp ("ebp",0);
&jne (&label("notintel"));
&or ("edx",1<<30); # set reserved bit#30 on Intel CPUs
- &and (&HB("eax"),15); # familiy ID
+ &and (&HB("eax"),15); # family ID
&cmp (&HB("eax"),15); # P4?
&jne (&label("notintel"));
&or ("edx",1<<20); # set reserved bit#20 to engage RC4_CHAR
&bt ("edx",28); # test hyper-threading bit
&jnc (&label("generic"));
&and ("edx",0xefffffff);
- &cmp ("edi",0);
+ &cmp ("esi",0);
&je (&label("generic"));
&or ("edx",0x10000000);
&set_label("generic");
&and ("ebp",1<<11); # isolate AMD XOP flag
&and ("ecx",0xfffff7ff); # force 11th bit to 0
- &mov ("esi","edx");
+ &mov ("esi","edx"); # %ebp:%esi is copy of %ecx:%edx
&or ("ebp","ecx"); # merge AMD XOP flag
- &bt ("ecx",27); # check OSXSAVE bit
+ &cmp ("edi",7);
+ &mov ("edi",&wparam(0));
+ &jb (&label("no_extended_info"));
+ &mov ("eax",7);
+ &xor ("ecx","ecx");
+ &cpuid ();
+ &mov (&DWP(8,"edi"),"ebx"); # save extended feature flag
+&set_label("no_extended_info");
+
+ &bt ("ebp",27); # check OSXSAVE bit
&jnc (&label("clear_avx"));
&xor ("ecx","ecx");
&data_byte(0x0f,0x01,0xd0); # xgetbv
&and ("esi",0xfeffffff); # clear FXSR
&set_label("clear_avx");
&and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits
- &mov ("edi",&wparam(0));
&and (&DWP(8,"edi"),0xffffffdf); # clear AVX2
&set_label("done");
&mov ("eax","esi");
&set_label("spin");
&lea ("ebx",&DWP(0,"eax","ecx"));
&nop ();
- &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx) # %eax is envolved and is always reloaded
+ &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx) # %eax is involved and is always reloaded
&jne (&label("spin"));
&mov ("eax","ebx"); # OpenSSL expects the new value
&pop ("ebx");
sub gen_random {
my $rdop = shift;
-&function_begin_B("OPENSSL_ia32_${rdop}");
- &mov ("ecx",8);
-&set_label("loop");
- &${rdop}("eax");
- &jc (&label("break"));
- &loop (&label("loop"));
-&set_label("break");
- &cmp ("eax",0);
- &cmove ("eax","ecx");
- &ret ();
-&function_end_B("OPENSSL_ia32_${rdop}");
-
&function_begin_B("OPENSSL_ia32_${rdop}_bytes");
&push ("edi");
&push ("ebx");
&jnz (&label("tail"));
&set_label("done");
+ &xor ("edx","edx"); # Clear random value from registers
&pop ("ebx");
&pop ("edi");
&ret ();