diff options
author | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-06-09 16:37:38 +0300 |
---|---|---|
committer | Jussi Kivilinna <jussi.kivilinna@iki.fi> | 2013-06-09 16:37:42 +0300 |
commit | 3289bca708bdd02c69a331095ac6ca9a1efd74cc (patch) | |
tree | 6bbf91993a4566d7c018fa0ee20751d3ed2e7c0a /src/hwf-x86.c | |
parent | d325ab5d86e6107a46007a4d0131122bbd719f8c (diff) | |
download | libgcrypt-3289bca708bdd02c69a331095ac6ca9a1efd74cc.tar.gz |
Add detection for Intel AVX2 instruction set
* configure.ac: Add option --disable-avx2-support.
(HAVE_GCC_INLINE_ASM_AVX2): New.
(ENABLE_AVX2_SUPPORT): New.
* src/g10lib.h (HWF_INTEL_AVX2): New.
* src/global.c (hwflist): Add HWF_INTEL_AVX2.
* src/hwf-x86.c [__i386__] (get_cpuid): Initialize registers to zero
before cpuid.
[__x86_64__] (get_cpuid): Initialize registers to zero before cpuid.
(detect_x86_gnuc): Store maximum cpuid level.
(detect_x86_gnuc) [ENABLE_AVX2_SUPPORT]: Add detection for AVX2.
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna@iki.fi>
Diffstat (limited to 'src/hwf-x86.c')
-rw-r--r-- | src/hwf-x86.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/src/hwf-x86.c b/src/hwf-x86.c index 1e6ec944..2ceb04c8 100644 --- a/src/hwf-x86.c +++ b/src/hwf-x86.c @@ -77,11 +77,12 @@ get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx, asm volatile ("pushl %%ebx\n\t" /* Save GOT register. */ + "movl %1, %%ebx\n\t" "cpuid\n\t" "movl %%ebx, %1\n\t" "popl %%ebx\n\t" /* Restore GOT register. */ : "=a" (regs[0]), "=r" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) - : "0" (in) + : "0" (in), "1" (0), "2" (0), "3" (0) : "cc" ); @@ -115,7 +116,7 @@ get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx, asm volatile ("cpuid\n\t" : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3]) - : "0" (in) + : "0" (in), "1" (0), "2" (0), "3" (0) : "cc" ); @@ -137,12 +138,13 @@ detect_x86_gnuc (void) { char vendor_id[12+1]; unsigned int features; + unsigned int max_cpuid_level; unsigned int result = 0; if (!is_cpuid_available()) return 0; - get_cpuid(0, NULL, + get_cpuid(0, &max_cpuid_level, (unsigned int *)&vendor_id[0], (unsigned int *)&vendor_id[8], (unsigned int *)&vendor_id[4]); @@ -215,6 +217,22 @@ detect_x86_gnuc (void) result |= HWF_INTEL_RDRAND; #endif /*ENABLE_DRNG_SUPPORT*/ + /* Check additional Intel feature flags. Early Intel P5 processors report + * too high max_cpuid_level, so don't check level 7 if processor does not + * support SSE3 (as cpuid:7 contains only features for newer processors). + * Source: http://www.sandpile.org/x86/cpuid.htm */ + if (max_cpuid_level >= 7 && (features & 0x00000001)) + { +#ifdef ENABLE_AVX2_SUPPORT + /* Get CPUID:7 contains further Intel feature flags. */ + get_cpuid(7, NULL, &features, NULL, NULL); + + /* Test bit 5 for AVX2. */ + if (features & 0x00000020) + result |= HWF_INTEL_AVX2; +#endif /*ENABLE_AVX_SUPPORT*/ + } + return result; } #endif /* HAS_X86_CPUID */ |