X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=crypto%2Fx86cpuid.pl;h=c53c9bc9980f6c696eb304713d2b79b5a01822e0;hb=3671233089c80eaebca58ebd8518583cd401f38e;hp=9ad9435ffdc031b3330a71781491d58f3ad09f59;hpb=cee73df3bd6dfad96f686b766cc8900f432d23b4;p=openssl.git diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl index 9ad9435ffd..c53c9bc998 100644 --- a/crypto/x86cpuid.pl +++ b/crypto/x86cpuid.pl @@ -5,6 +5,8 @@ require "x86asm.pl"; &asm_init($ARGV[0],"x86cpuid"); +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + &function_begin("OPENSSL_ia32_cpuid"); &xor ("edx","edx"); &pushf (); @@ -115,20 +117,21 @@ require "x86asm.pl"; &mov ("ecx",&DWP(0,"ecx")); &bt (&DWP(0,"ecx"),1); &jnc (&label("no_x87")); - &bt (&DWP(0,"ecx"),26); - &jnc (&label("no_sse2")); - &pxor ("xmm0","xmm0"); - &pxor ("xmm1","xmm1"); - &pxor ("xmm2","xmm2"); - &pxor ("xmm3","xmm3"); - &pxor ("xmm4","xmm4"); - &pxor ("xmm5","xmm5"); - &pxor ("xmm6","xmm6"); - &pxor ("xmm7","xmm7"); -&set_label("no_sse2"); - # just a bunch of fldz to zap the fp/mm bank... - &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9); - &emms (); + if ($sse2) { + &bt (&DWP(0,"ecx"),26); + &jnc (&label("no_sse2")); + &pxor ("xmm0","xmm0"); + &pxor ("xmm1","xmm1"); + &pxor ("xmm2","xmm2"); + &pxor ("xmm3","xmm3"); + &pxor ("xmm4","xmm4"); + &pxor ("xmm5","xmm5"); + &pxor ("xmm6","xmm6"); + &pxor ("xmm7","xmm7"); + &set_label("no_sse2"); + } + # just a bunch of fldz to zap the fp/mm bank followed by finit... + &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b); &set_label("no_x87"); &lea ("eax",&DWP(4,"esp")); &ret (); @@ -150,6 +153,45 @@ require "x86asm.pl"; &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 $i,$max=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"); + &initseg("OPENSSL_cpuid_setup"); &asm_finish();