/* Libottery by Nick Mathewson. This software has been dedicated to the public domain under the CC0 public domain dedication. To the extent possible under law, the person who associated CC0 with libottery has waived all copyright and related or neighboring rights to libottery. You should have received a copy of the CC0 legalcode along with this work in doc/cc0.txt. If not, see . */ #include "ottery-internal.h" #include #if defined(i386) || \ defined(__i386) || \ defined(__M_IX86) || \ defined(_M_IX86) #define X86 #elif defined(__x86_64) || \ defined(_M_AMD64) #define X86 #define X86_64 #endif #if defined(__arm__) || \ defined(_M_ARM) #define ARM #endif #if defined(X86) #ifdef _MSC_VER #include #define cpuid(a,b) __cpuid((b), (a)) #else static void cpuid(int index, int regs[4]) { unsigned int eax, ebx, ecx, edx; #ifdef X86_64 __asm("cpuid" : "=a"(eax), "=b" (ebx), "=c"(ecx), "=d"(edx) : "0"(index)); #else __asm volatile( "xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" : "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx) : "0" (index) : "cc" ); #endif regs[0] = eax; regs[1] = ebx; regs[2] = ecx; regs[3] = edx; } #endif #endif static uint32_t disabled_cpu_capabilities = 0; void ottery_disable_cpu_capabilities_(uint32_t disable) { disabled_cpu_capabilities |= disable; } uint32_t ottery_get_cpu_capabilities_(void) { #ifdef X86 uint32_t cap = 0; int res[4]; cpuid(1, res); if (res[3] & (1<<26)) cap |= OTTERY_CPUCAP_SIMD; if (res[2] & (1<<9)) cap |= OTTERY_CPUCAP_SSSE3; if (res[2] & (1<<25)) cap |= OTTERY_CPUCAP_AES; if (res[2] & (1<<30)) cap |= OTTERY_CPUCAP_RAND; #else uint32_t cap = OTTERY_CPUCAP_SIMD; #endif return cap & ~disabled_cpu_capabilities; }