X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=crypto%2Fx86cpuid.pl;h=176e8e38c8d6f21a260c91abb594e4c7dcbb7c61;hb=6577e00892fc7b2ce02223e1eff77330e05ea660;hp=e8eaef758262343b541942476157b644eac2e7d8;hpb=bdf40fd2511d61439d169146760a121bcb17f194;p=openssl.git diff --git a/crypto/x86cpuid.pl b/crypto/x86cpuid.pl index e8eaef7582..176e8e38c8 100644 --- a/crypto/x86cpuid.pl +++ b/crypto/x86cpuid.pl @@ -1,9 +1,19 @@ -#!/usr/bin/env perl +#! /usr/bin/env perl +# Copyright 2004-2016 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 +# in the file LICENSE in the source distribution or at +# https://www.openssl.org/source/license.html $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; push(@INC, "${dir}perlasm", "perlasm"); require "x86asm.pl"; +$output = pop; +open OUT,">$output"; +*STDOUT=*OUT; + &asm_init($ARGV[0],"x86cpuid"); for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } @@ -19,9 +29,11 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &pushf (); &pop ("eax"); &xor ("ecx","eax"); - &bt ("ecx",21); - &jnc (&label("generic")); &xor ("eax","eax"); + &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 @@ -67,6 +79,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &inc ("esi"); # number of cores &mov ("eax",1); + &xor ("ecx","ecx"); &cpuid (); &bt ("edx",28); &jnc (&label("generic")); @@ -76,8 +89,18 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &ja (&label("generic")); &and ("edx",0xefffffff); # clear hyper-threading bit &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); &jb (&label("nocacheinfo")); @@ -91,6 +114,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &set_label("nocacheinfo"); &mov ("eax",1); + &xor ("ecx","ecx"); &cpuid (); &and ("edx",0xbfefffff); # force reserved bits #20, #30 to 0 &cmp ("ebp",0); @@ -133,9 +157,12 @@ 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"); &mov ("edx","ebp"); +&set_label("nocpuid"); &function_end("OPENSSL_ia32_cpuid"); &external_label("OPENSSL_ia32cap_P"); @@ -164,7 +191,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &jnz (&label("nohalt")); # not enough privileges &pushf (); - &pop ("eax") + &pop ("eax"); &bt ("eax",9); &jnc (&label("nohalt")); # interrupts are disabled @@ -195,7 +222,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &function_begin_B("OPENSSL_far_spin"); &pushf (); - &pop ("eax") + &pop ("eax"); &bt ("eax",9); &jnc (&label("nospin")); # interrupts are disabled @@ -279,7 +306,7 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } # arguments is 1 or 2! &function_begin_B("OPENSSL_indirect_call"); { - my $i,$max=7; # $max has to be chosen as 4*n-1 + my ($max,$i)=(7,); # $max has to be chosen as 4*n-1 # in order to preserve eventual # stack alignment &push ("ebp"); @@ -338,6 +365,31 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } &ret (); &function_end_B("OPENSSL_cleanse"); +&function_begin_B("CRYPTO_memcmp"); + &push ("esi"); + &push ("edi"); + &mov ("esi",&wparam(0)); + &mov ("edi",&wparam(1)); + &mov ("ecx",&wparam(2)); + &xor ("eax","eax"); + &xor ("edx","edx"); + &cmp ("ecx",0); + &je (&label("no_data")); +&set_label("loop"); + &mov ("dl",&BP(0,"esi")); + &lea ("esi",&DWP(1,"esi")); + &xor ("dl",&BP(0,"edi")); + &lea ("edi",&DWP(1,"edi")); + &or ("al","dl"); + &dec ("ecx"); + &jnz (&label("loop")); + &neg ("eax"); + &shr ("eax",31); +&set_label("no_data"); + &pop ("edi"); + &pop ("esi"); + &ret (); +&function_end_B("CRYPTO_memcmp"); { my $lasttick = "esi"; my $lastdiff = "ebx"; @@ -440,18 +492,70 @@ 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")); + + &mov ("ecx",8); +&set_label("loop"); + &${rdop}("edx"); + &jc (&label("break")); + &loop (&label("loop")); + &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_${rdop}_bytes"); +} +&gen_random("rdrand"); +&gen_random("rdseed"); &initseg("OPENSSL_cpuid_setup"); +&hidden("OPENSSL_cpuid_setup"); +&hidden("OPENSSL_ia32cap_P"); + &asm_finish(); + +close STDOUT;