diff options
Diffstat (limited to '')
| -rw-r--r-- | src/lib/libcrypto/x86cpuid.pl | 78 | 
1 files changed, 61 insertions, 17 deletions
| diff --git a/src/lib/libcrypto/x86cpuid.pl b/src/lib/libcrypto/x86cpuid.pl index a7464af19b..39fd8f2293 100644 --- a/src/lib/libcrypto/x86cpuid.pl +++ b/src/lib/libcrypto/x86cpuid.pl | |||
| @@ -19,9 +19,9 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | |||
| 19 | &pushf (); | 19 | &pushf (); | 
| 20 | &pop ("eax"); | 20 | &pop ("eax"); | 
| 21 | &xor ("ecx","eax"); | 21 | &xor ("ecx","eax"); | 
| 22 | &bt ("ecx",21); | ||
| 23 | &jnc (&label("done")); | ||
| 24 | &xor ("eax","eax"); | 22 | &xor ("eax","eax"); | 
| 23 | &bt ("ecx",21); | ||
| 24 | &jnc (&label("nocpuid")); | ||
| 25 | &cpuid (); | 25 | &cpuid (); | 
| 26 | &mov ("edi","eax"); # max value for standard query level | 26 | &mov ("edi","eax"); # max value for standard query level | 
| 27 | 27 | ||
| @@ -51,7 +51,14 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | |||
| 51 | # AMD specific | 51 | # AMD specific | 
| 52 | &mov ("eax",0x80000000); | 52 | &mov ("eax",0x80000000); | 
| 53 | &cpuid (); | 53 | &cpuid (); | 
| 54 | &cmp ("eax",0x80000008); | 54 | &cmp ("eax",0x80000001); | 
| 55 | &jb (&label("intel")); | ||
| 56 | &mov ("esi","eax"); | ||
| 57 | &mov ("eax",0x80000001); | ||
| 58 | &cpuid (); | ||
| 59 | &or ("ebp","ecx"); | ||
| 60 | &and ("ebp",1<<11|1); # isolate XOP bit | ||
| 61 | &cmp ("esi",0x80000008); | ||
| 55 | &jb (&label("intel")); | 62 | &jb (&label("intel")); | 
| 56 | 63 | ||
| 57 | &mov ("eax",0x80000008); | 64 | &mov ("eax",0x80000008); | 
| @@ -62,13 +69,13 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | |||
| 62 | &mov ("eax",1); | 69 | &mov ("eax",1); | 
| 63 | &cpuid (); | 70 | &cpuid (); | 
| 64 | &bt ("edx",28); | 71 | &bt ("edx",28); | 
| 65 | &jnc (&label("done")); | 72 | &jnc (&label("generic")); | 
| 66 | &shr ("ebx",16); | 73 | &shr ("ebx",16); | 
| 67 | &and ("ebx",0xff); | 74 | &and ("ebx",0xff); | 
| 68 | &cmp ("ebx","esi"); | 75 | &cmp ("ebx","esi"); | 
| 69 | &ja (&label("done")); | 76 | &ja (&label("generic")); | 
| 70 | &and ("edx",0xefffffff); # clear hyper-threading bit | 77 | &and ("edx",0xefffffff); # clear hyper-threading bit | 
| 71 | &jmp (&label("done")); | 78 | &jmp (&label("generic")); | 
| 72 | 79 | ||
| 73 | &set_label("intel"); | 80 | &set_label("intel"); | 
| 74 | &cmp ("edi",4); | 81 | &cmp ("edi",4); | 
| @@ -85,27 +92,51 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | |||
| 85 | &set_label("nocacheinfo"); | 92 | &set_label("nocacheinfo"); | 
| 86 | &mov ("eax",1); | 93 | &mov ("eax",1); | 
| 87 | &cpuid (); | 94 | &cpuid (); | 
| 95 | &and ("edx",0xbfefffff); # force reserved bits #20, #30 to 0 | ||
| 88 | &cmp ("ebp",0); | 96 | &cmp ("ebp",0); | 
| 89 | &jne (&label("notP4")); | 97 | &jne (&label("notintel")); | 
| 98 | &or ("edx",1<<30); # set reserved bit#30 on Intel CPUs | ||
| 90 | &and (&HB("eax"),15); # familiy ID | 99 | &and (&HB("eax"),15); # familiy ID | 
| 91 | &cmp (&HB("eax"),15); # P4? | 100 | &cmp (&HB("eax"),15); # P4? | 
| 92 | &jne (&label("notP4")); | 101 | &jne (&label("notintel")); | 
| 93 | &or ("edx",1<<20); # use reserved bit to engage RC4_CHAR | 102 | &or ("edx",1<<20); # set reserved bit#20 to engage RC4_CHAR | 
| 94 | &set_label("notP4"); | 103 | &set_label("notintel"); | 
| 95 | &bt ("edx",28); # test hyper-threading bit | 104 | &bt ("edx",28); # test hyper-threading bit | 
| 96 | &jnc (&label("done")); | 105 | &jnc (&label("generic")); | 
| 97 | &and ("edx",0xefffffff); | 106 | &and ("edx",0xefffffff); | 
| 98 | &cmp ("edi",0); | 107 | &cmp ("edi",0); | 
| 99 | &je (&label("done")); | 108 | &je (&label("generic")); | 
| 100 | 109 | ||
| 101 | &or ("edx",0x10000000); | 110 | &or ("edx",0x10000000); | 
| 102 | &shr ("ebx",16); | 111 | &shr ("ebx",16); | 
| 103 | &cmp (&LB("ebx"),1); | 112 | &cmp (&LB("ebx"),1); | 
| 104 | &ja (&label("done")); | 113 | &ja (&label("generic")); | 
| 105 | &and ("edx",0xefffffff); # clear hyper-threading bit if not | 114 | &and ("edx",0xefffffff); # clear hyper-threading bit if not | 
| 115 | |||
| 116 | &set_label("generic"); | ||
| 117 | &and ("ebp",1<<11); # isolate AMD XOP flag | ||
| 118 | &and ("ecx",0xfffff7ff); # force 11th bit to 0 | ||
| 119 | &mov ("esi","edx"); | ||
| 120 | &or ("ebp","ecx"); # merge AMD XOP flag | ||
| 121 | |||
| 122 | &bt ("ecx",27); # check OSXSAVE bit | ||
| 123 | &jnc (&label("clear_avx")); | ||
| 124 | &xor ("ecx","ecx"); | ||
| 125 | &data_byte(0x0f,0x01,0xd0); # xgetbv | ||
| 126 | &and ("eax",6); | ||
| 127 | &cmp ("eax",6); | ||
| 128 | &je (&label("done")); | ||
| 129 | &cmp ("eax",2); | ||
| 130 | &je (&label("clear_avx")); | ||
| 131 | &set_label("clear_xmm"); | ||
| 132 | &and ("ebp",0xfdfffffd); # clear AESNI and PCLMULQDQ bits | ||
| 133 | &and ("esi",0xfeffffff); # clear FXSR | ||
| 134 | &set_label("clear_avx"); | ||
| 135 | &and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits | ||
| 106 | &set_label("done"); | 136 | &set_label("done"); | 
| 107 | &mov ("eax","edx"); | 137 | &mov ("eax","esi"); | 
| 108 | &mov ("edx","ecx"); | 138 | &mov ("edx","ebp"); | 
| 139 | &set_label("nocpuid"); | ||
| 109 | &function_end("OPENSSL_ia32_cpuid"); | 140 | &function_end("OPENSSL_ia32_cpuid"); | 
| 110 | 141 | ||
| 111 | &external_label("OPENSSL_ia32cap_P"); | 142 | &external_label("OPENSSL_ia32cap_P"); | 
| @@ -199,8 +230,9 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | |||
| 199 | &bt (&DWP(0,"ecx"),1); | 230 | &bt (&DWP(0,"ecx"),1); | 
| 200 | &jnc (&label("no_x87")); | 231 | &jnc (&label("no_x87")); | 
| 201 | if ($sse2) { | 232 | if ($sse2) { | 
| 202 | &bt (&DWP(0,"ecx"),26); | 233 | &and ("ecx",1<<26|1<<24); # check SSE2 and FXSR bits | 
| 203 | &jnc (&label("no_sse2")); | 234 | &cmp ("ecx",1<<26|1<<24); | 
| 235 | &jne (&label("no_sse2")); | ||
| 204 | &pxor ("xmm0","xmm0"); | 236 | &pxor ("xmm0","xmm0"); | 
| 205 | &pxor ("xmm1","xmm1"); | 237 | &pxor ("xmm1","xmm1"); | 
| 206 | &pxor ("xmm2","xmm2"); | 238 | &pxor ("xmm2","xmm2"); | 
| @@ -307,6 +339,18 @@ for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } | |||
| 307 | &ret (); | 339 | &ret (); | 
| 308 | &function_end_B("OPENSSL_cleanse"); | 340 | &function_end_B("OPENSSL_cleanse"); | 
| 309 | 341 | ||
| 342 | &function_begin_B("OPENSSL_ia32_rdrand"); | ||
| 343 | &mov ("ecx",8); | ||
| 344 | &set_label("loop"); | ||
| 345 | &rdrand ("eax"); | ||
| 346 | &jc (&label("break")); | ||
| 347 | &loop (&label("loop")); | ||
| 348 | &set_label("break"); | ||
| 349 | &cmp ("eax",0); | ||
| 350 | &cmove ("eax","ecx"); | ||
| 351 | &ret (); | ||
| 352 | &function_end_B("OPENSSL_ia32_rdrand"); | ||
| 353 | |||
| 310 | &initseg("OPENSSL_cpuid_setup"); | 354 | &initseg("OPENSSL_cpuid_setup"); | 
| 311 | 355 | ||
| 312 | &asm_finish(); | 356 | &asm_finish(); | 
