summaryrefslogtreecommitdiff
path: root/src/hwf-x86.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@iki.fi>2013-06-09 16:37:38 +0300
committerJussi Kivilinna <jussi.kivilinna@iki.fi>2013-06-09 16:37:42 +0300
commit3289bca708bdd02c69a331095ac6ca9a1efd74cc (patch)
tree6bbf91993a4566d7c018fa0ee20751d3ed2e7c0a /src/hwf-x86.c
parentd325ab5d86e6107a46007a4d0131122bbd719f8c (diff)
downloadlibgcrypt-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.c24
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 */