mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-04-13 15:11:45 +03:00
We need to select which SIMD variable to check based on the compilation target: HAVE_KERNEL_xxx for the Linux kernel, HAVE_TOOLCHAIN_xxx for other platforms. This adds a HAVE_SIMD() macro returns the right result depending on the definedness or value of the variable for this target. The macro is in simd_config.h, which is forcibly included in every compiler call (like zfs_config.h), to ensure that it can be used directly without further includes. Sponsored-by: TrueNAS Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <rob.norris@truenas.com> Closes #18285
103 lines
3.5 KiB
C
103 lines
3.5 KiB
C
// SPDX-License-Identifier: CDDL-1.0
|
|
/*
|
|
* CDDL HEADER START
|
|
*
|
|
* The contents of this file are subject to the terms of the
|
|
* Common Development and Distribution License (the "License").
|
|
* You may not use this file except in compliance with the License.
|
|
*
|
|
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
|
|
* or https://opensource.org/licenses/CDDL-1.0.
|
|
* See the License for the specific language governing permissions
|
|
* and limitations under the License.
|
|
*
|
|
* When distributing Covered Code, include this CDDL HEADER in each
|
|
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
|
|
* If applicable, add the following below this CDDL HEADER, with the
|
|
* fields enclosed by brackets "[]" replaced with your own identifying
|
|
* information: Portions Copyright [yyyy] [name of copyright owner]
|
|
*
|
|
* CDDL HEADER END
|
|
*/
|
|
/*
|
|
* Copyright (c) 2026, TrueNAS.
|
|
*/
|
|
|
|
#ifndef _SYS_SIMD_CONFIG_H
|
|
#define _SYS_SIMD_CONFIG_H
|
|
|
|
/*
|
|
* Goal: a HAVE_SIMD(x) macro that expands to either 1 or 0 depending on
|
|
* the availabilty of that extension on the wanted toolchain.
|
|
*
|
|
* We need to allow the following:
|
|
* - #define HAVE_TOOLCHAIN_AVX 1 (zfs_config.h, detected by configure)
|
|
* - #undef HAVE_TOOLCHAIN_AVX (zfs_config.h, probed but not detected)
|
|
* - -DHAVE_TOOLCHAIN_AVX (Makefile.bsd)
|
|
*
|
|
* For completeness, we also allow disabling by defined HAVE_TOOLCHAIN_AVX=0.
|
|
*
|
|
* The "obvious" implementation of this would be a macro that includes
|
|
* defined(...) in its expansion, but unfortunately that is not portable, and
|
|
* can produce compiler warnings (see -Wexpansion-to-defined). So we need to
|
|
* build our own version.
|
|
*/
|
|
|
|
/*
|
|
* 1. Expand incoming token to its defined value, if anything:
|
|
* eg HAVE_SIMD(AVX)
|
|
* -> _zfs_deftrue(HAVE_TOOLCHAIN_AVX)
|
|
* or -> __zfs_deftrue() (HAVE_TOOLCHAIN_AVX defined)
|
|
* or -> __zfs_deftrue(1) (HAVE_TOOLCHAIN_AVX = 1)
|
|
* -> __zfs_deftrue(0) (HAVE_TOOLCHAIN_AVX = 0)
|
|
* or -> __zfs_deftrue(HAVE_TOOLCHAIN_AVX) (HAVE_TOOLCHAIN_AVX undef)
|
|
*/
|
|
#define _zfs_deftrue(x) __zfs_deftrue(x)
|
|
|
|
/*
|
|
* 2. Replace know values with a token that we control:
|
|
* __zfs_deftrue()
|
|
* -> ___zfs_deftrue(___zfs_deftrue_arg_)
|
|
* __zfs_deftrue(1)
|
|
* -> ___zfs_deftrue(___zfs_deftrue_arg_1)
|
|
* __zfs_deftrue(0)
|
|
* -> ___zfs_deftrue(___zfs_deftrue_arg_0)
|
|
* __zfs_deftrue(HAVE_TOOLCHAIN_AVX)
|
|
* -> ___zfs_deftrue(___zfs_deftrue_arg_HAVE_TOOLCHAIN_AVX)
|
|
*/
|
|
#define __zfs_deftrue(v) ___zfs_deftrue(___zfs_deftrue_arg_##v)
|
|
|
|
/*
|
|
* 3. Expand the incoming token into positional parameters for the next call:
|
|
* ___zfs_deftrue(___zfs_deftrue_arg_0)
|
|
* -> ____zfs_deftrue(0, 0, 0)
|
|
* ___zfs_deftrue(___zfs_deftrue_arg_1)
|
|
* -> ____zfs_deftrue(0, 1, 0)
|
|
* ___zfs_deftrue(___zfs_deftrue_arg_HAVE_TOOLCHAIN_AVX)
|
|
* -> ____zfs_deftrue(___zfs_deftrue_arg_HAVE_TOOLCHAIN_AVX, 0)
|
|
*/
|
|
#define ___zfs_deftrue_arg_ 0, 1
|
|
#define ___zfs_deftrue_arg_1 0, 1
|
|
#define ___zfs_deftrue_arg_0 0, 0
|
|
#define ___zfs_deftrue(t, ...) ____zfs_deftrue(t, 0)
|
|
|
|
/*
|
|
* 4. Emit the second argument, either the original value or the default 0.
|
|
* ____zfs_deftrue(0, 0, 0) -> 0
|
|
* ____zfs_deftrue(0, 1, 0) -> 1
|
|
* ____zfs_deftrue(___zfs_deftrue_arg_HAVE_TOOLCHAIN_AVX, 0) -> 0
|
|
*/
|
|
#define ____zfs_deftrue(_n, v, ...) v
|
|
|
|
/*
|
|
* The Linux kernel requires a specific toolchain. Everything else uses the
|
|
* regular compiler toolchain.
|
|
*/
|
|
#if defined(_KERNEL) && defined(__linux__)
|
|
#define HAVE_SIMD(ext) _zfs_deftrue(HAVE_KERNEL_##ext)
|
|
#else
|
|
#define HAVE_SIMD(ext) _zfs_deftrue(HAVE_TOOLCHAIN_##ext)
|
|
#endif
|
|
|
|
#endif
|