X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fx86cpuid.pl;h=d43dda4d935cbdee633b11fc62366d09c2a245ec;hp=176e8e38c8d6f21a260c91abb594e4c7dcbb7c61;hb=bbb02a5b6d27f76931c3385321b2c594781c7a1b;hpb=609b0852e4d50251857dbbac3141ba042e35a9ae diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl index 176e8e38c8..d43dda4d93 100644 --- a/crypto/x86cpuid.pl +++ b/crypto/x86cpuid.pl @@ -1,5 +1,5 @@ #! /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 # this file except in compliance with the License. You can obtain a copy @@ -14,7 +14,7 @@ $output = pop; open OUT,">$output"; *STDOUT=*OUT; -&asm_init($ARGV[0],"x86cpuid"); +&asm_init($ARGV[0]); for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } @@ -30,10 +30,10 @@ 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 @@ -91,26 +91,16 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &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); @@ -120,7 +110,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &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 @@ -128,7 +118,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &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); @@ -140,10 +130,19 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &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 @@ -157,7 +156,6 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &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"); @@ -285,52 +283,13 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &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"); &ret (); &function_end_B("OPENSSL_atomic_add"); -# This function can become handy under Win32 in situations when -# we don't know which calling convention, __stdcall or __cdecl(*), -# indirect callee is using. In C it can be deployed as -# -#ifdef OPENSSL_CPUID_OBJ -# type OPENSSL_indirect_call(void *f,...); -# ... -# OPENSSL_indirect_call(func,[up to $max arguments]); -#endif -# -# (*) it's designed to work even for __fastcall if number of -# arguments is 1 or 2! -&function_begin_B("OPENSSL_indirect_call"); - { - my ($max,$i)=(7,); # $max has to be chosen as 4*n-1 - # in order to preserve eventual - # stack alignment - &push ("ebp"); - &mov ("ebp","esp"); - &sub ("esp",$max*4); - &mov ("ecx",&DWP(12,"ebp")); - &mov (&DWP(0,"esp"),"ecx"); - &mov ("edx",&DWP(16,"ebp")); - &mov (&DWP(4,"esp"),"edx"); - for($i=2;$i<$max;$i++) - { - # Some copies will be redundant/bogus... - &mov ("eax",&DWP(12+$i*4,"ebp")); - &mov (&DWP(0+$i*4,"esp"),"eax"); - } - &call_ptr (&DWP(8,"ebp"));# make the call... - &mov ("esp","ebp"); # ... and just restore the stack pointer - # without paying attention to what we called, - # (__cdecl *func) or (__stdcall *one). - &pop ("ebp"); - &ret (); - } -&function_end_B("OPENSSL_indirect_call"); - &function_begin_B("OPENSSL_cleanse"); &mov ("edx",&wparam(0)); &mov ("ecx",&wparam(1)); @@ -494,18 +453,6 @@ my $max = "ebp"; 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"); @@ -543,6 +490,7 @@ my $rdop = shift; &jnz (&label("tail")); &set_label("done"); + &xor ("edx","edx"); # Clear random value from registers &pop ("ebx"); &pop ("edi"); &ret ();