diff --git a/conf/Makefile.common b/conf/Makefile.common index 4d38ff034..7ef171b2b 100644 --- a/conf/Makefile.common +++ b/conf/Makefile.common @@ -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)/,,$<)\" diff --git a/configure.ac b/configure.ac index 1036638a9..1f391fa8e 100644 --- a/configure.ac +++ b/configure.ac @@ -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"