1 /* 2 * Runtime CPU detection 3 * (C) 2009-2010 Jack Lloyd 4 * 5 * Distributed under the terms of the Botan license 6 */ 7 8 #ifndef BOTAN_CPUID_H__ 9 #define BOTAN_CPUID_H__ 10 11 #include <botan/types.h> 12 13 namespace Botan { 14 15 /** 16 * A class handling runtime CPU feature detection 17 */ 18 class BOTAN_DLL CPUID 19 { 20 public: 21 /** 22 * Probe the CPU and see what extensions are supported 23 */ 24 static void initialize(); 25 26 /** 27 * Return a best guess of the cache line size 28 */ cache_line_size()29 static size_t cache_line_size() { return cache_line; } 30 31 /** 32 * Check if the processor supports RDTSC 33 */ has_rdtsc()34 static bool has_rdtsc() 35 { return x86_processor_flags_has(CPUID_RDTSC_BIT); } 36 37 /** 38 * Check if the processor supports SSE2 39 */ has_sse2()40 static bool has_sse2() 41 { return x86_processor_flags_has(CPUID_SSE2_BIT); } 42 43 /** 44 * Check if the processor supports SSSE3 45 */ has_ssse3()46 static bool has_ssse3() 47 { return x86_processor_flags_has(CPUID_SSSE3_BIT); } 48 49 /** 50 * Check if the processor supports SSE4.1 51 */ has_sse41()52 static bool has_sse41() 53 { return x86_processor_flags_has(CPUID_SSE41_BIT); } 54 55 /** 56 * Check if the processor supports SSE4.2 57 */ has_sse42()58 static bool has_sse42() 59 { return x86_processor_flags_has(CPUID_SSE42_BIT); } 60 61 /** 62 * Check if the processor supports extended AVX vector instructions 63 */ has_avx()64 static bool has_avx() 65 { return x86_processor_flags_has(CPUID_AVX_BIT); } 66 67 /** 68 * Check if the processor supports AES-NI 69 */ has_aes_ni()70 static bool has_aes_ni() 71 { return x86_processor_flags_has(CPUID_AESNI_BIT); } 72 73 /** 74 * Check if the processor supports PCMULUDQ 75 */ has_pcmuludq()76 static bool has_pcmuludq() 77 { return x86_processor_flags_has(CPUID_PCMUL_BIT); } 78 79 /** 80 * Check if the processor supports MOVBE 81 */ has_movbe()82 static bool has_movbe() 83 { return x86_processor_flags_has(CPUID_MOVBE_BIT); } 84 85 /** 86 * Check if the processor supports RDRAND 87 */ has_rdrand()88 static bool has_rdrand() 89 { return x86_processor_flags_has(CPUID_RDRAND_BIT); } 90 91 /** 92 * Check if the processor supports AltiVec/VMX 93 */ has_altivec()94 static bool has_altivec() { return altivec_capable; } 95 private: 96 enum CPUID_bits { 97 CPUID_RDTSC_BIT = 4, 98 CPUID_SSE2_BIT = 26, 99 CPUID_PCMUL_BIT = 33, 100 CPUID_SSSE3_BIT = 41, 101 CPUID_SSE41_BIT = 51, 102 CPUID_SSE42_BIT = 52, 103 CPUID_MOVBE_BIT = 54, 104 CPUID_AESNI_BIT = 57, 105 CPUID_AVX_BIT = 60, 106 CPUID_RDRAND_BIT = 62 107 }; 108 x86_processor_flags_has(u64bit bit)109 static bool x86_processor_flags_has(u64bit bit) 110 { 111 return ((x86_processor_flags >> bit) & 1); 112 } 113 114 static u64bit x86_processor_flags; 115 static size_t cache_line; 116 static bool altivec_capable; 117 }; 118 119 } 120 121 #endif 122