summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac35
-rw-r--r--src/g10lib.h1
-rw-r--r--src/global.c1
-rw-r--r--src/hwf-x86.c24
4 files changed, 58 insertions, 3 deletions
diff --git a/configure.ac b/configure.ac
index 8cb980c4..7fc7935c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -594,6 +594,14 @@ AC_ARG_ENABLE(avx-support,
avxsupport=$enableval,avxsupport=yes)
AC_MSG_RESULT($avxsupport)
+# Implementation of the --disable-avx2-support switch.
+AC_MSG_CHECKING([whether AVX2 support is requested])
+AC_ARG_ENABLE(avx2-support,
+ AC_HELP_STRING([--disable-avx2-support],
+ [Disable support for the Intel AVX2 instructions]),
+ avx2support=$enableval,avx2support=yes)
+AC_MSG_RESULT($avx2support)
+
# Implementation of the --disable-O-flag-munging switch.
AC_MSG_CHECKING([whether a -O flag munging is requested])
AC_ARG_ENABLE([O-flag-munging],
@@ -916,6 +924,23 @@ if test "$gcry_cv_gcc_inline_asm_avx" = "yes" ; then
fi
+#
+# Check whether GCC inline assembler supports AVX2 instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AVX2 instructions],
+ [gcry_cv_gcc_inline_asm_avx2],
+ [gcry_cv_gcc_inline_asm_avx2=no
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+ [[void a(void) {
+ __asm__("vpbroadcastb %%xmm7,%%ymm1\n\t":::);
+ }]])],
+ [gcry_cv_gcc_inline_asm_avx2=yes])])
+if test "$gcry_cv_gcc_inline_asm_avx2" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_AVX2,1,
+ [Defined if inline assembler supports AVX2 instructions])
+fi
+
+
#######################################
#### Checks for library functions. ####
#######################################
@@ -1165,6 +1190,11 @@ if test x"$avxsupport" = xyes ; then
avxsupport="no (unsupported by compiler)"
fi
fi
+if test x"$avx2support" = xyes ; then
+ if test "$gcry_cv_gcc_inline_asm_avx2" != "yes" ; then
+ avx2support="no (unsupported by compiler)"
+ fi
+fi
if test x"$aesnisupport" = xyes ; then
AC_DEFINE(ENABLE_AESNI_SUPPORT, 1,
@@ -1174,6 +1204,10 @@ if test x"$avxsupport" = xyes ; then
AC_DEFINE(ENABLE_AVX_SUPPORT,1,
[Enable support for Intel AVX instructions.])
fi
+if test x"$avx2support" = xyes ; then
+ AC_DEFINE(ENABLE_AVX2_SUPPORT,1,
+ [Enable support for Intel AVX2 instructions.])
+fi
# Define conditional sources and config.h symbols depending on the
@@ -1513,6 +1547,7 @@ GCRY_MSG_SHOW([Try using Padlock crypto: ],[$padlocksupport])
GCRY_MSG_SHOW([Try using AES-NI crypto: ],[$aesnisupport])
GCRY_MSG_SHOW([Try using DRNG (RDRAND): ],[$drngsupport])
GCRY_MSG_SHOW([Try using Intel AVX: ],[$avxsupport])
+GCRY_MSG_SHOW([Try using Intel AVX2: ],[$avx2support])
GCRY_MSG_SHOW([],[])
if test "$print_egd_notice" = "yes"; then
diff --git a/src/g10lib.h b/src/g10lib.h
index 23ea0960..e6d20e97 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -153,6 +153,7 @@ int _gcry_log_verbosity( int level );
#define HWF_INTEL_AESNI 256
#define HWF_INTEL_RDRAND 512
#define HWF_INTEL_AVX 1024
+#define HWF_INTEL_AVX2 2048
unsigned int _gcry_get_hw_features (void);
diff --git a/src/global.c b/src/global.c
index a6fe9804..9c80573e 100644
--- a/src/global.c
+++ b/src/global.c
@@ -69,6 +69,7 @@ static struct
{ HWF_INTEL_AESNI, "intel-aesni" },
{ HWF_INTEL_RDRAND,"intel-rdrand" },
{ HWF_INTEL_AVX, "intel-avx" },
+ { HWF_INTEL_AVX2, "intel-avx2" },
{ 0, NULL}
};
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 */