]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
configure: Tweak autoconf/automake files to detect x86_64 features
authorGary Lin <glin@suse.com>
Wed, 22 Oct 2025 01:28:51 +0000 (09:28 +0800)
committerDaniel Kiper <daniel.kiper@oracle.com>
Thu, 23 Oct 2025 17:14:59 +0000 (19:14 +0200)
To enable hardware acceleration, this commit ports the feature detection
logic from libgcrypt. This allows us to check if the compiler supports
specific assembly instructions, including SSSE3, Intel SHA extensions,
SSE4.1, AVX, AVX2, AVX512, and BMI2.

To simplify the initial implementation, support for x86_64 feature
detection is currently limited to the x86_64 EFI target.

Signed-off-by: Gary Lin <glin@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
conf/Makefile.common
configure.ac

index 4d38ff0346c38df71bc6b281c7a86df1c545450f..7ef171b2be3468fabe30b03e228deb4cc41ccee9 100644 (file)
@@ -24,6 +24,8 @@ if COND_HAVE_PCI
   CFLAGS_PLATFORM += -DGRUB_HAS_PCI
 endif
 
+CPPFLAGS_GCRY_ASM = @CPPFLAGS_GCRY_ASM@
+
 # Other options
 
 CPPFLAGS_DEFAULT = -DGRUB_FILE=\"$(subst $(srcdir)/,,$<)\"
index 1036638a965b042b99a222b66f29b72a3a8f1afb..1f391fa8ee28ac015f40d890c69801f6d7c3f172 100644 (file)
@@ -1148,6 +1148,239 @@ if test "x$grub_cv_cc_fno_ident" = xyes; then
   TARGET_CFLAGS="$TARGET_CFLAGS -fno-ident"
 fi
 
+# Implementation of the --disable-amd64-as-feature-detection switch.
+AC_MSG_CHECKING([whether to enable AMD64 as(1) feature detection])
+if test x$target_cpu == xx86_64 -a x$platform == xefi; then
+  CPPFLAGS_GCRY_ASM="-D__x86_64 -DHAVE_CPU_ARCH_X86"
+  AC_ARG_ENABLE(amd64-as-feature-detection,
+    AS_HELP_STRING([--disable-amd64-as-feature-detection],
+      [Disable the auto-detection of AMD64 as(1) features]),
+    [amd64_as_feature_detection=$enableval],
+    [amd64_as_feature_detection=yes])
+else
+  CPPFLAGS_GCRY_ASM=
+  amd64_as_feature_detection=no
+fi
+AC_MSG_RESULT($amd64_as_feature_detection)
+
+#
+# Check whether GCC assembler supports features needed for libgcrypt amd64
+# implementations
+#
+if test $amd64_as_feature_detection = yes; then
+  AC_CACHE_CHECK([whether GCC assembler is compatible for amd64 assembly implementations],
+    [grub_cv_gcc_x86_platform_as_ok],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_x86_platform_as_ok="n/a"
+     else
+       grub_cv_gcc_x86_platform_as_ok=no
+       AC_LINK_IFELSE([AC_LANG_PROGRAM(
+       [[__asm__(
+             /* Test if '.type' and '.size' are supported.  */
+             /* These work only on ELF targets. */
+             ".text\n\t"
+             "asmfunc:\n\t"
+             ".size asmfunc,.-asmfunc;\n\t"
+             ".type asmfunc,@function;\n\t"
+             /* Test if assembler allows use of '/' for constant division
+              * (Solaris/x86 issue). If previous constant division check
+              * and "-Wa,--divide" workaround failed, this causes assembly
+              * to be disable on this machine. */
+              "xorl \$(123456789/12345678), %ebp;\n\t"
+         );
+         void asmfunc(void);]], [ asmfunc(); ])],
+       [grub_cv_gcc_x86_platform_as_ok=yes])
+     fi])
+  if test "$grub_cv_gcc_x86_platform_as_ok" = "yes"; then
+    # Define __PIC__ to ensure the assembly code use PIC instructions
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -D__PIC__=1 -DHAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS"
+  fi
+
+  #
+  # Check whether GCC assembler supports Intel syntax
+  #
+  AC_CACHE_CHECK([whether GCC assembler is compatible for Intel syntax assembly implementations],
+    [grub_cv_gcc_platform_as_ok_for_intel_syntax],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_platform_as_ok_for_intel_syntax="n/a"
+     else
+       grub_cv_gcc_platform_as_ok_for_intel_syntax=no
+       AC_LINK_IFELSE([AC_LANG_PROGRAM(
+       [[__asm__(
+             ".intel_syntax noprefix\n\t"
+             ".text\n\t"
+             "actest:\n\t"
+             "pxor xmm1, xmm7;\n\t"
+             "vperm2i128 ymm2, ymm3, ymm0, 1;\n\t"
+             "add eax, ebp;\n\t"
+             "rorx eax, ebp, 1;\n\t"
+             "sub eax, [esp + 4];\n\t"
+             "add dword ptr [esp + eax], 0b10101;\n\t"
+             ".att_syntax prefix\n\t"
+         );
+         void actest(void);]], [ actest(); ])],
+       [grub_cv_gcc_platform_as_ok_for_intel_syntax=yes])
+     fi])
+  if test "$grub_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_INTEL_SYNTAX_PLATFORM_AS"
+  fi
+
+  #
+  # Check whether GCC inline assembler supports SSSE3 instructions
+  #
+  AC_CACHE_CHECK([whether GCC inline assembler supports SSSE3 instructions],
+    [grub_cv_gcc_inline_asm_ssse3],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_inline_asm_ssse3="n/a"
+     else
+       grub_cv_gcc_inline_asm_ssse3=no
+       AC_LINK_IFELSE([AC_LANG_PROGRAM(
+       [[static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+           { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+         void a(void) {
+           __asm__("pshufb %[mask], %%xmm2\n\t"::[mask]"m"(*be_mask):);
+         }]], [ a(); ] )],
+       [grub_cv_gcc_inline_asm_ssse3=yes])
+     fi])
+  if test "$grub_cv_gcc_inline_asm_ssse3" = "yes" ; then
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_SSSE3"
+  fi
+
+  #
+  # Check whether GCC inline assembler supports SHA Extensions instructions.
+  #
+  AC_CACHE_CHECK([whether GCC inline assembler supports SHA Extensions instructions],
+    [grub_cv_gcc_inline_asm_shaext],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_inline_asm_shaext="n/a"
+     else
+       grub_cv_gcc_inline_asm_shaext=no
+       AC_LINK_IFELSE([AC_LANG_PROGRAM(
+       [[void a(void) {
+           __asm__("sha1rnds4 \$0, %%xmm1, %%xmm3\n\t":::"cc");
+           __asm__("sha1nexte %%xmm1, %%xmm3\n\t":::"cc");
+           __asm__("sha1msg1 %%xmm1, %%xmm3\n\t":::"cc");
+           __asm__("sha1msg2 %%xmm1, %%xmm3\n\t":::"cc");
+           __asm__("sha256rnds2 %%xmm0, %%xmm1, %%xmm3\n\t":::"cc");
+           __asm__("sha256msg1 %%xmm1, %%xmm3\n\t":::"cc");
+           __asm__("sha256msg2 %%xmm1, %%xmm3\n\t":::"cc");
+         }]], [ a(); ] )],
+       [grub_cv_gcc_inline_asm_shaext=yes])
+     fi])
+  if test "$grub_cv_gcc_inline_asm_shaext" = "yes" ; then
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_SHAEXT -DENABLE_SHAEXT_SUPPORT"
+  fi
+
+  #
+  # Check whether GCC inline assembler supports SSE4.1 instructions.
+  #
+  AC_CACHE_CHECK([whether GCC inline assembler supports SSE4.1 instructions],
+    [grub_cv_gcc_inline_asm_sse41],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_inline_asm_sse41="n/a"
+     else
+       grub_cv_gcc_inline_asm_sse41=no
+       AC_LINK_IFELSE([AC_LANG_PROGRAM(
+       [[void a(void) {
+           int i;
+           __asm__("pextrd \$2, %%xmm0, %[out]\n\t" : [out] "=m" (i));
+         }]], [ a(); ] )],
+       [grub_cv_gcc_inline_asm_sse41=yes])
+     fi])
+  if test "$grub_cv_gcc_inline_asm_sse41" = "yes" ; then
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_SSE41"
+  fi
+
+  #
+  # Check whether GCC inline assembler supports AVX instructions
+  #
+  AC_CACHE_CHECK([whether GCC inline assembler supports AVX instructions],
+    [grub_cv_gcc_inline_asm_avx],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_inline_asm_avx="n/a"
+     else
+       grub_cv_gcc_inline_asm_avx=no
+       AC_LINK_IFELSE([AC_LANG_PROGRAM(
+       [[void a(void) {
+           __asm__("xgetbv; vaesdeclast (%[mem]),%%xmm0,%%xmm7\n\t"::[mem]"r"(0):);
+         }]], [ a(); ] )],
+       [grub_cv_gcc_inline_asm_avx=yes])
+     fi])
+  if test "$grub_cv_gcc_inline_asm_avx" = "yes" ; then
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_AVX"
+  fi
+
+  #
+  # Check whether GCC inline assembler supports AVX2 instructions
+  #
+  AC_CACHE_CHECK([whether GCC inline assembler supports AVX2 instructions],
+    [grub_cv_gcc_inline_asm_avx2],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_inline_asm_avx2="n/a"
+     else
+       grub_cv_gcc_inline_asm_avx2=no
+       AC_LINK_IFELSE([AC_LANG_PROGRAM(
+       [[void a(void) {
+           __asm__("xgetbv; vpbroadcastb %%xmm7,%%ymm1\n\t":::"cc");
+         }]], [ a(); ] )],
+       [grub_cv_gcc_inline_asm_avx2=yes])
+     fi])
+  if test "$grub_cv_gcc_inline_asm_avx2" = "yes" ; then
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_AVX2"
+  fi
+
+  #
+  # Check whether GCC inline assembler supports AVX512 instructions
+  #
+  AC_CACHE_CHECK([whether GCC inline assembler supports AVX512 instructions],
+    [grub_cv_gcc_inline_asm_avx512],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_inline_asm_avx512="n/a"
+     else
+       grub_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");
+           __asm__("vpxorq %%xmm7, %%xmm7, %%xmm7;\n\t":::"cc");
+           __asm__("vpxorq %%ymm7, %%ymm7, %%ymm7;\n\t":::"cc");
+           __asm__("vpxorq (%%eax)%{1to8%}, %%zmm7, %%zmm7;\n\t":::"cc");
+         }]], [ a(); ] )],
+       [grub_cv_gcc_inline_asm_avx512=yes])
+     fi])
+  if test "$grub_cv_gcc_inline_asm_avx512" = "yes" ; then
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_AVX512"
+  fi
+
+  #
+  # Check whether GCC inline assembler supports BMI2 instructions
+  #
+  AC_CACHE_CHECK([whether GCC inline assembler supports BMI2 instructions],
+    [grub_cv_gcc_inline_asm_bmi2],
+    [if test "$target_cpu" != "x86_64" ; then
+       grub_cv_gcc_inline_asm_bmi2="n/a"
+     else
+       grub_cv_gcc_inline_asm_bmi2=no
+       AC_LINK_IFELSE([AC_LANG_PROGRAM(
+       [[unsigned int a(unsigned int x, unsigned int y) {
+           unsigned int tmp1, tmp2;
+           asm ("rorxl %2, %1, %0"
+                : "=r" (tmp1)
+                : "rm0" (x), "J" (32 - ((23) & 31)));
+           asm ("andnl %2, %1, %0"
+                : "=r" (tmp2)
+                : "r0" (x), "rm" (y));
+           return tmp1 + tmp2;
+         }]], [ a(1, 2); ] )],
+       [grub_cv_gcc_inline_asm_bmi2=yes])
+     fi])
+  if test "$grub_cv_gcc_inline_asm_bmi2" = "yes" ; then
+    CPPFLAGS_GCRY_ASM="$CPPFLAGS_GCRY_ASM -DHAVE_GCC_INLINE_ASM_BMI2"
+  fi
+fi
+
+AC_SUBST(CPPFLAGS_GCRY_ASM)
+
 CFLAGS="$TARGET_CFLAGS"