mirror_zfs/config/toolchain-simd.m4

89 lines
3.1 KiB
Plaintext
Raw Normal View History

dnl # SPDX-License-Identifier: CDDL-1.0
Support for vectorized algorithms on x86 This is initial support for x86 vectorized implementations of ZFS parity and checksum algorithms. For the compilation phase, configure step checks if toolchain supports relevant instruction sets. Each implementation must ensure that the code is not passed to compiler if relevant instruction set is not supported. For this purpose, following new defines are provided if instruction set is supported: - HAVE_SSE, - HAVE_SSE2, - HAVE_SSE3, - HAVE_SSSE3, - HAVE_SSE4_1, - HAVE_SSE4_2, - HAVE_AVX, - HAVE_AVX2. For detecting if an instruction set can be used in runtime, following functions are provided in (include/linux/simd_x86.h): - zfs_sse_available() - zfs_sse2_available() - zfs_sse3_available() - zfs_ssse3_available() - zfs_sse4_1_available() - zfs_sse4_2_available() - zfs_avx_available() - zfs_avx2_available() - zfs_bmi1_available() - zfs_bmi2_available() These function should be called once, on module load, or initialization. They are safe to use from user and kernel space. If an implementation is using more than single instruction set, both compiler and runtime support for all relevant instruction sets should be checked. Kernel fpu methods: - kfpu_begin() - kfpu_end() Use __get_cpuid_max and __cpuid_count from <cpuid.h> Both gcc and clang have support for these. They also handle ebx register in case it is used for PIC code. Signed-off-by: Gvozden Neskovic <neskovic@gmail.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Chunwei Chen <tuxoko@gmail.com> Closes #4381
2016-02-29 21:42:27 +03:00
dnl #
dnl # Checks if host toolchain supports SIMD instructions
dnl #
dnl #
dnl # Each invocation of ZFS_AC_TOOLCHAIN_SIMD_CHECK(name, asmsrc) creates
dnl # two sets of macros:
dnl # - ZFS_AC_TOOLCHAIN_SIMD_<name>
dnl # - ZFS_AC_KERNEL_SRC_SIMD_<name> & ZFS_AC_KERNEL_SIMD_<name>
dnl #
dnl # These try to compile the given <asmsrc> in a __asm__ directive, using
dnl # either the host or the kernel toolchains. Successful checks set
dnl # HAVE_TOOLCHAIN_<name> or HAVE_KERNEL_<name>, respectively.
dnl #
AC_DEFUN([ZFS_AC_SIMD_CHECK], [
AC_DEFUN([ZFS_AC_TOOLCHAIN_SIMD_]m4_quote($1), [
AC_MSG_CHECKING([whether host toolchain supports $1])
AC_LINK_IFELSE([AC_LANG_SOURCE([[
int main () {
__asm__ __volatile__($2);
return (0);
}
]])], [
AC_DEFINE([HAVE_TOOLCHAIN_$1], 1,
[Define if host toolchain supports $1])
AC_MSG_RESULT([yes])
], [
AC_MSG_RESULT([no])
])
])
AC_DEFUN([ZFS_AC_KERNEL_SRC_SIMD_]m4_quote($1), [
ZFS_LINUX_TEST_SRC(
[simd_]m4_quote(m4_translit([$1], [A-Z], [a-z])), [], [
__asm__ __volatile__($2);
])
])
AC_DEFUN([ZFS_AC_KERNEL_SIMD_]m4_quote($1), [
AC_MSG_CHECKING([whether kernel toolchain supports $1])
ZFS_LINUX_TEST_RESULT(
[simd_]m4_quote(m4_translit([$1], [A-Z], [a-z])), [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_KERNEL_$1], 1,
[Define if kernel toolchain supports $1])
], [
AC_MSG_RESULT([no])
])
])
dnl Stash the names of the new functions so we can execute them later.
m4_pushdef([_zfs_ac_toolchain_simd_checks],
[ZFS_AC_TOOLCHAIN_SIMD_]m4_quote($1))
m4_pushdef([_zfs_ac_kernel_src_simd_checks],
[ZFS_AC_KERNEL_SRC_SIMD_]m4_quote($1))
m4_pushdef([_zfs_ac_kernel_simd_checks],
[ZFS_AC_KERNEL_SIMD_]m4_quote($1))
])
dnl # Invoke the macros created by ZFS_AC_TOOLCHAIN_SIMD_CHECK.
AC_DEFUN([ZFS_AC_TOOLCHAIN_SIMD], [
m4_stack_foreach([_zfs_ac_toolchain_simd_checks], [m4_indir])
])
AC_DEFUN([ZFS_AC_KERNEL_SRC_SIMD], [
m4_stack_foreach([_zfs_ac_kernel_src_simd_checks], [m4_indir])
])
AC_DEFUN([ZFS_AC_KERNEL_SIMD], [
m4_stack_foreach([_zfs_ac_kernel_simd_checks], [m4_indir])
])
dnl # Instruction sets to test
ZFS_AC_SIMD_CHECK([SSE2], ["pxor %xmm0, %xmm1"])
ZFS_AC_SIMD_CHECK([SSSE3], ["pshufb %xmm0, %xmm1"])
ZFS_AC_SIMD_CHECK([SSE4_1], ["pmaxsb %xmm0, %xmm1"])
ZFS_AC_SIMD_CHECK([AVX], ["vmovdqa %ymm0, %ymm1"])
ZFS_AC_SIMD_CHECK([AVX2], ["vpshufb %ymm0, %ymm1, %ymm2"])
ZFS_AC_SIMD_CHECK([AVX512F], ["vpandd %zmm0, %zmm1, %zmm2"])
ZFS_AC_SIMD_CHECK([AVX512BW], ["vpshufb %zmm0, %zmm1, %zmm2"])
ZFS_AC_SIMD_CHECK([AVX512VL], ["vpabsq %zmm0,%zmm1"])
ZFS_AC_SIMD_CHECK([AES], ["aesenc %xmm0, %xmm1"])
ZFS_AC_SIMD_CHECK([PCLMULQDQ], ["pclmulqdq %0, %%xmm0, %%xmm1" :: "i"(0)])
ZFS_AC_SIMD_CHECK([MOVBE], ["movbe 0(%eax), %eax"])
ZFS_AC_SIMD_CHECK([VAES], ["vaesenc %ymm0, %ymm1, %ymm0"])
ZFS_AC_SIMD_CHECK([VPCLMULQDQ], ["vpclmulqdq %0, %%ymm4, %%ymm3, %%ymm5" :: "i"(0)])
ZFS_AC_SIMD_CHECK([SHA512EXT], ["vsha512msg2 %ymm5, %ymm6"])
ZFS_AC_SIMD_CHECK([XSAVE], ["xsave 0"])
ZFS_AC_SIMD_CHECK([XSAVEOPT], ["xsaveopt 0"])
ZFS_AC_SIMD_CHECK([XSAVES], ["xsaves 0"])