diff options
author | lloyd <[email protected]> | 2009-09-25 11:51:58 +0000 |
---|---|---|
committer | lloyd <[email protected]> | 2009-09-25 11:51:58 +0000 |
commit | 2c817e542ab946c8d1b38f0ebb52c624a8076169 (patch) | |
tree | f272fb6f5639fd43064ef92e6a7f26f062b790ff /src/utils | |
parent | 6cb4b06db7855fa8bec60b2965fe34fb01e5896c (diff) | |
parent | 03f41b6ceb6e9dcfbe4b134239431de43afd7e6b (diff) |
merge of '1efb42e84eca9e01edd7b7f1335af7011eab994c'
and 'bb55abb64b64ca63aeb361db40c6bc4692d4ce48'
Diffstat (limited to 'src/utils')
-rw-r--r-- | src/utils/cpuid.cpp | 108 | ||||
-rw-r--r-- | src/utils/cpuid.h | 51 | ||||
-rw-r--r-- | src/utils/info.txt | 2 |
3 files changed, 161 insertions, 0 deletions
diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp new file mode 100644 index 000000000..4f22ef867 --- /dev/null +++ b/src/utils/cpuid.cpp @@ -0,0 +1,108 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/cpuid.h> +#include <botan/types.h> + +#if defined(_MSC_VER) + #include <intrin.h> +#endif + +namespace Botan { + +namespace CPUID { + +namespace { + +/* +* Call the x86 CPUID instruction and return the contents of ecx and +* edx, which contain the feature masks. +*/ +u64bit x86_processor_flags() + { + static u64bit proc_flags = 0; + + if(proc_flags) + return proc_flags; + +#if defined(BOTAN_TARGET_ARCH_IS_X86) || defined(BOTAN_TARGET_ARCH_IS_AMD64) + +#if defined(__GNUG__) + + u32bit a = 1, b = 0, c = 0, d = 0; + +#if defined(__i386__) && defined(__PIC__) + // ebx is used in PIC on 32-bit x86, so save and restore it + asm("xchgl %%ebx, %1\n\t" + "cpuid\n\t" + "xchgl %%ebx, %1\n\t" + : "=a" (a), "=r" (b), "=c" (c), "=d" (d) : "0" (a)); +#else + // if not PIC or in 64-bit mode, can smash ebx + asm("cpuid" : "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "0" (a)); + +#endif + + proc_flags = ((u64bit)c << 32) | d; + +#elif defined(_MSC_VER) + + int cpuinfo[4] = { 0 }; + __cpuid(cpuinfo, 1); + + proc_flags = ((u64bit)cpuinfo[2] << 32) | cpuinfo[3]; + +#endif + +#endif + + return proc_flags; + } + +enum CPUID_bits { + CPUID_RDTSC_BIT = 4, + CPUID_SSE2_BIT = 26, + CPUID_SSSE3_BIT = 41, + CPUID_SSE41_BIT = 51, + CPUID_SSE42_BIT = 52 +}; + +} + +u32bit cache_line_size() + { + return 32; // FIXME! + } + +bool has_rdtsc() + { + return ((x86_processor_flags() >> CPUID_RDTSC_BIT) & 1); + } + +bool has_sse2() + { + return ((x86_processor_flags() >> CPUID_SSE2_BIT) & 1); + } + +bool has_ssse3() + { + return ((x86_processor_flags() >> CPUID_SSSE3_BIT) & 1); + } + +bool has_sse41() + { + return ((x86_processor_flags() >> CPUID_SSE41_BIT) & 1); + } + +bool has_sse42() + { + return ((x86_processor_flags() >> CPUID_SSE42_BIT) & 1); + } + +} + +} diff --git a/src/utils/cpuid.h b/src/utils/cpuid.h new file mode 100644 index 000000000..557590db8 --- /dev/null +++ b/src/utils/cpuid.h @@ -0,0 +1,51 @@ +/** +* Runtime CPU detection +* (C) 2009 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_CPUID_H__ +#define BOTAN_CPUID_H__ + +#include <botan/types.h> + +namespace Botan { + +namespace CPUID { + +/** +* Return a best guess of the cache line size +*/ +u32bit cache_line_size(); + +/** +* Check if the processor supports RDTSC +*/ +bool has_rdtsc(); + +/** +* Check if the processor supports SSE2 +*/ +bool has_sse2(); + +/** +* Check if the processor supports SSSE3 +*/ +bool has_ssse3(); + +/** +* Check if the processor supports SSE4.1 +*/ +bool has_sse41(); + +/** +* Check if the processor supports SSE4.2 +*/ +bool has_sse42(); + +} + +} + +#endif diff --git a/src/utils/info.txt b/src/utils/info.txt index 68981729f..f530fb03a 100644 --- a/src/utils/info.txt +++ b/src/utils/info.txt @@ -13,6 +13,8 @@ bit_ops.h bswap.h charset.cpp charset.h +cpuid.cpp +cpuid.h exceptn.cpp exceptn.h loadstor.h |