[PATCH 2/3] Add detection for HW feature "intel-avx512"
Jussi Kivilinna
jussi.kivilinna at iki.fi
Sun Mar 6 18:19:09 CET 2022
* configure.ac (avx512support, gcry_cv_gcc_inline_asm_avx512)
(ENABLE_AVX512_SUPPORT): New.
* src/g10lib.h (HWF_INTEL_AVX512): New.
* src/hwf-x86.c (detect_x86_gnuc): Add AVX512 detection.
* src/hwfeatures.c (hwflist): Add "intel-avx512".
--
Signed-off-by: Jussi Kivilinna <jussi.kivilinna at iki.fi>
---
configure.ac | 36 +++++++++++++++++++++++++++++++++++
src/g10lib.h | 1 +
src/hwf-x86.c | 49 +++++++++++++++++++++++++++++++++++++++++++++---
src/hwfeatures.c | 1 +
4 files changed, 84 insertions(+), 3 deletions(-)
diff --git a/configure.ac b/configure.ac
index e20f9d13..27d72141 100644
--- a/configure.ac
+++ b/configure.ac
@@ -667,6 +667,14 @@ AC_ARG_ENABLE(avx2-support,
avx2support=$enableval,avx2support=yes)
AC_MSG_RESULT($avx2support)
+# Implementation of the --disable-avx512-support switch.
+AC_MSG_CHECKING([whether AVX512 support is requested])
+AC_ARG_ENABLE(avx512-support,
+ AS_HELP_STRING([--disable-avx512-support],
+ [Disable support for the Intel AVX512 instructions]),
+ avx512support=$enableval,avx512support=yes)
+AC_MSG_RESULT($avx512support)
+
# Implementation of the --disable-neon-support switch.
AC_MSG_CHECKING([whether NEON support is requested])
AC_ARG_ENABLE(neon-support,
@@ -1545,6 +1553,29 @@ if test "$gcry_cv_gcc_inline_asm_avx2" = "yes" ; then
fi
+#
+# Check whether GCC inline assembler supports AVX512 instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AVX512 instructions],
+ [gcry_cv_gcc_inline_asm_avx512],
+ [if test "$mpi_cpu_arch" != "x86" ||
+ test "$try_asm_modules" != "yes" ; then
+ gcry_cv_gcc_inline_asm_avx512="n/a"
+ else
+ gcry_cv_gcc_inline_asm_avx512=no
+ AC_LINK_IFELSE([AC_LANG_PROGRAM(
+ [[void a(void) {
+ __asm__("xgetbv; vpopcntq %%zmm7, %%zmm1%{%%k1%}%{z%};\n\t":::"cc");
+ __asm__("vpexpandb %%zmm3, %%zmm1;\n\t":::"cc");
+ }]], [ a(); ] )],
+ [gcry_cv_gcc_inline_asm_avx512=yes])
+ fi])
+if test "$gcry_cv_gcc_inline_asm_avx512" = "yes" ; then
+ AC_DEFINE(HAVE_GCC_INLINE_ASM_AVX512,1,
+ [Defined if inline assembler supports AVX512 instructions])
+fi
+
+
#
# Check whether GCC inline assembler supports VAES and VPCLMUL instructions
#
@@ -2409,6 +2440,10 @@ if test x"$avx2support" = xyes ; then
AC_DEFINE(ENABLE_AVX2_SUPPORT,1,
[Enable support for Intel AVX2 instructions.])
fi
+if test x"$avx512support" = xyes ; then
+ AC_DEFINE(ENABLE_AVX512_SUPPORT,1,
+ [Enable support for Intel AVX512 instructions.])
+fi
if test x"$neonsupport" = xyes ; then
AC_DEFINE(ENABLE_NEON_SUPPORT,1,
[Enable support for ARM NEON instructions.])
@@ -3266,6 +3301,7 @@ GCRY_MSG_SHOW([Try using Intel SSE4.1: ],[$sse41support])
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([Try using Intel AVX512: ],[$avx512support])
GCRY_MSG_SHOW([Try using ARM NEON: ],[$neonsupport])
GCRY_MSG_SHOW([Try using ARMv8 crypto: ],[$armcryptosupport])
GCRY_MSG_SHOW([Try using PPC crypto: ],[$ppccryptosupport])
diff --git a/src/g10lib.h b/src/g10lib.h
index 985e75c6..c07ed788 100644
--- a/src/g10lib.h
+++ b/src/g10lib.h
@@ -237,6 +237,7 @@ char **_gcry_strtokenize (const char *string, const char *delim);
#define HWF_INTEL_RDTSC (1 << 15)
#define HWF_INTEL_SHAEXT (1 << 16)
#define HWF_INTEL_VAES_VPCLMUL (1 << 17)
+#define HWF_INTEL_AVX512 (1 << 18)
#elif defined(HAVE_CPU_ARCH_ARM)
diff --git a/src/hwf-x86.c b/src/hwf-x86.c
index a1aa02e7..0a5266c6 100644
--- a/src/hwf-x86.c
+++ b/src/hwf-x86.c
@@ -182,12 +182,14 @@ detect_x86_gnuc (void)
} vendor_id;
unsigned int features, features2;
unsigned int os_supports_avx_avx2_registers = 0;
+ unsigned int os_supports_avx512_registers = 0;
unsigned int max_cpuid_level;
unsigned int fms, family, model;
unsigned int result = 0;
unsigned int avoid_vpgather = 0;
(void)os_supports_avx_avx2_registers;
+ (void)os_supports_avx512_registers;
if (!is_cpuid_available())
return 0;
@@ -338,13 +340,22 @@ detect_x86_gnuc (void)
if (features & 0x02000000)
result |= HWF_INTEL_AESNI;
#endif /*ENABLE_AESNI_SUPPORT*/
-#if defined(ENABLE_AVX_SUPPORT) || defined(ENABLE_AVX2_SUPPORT)
- /* Test bit 27 for OSXSAVE (required for AVX/AVX2). */
+#if defined(ENABLE_AVX_SUPPORT) || defined(ENABLE_AVX2_SUPPORT) \
+ || defined(ENABLE_AVX512_SUPPORT)
+ /* Test bit 27 for OSXSAVE (required for AVX/AVX2/AVX512). */
if (features & 0x08000000)
{
+ unsigned int xmm_ymm_mask = (1 << 2) | (1 << 1);
+ unsigned int zmm15_ymm31_k7_mask = (1 << 7) | (1 << 6) | (1 << 5);
+ unsigned int xgetbv = get_xgetbv();
+
/* Check that OS has enabled both XMM and YMM state support. */
- if ((get_xgetbv() & 0x6) == 0x6)
+ if ((xgetbv & xmm_ymm_mask) == xmm_ymm_mask)
os_supports_avx_avx2_registers = 1;
+
+ /* Check that OS has enabled both XMM and YMM state support. */
+ if ((xgetbv & zmm15_ymm31_k7_mask) == zmm15_ymm31_k7_mask)
+ os_supports_avx512_registers = 1;
}
#endif
#ifdef ENABLE_AVX_SUPPORT
@@ -396,6 +407,38 @@ detect_x86_gnuc (void)
if ((features2 & 0x00000200) && (features2 & 0x00000400))
result |= HWF_INTEL_VAES_VPCLMUL;
#endif
+
+#ifdef ENABLE_AVX512_SUPPORT
+ /* Test for AVX512 features. List of features is selected so that
+ * supporting CPUs are new enough not to suffer from reduced clock
+ * frequencies when AVX512 is used, which was issue on early AVX512
+ * capable CPUs.
+ * - AVX512F (features bit 16)
+ * - AVX512DQ (features bit 17)
+ * - AVX512IFMA (features bit 21)
+ * - AVX512CD (features bit 28)
+ * - AVX512BW (features bit 30)
+ * - AVX512VL (features bit 31)
+ * - AVX512_VBMI (features2 bit 1)
+ * - AVX512_VBMI2 (features2 bit 6)
+ * - AVX512_VNNI (features2 bit 11)
+ * - AVX512_BITALG (features2 bit 12)
+ * - AVX512_VPOPCNTDQ (features2 bit 14)
+ */
+ if (os_supports_avx512_registers
+ && (features & (1 << 16))
+ && (features & (1 << 17))
+ && (features & (1 << 21))
+ && (features & (1 << 28))
+ && (features & (1 << 30))
+ && (features & (1 << 31))
+ && (features2 & (1 << 1))
+ && (features2 & (1 << 6))
+ && (features2 & (1 << 11))
+ && (features2 & (1 << 12))
+ && (features2 & (1 << 14)))
+ result |= HWF_INTEL_AVX512;
+#endif
}
return result;
diff --git a/src/hwfeatures.c b/src/hwfeatures.c
index 7060d995..8e92cbdd 100644
--- a/src/hwfeatures.c
+++ b/src/hwfeatures.c
@@ -62,6 +62,7 @@ static struct
{ HWF_INTEL_RDTSC, "intel-rdtsc" },
{ HWF_INTEL_SHAEXT, "intel-shaext" },
{ HWF_INTEL_VAES_VPCLMUL, "intel-vaes-vpclmul" },
+ { HWF_INTEL_AVX512, "intel-avx512" },
#elif defined(HAVE_CPU_ARCH_ARM)
{ HWF_ARM_NEON, "arm-neon" },
{ HWF_ARM_AES, "arm-aes" },
--
2.32.0
More information about the Gcrypt-devel
mailing list