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 | |
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>
-rw-r--r-- | configure.ac | 35 | ||||
-rw-r--r-- | src/g10lib.h | 1 | ||||
-rw-r--r-- | src/global.c | 1 | ||||
-rw-r--r-- | src/hwf-x86.c | 24 |
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 */ |