Botan
1.11.15
|
00001 /* 00002 * Runtime CPU detection 00003 * (C) 2009-2010,2013 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #ifndef BOTAN_CPUID_H__ 00009 #define BOTAN_CPUID_H__ 00010 00011 #include <botan/types.h> 00012 #include <iosfwd> 00013 00014 namespace Botan { 00015 00016 /** 00017 * A class handling runtime CPU feature detection 00018 */ 00019 class BOTAN_DLL CPUID 00020 { 00021 public: 00022 /** 00023 * Probe the CPU and see what extensions are supported 00024 */ 00025 static void initialize(); 00026 00027 /** 00028 * Return a best guess of the cache line size 00029 */ 00030 static size_t cache_line_size() { initialize(); return g_cache_line_size; } 00031 00032 /** 00033 * Check if the processor supports AltiVec/VMX 00034 */ 00035 static bool has_altivec() { initialize(); return g_altivec_capable; } 00036 00037 /** 00038 * Check if the processor supports RDTSC 00039 */ 00040 static bool has_rdtsc() 00041 { return x86_processor_flags_has(CPUID_RDTSC_BIT); } 00042 00043 /** 00044 * Check if the processor supports SSE2 00045 */ 00046 static bool has_sse2() 00047 { return x86_processor_flags_has(CPUID_SSE2_BIT); } 00048 00049 /** 00050 * Check if the processor supports SSSE3 00051 */ 00052 static bool has_ssse3() 00053 { return x86_processor_flags_has(CPUID_SSSE3_BIT); } 00054 00055 /** 00056 * Check if the processor supports SSE4.1 00057 */ 00058 static bool has_sse41() 00059 { return x86_processor_flags_has(CPUID_SSE41_BIT); } 00060 00061 /** 00062 * Check if the processor supports SSE4.2 00063 */ 00064 static bool has_sse42() 00065 { return x86_processor_flags_has(CPUID_SSE42_BIT); } 00066 00067 /** 00068 * Check if the processor supports AVX2 00069 */ 00070 static bool has_avx2() 00071 { return x86_processor_flags_has(CPUID_AVX2_BIT); } 00072 00073 /** 00074 * Check if the processor supports AVX-512F 00075 */ 00076 static bool has_avx512f() 00077 { return x86_processor_flags_has(CPUID_AVX512F_BIT); } 00078 00079 /** 00080 * Check if the processor supports BMI2 00081 */ 00082 static bool has_bmi2() 00083 { return x86_processor_flags_has(CPUID_BMI2_BIT); } 00084 00085 /** 00086 * Check if the processor supports AES-NI 00087 */ 00088 static bool has_aes_ni() 00089 { return x86_processor_flags_has(CPUID_AESNI_BIT); } 00090 00091 /** 00092 * Check if the processor supports CLMUL 00093 */ 00094 static bool has_clmul() 00095 { return x86_processor_flags_has(CPUID_CLMUL_BIT); } 00096 00097 /** 00098 * Check if the processor supports Intel SHA extension 00099 */ 00100 static bool has_intel_sha() 00101 { return x86_processor_flags_has(CPUID_SHA_BIT); } 00102 00103 /** 00104 * Check if the processor supports ADX extension 00105 */ 00106 static bool has_adx() 00107 { return x86_processor_flags_has(CPUID_ADX_BIT); } 00108 00109 /** 00110 * Check if the processor supports RDRAND 00111 */ 00112 static bool has_rdrand() 00113 { return x86_processor_flags_has(CPUID_RDRAND_BIT); } 00114 00115 /** 00116 * Check if the processor supports RDSEED 00117 */ 00118 static bool has_rdseed() 00119 { return x86_processor_flags_has(CPUID_RDSEED_BIT); } 00120 00121 static void print(std::ostream& o); 00122 private: 00123 enum CPUID_bits { 00124 CPUID_RDTSC_BIT = 4, 00125 CPUID_SSE2_BIT = 26, 00126 CPUID_CLMUL_BIT = 33, 00127 CPUID_SSSE3_BIT = 41, 00128 CPUID_SSE41_BIT = 51, 00129 CPUID_SSE42_BIT = 52, 00130 CPUID_AESNI_BIT = 57, 00131 CPUID_RDRAND_BIT = 62, 00132 00133 CPUID_AVX2_BIT = 64+5, 00134 CPUID_BMI2_BIT = 64+8, 00135 CPUID_AVX512F_BIT = 64+16, 00136 CPUID_RDSEED_BIT = 64+18, 00137 CPUID_ADX_BIT = 64+19, 00138 CPUID_SHA_BIT = 64+29, 00139 }; 00140 00141 static bool x86_processor_flags_has(u64bit bit) 00142 { 00143 if(!g_initialized) 00144 initialize(); 00145 return ((g_x86_processor_flags[bit/64] >> (bit % 64)) & 1); 00146 } 00147 00148 static bool g_initialized; 00149 static u64bit g_x86_processor_flags[2]; 00150 static size_t g_cache_line_size; 00151 static bool g_altivec_capable; 00152 }; 00153 00154 } 00155 00156 #endif