From fbbe92fa28a9bc393b971052898aef2fa1dd8397 Mon Sep 17 00:00:00 2001 From: Evan Nemerson Date: Thu, 30 Jul 2020 13:49:43 -0700 Subject: [PATCH] Add static dispatch macros. --- CMakeLists.txt | 2 + sleef-config.h.in | 23 +++++- src/libm/CMakeLists.txt | 10 +++ src/libm/mkstatic.c | 150 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 src/libm/mkstatic.c diff --git a/CMakeLists.txt b/CMakeLists.txt index d3e8349d..00ba2589 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,8 @@ set(TARGET_MKRENAME_GNUABI "mkrename_gnuabi") set(TARGET_MKMASKED_GNUABI "mkmasked_gnuabi") # Generates the helper executable file mkdisp needed to write the sleef header set(TARGET_MKDISP "mkdisp") +# Generates the helper executable file mkstatic for generating the static dispatch macros +set(TARGET_MKSTATIC "mkstatic") set(TARGET_MKALIAS "mkalias") # Generates static library common # Defined in src/common/CMakeLists.txt via command add_library diff --git a/sleef-config.h.in b/sleef-config.h.in index 58316f45..3004ae7b 100644 --- a/sleef-config.h.in +++ b/sleef-config.h.in @@ -8,9 +8,30 @@ // FEATURE DETECTION *********************************************************** +#cmakedefine COMPILER_SUPPORTS_BUILTIN_MATH #cmakedefine COMPILER_SUPPORTS_LONG_DOUBLE -#cmakedefine COMPILER_SUPPORTS_FLOAT128 +#cmakedefine COMPILER_SUPPORTS_OPENMP +#cmakedefine COMPILER_SUPPORTS_SYS_GETRANDOM +#cmakedefine COMPILER_SUPPORTS_WEAK_ALIASES +#cmakedefine COMPILER_SUPPORTS_ADVSIMD +#cmakedefine COMPILER_SUPPORTS_ADVSIMDNOFMA +#cmakedefine COMPILER_SUPPORTS_AVX +#cmakedefine COMPILER_SUPPORTS_AVX2 +#cmakedefine COMPILER_SUPPORTS_AVX2128 +#cmakedefine COMPILER_SUPPORTS_AVX512F +#cmakedefine COMPILER_SUPPORTS_AVX512FNOFMA +#cmakedefine COMPILER_SUPPORTS_FLOAT128 +#cmakedefine COMPILER_SUPPORTS_FMA4 +#cmakedefine COMPILER_SUPPORTS_NEON32 +#cmakedefine COMPILER_SUPPORTS_NEON32VFPV4 +#cmakedefine COMPILER_SUPPORTS_PURECFMA_SCALAR +#cmakedefine COMPILER_SUPPORTS_PUREC_SCALAR #cmakedefine COMPILER_SUPPORTS_SSE2 +#cmakedefine COMPILER_SUPPORTS_SSE4 +#cmakedefine COMPILER_SUPPORTS_SVE +#cmakedefine COMPILER_SUPPORTS_SVENOFMA +#cmakedefine COMPILER_SUPPORTS_VSX +#cmakedefine COMPILER_SUPPORTS_VSXNOFMA #endif // CONFIG_H diff --git a/src/libm/CMakeLists.txt b/src/libm/CMakeLists.txt index 490af62e..8a9df24c 100644 --- a/src/libm/CMakeLists.txt +++ b/src/libm/CMakeLists.txt @@ -21,6 +21,8 @@ foreach(SIMD ${SLEEF_HEADER_LIST}) list(APPEND SLEEF_HEADER_COMMANDS COMMAND echo Generating sleef.h: ${TARGET_MKRENAME} ${HEADER_PARAMS_${SIMD}}) list(APPEND SLEEF_HEADER_COMMANDS COMMAND $ ${HEADER_PARAMS_${SIMD}} >> ${SLEEF_INCLUDE_HEADER}) endforeach() +list(APPEND SLEEF_HEADER_COMMANDS COMMAND echo Generating sleef.h: ${TARGET_MKSTATIC}) +list(APPEND SLEEF_HEADER_COMMANDS COMMAND $ >> ${SLEEF_INCLUDE_HEADER}) if((MSVC OR MINGW AND WIN32) OR SLEEF_CLANG_ON_WINDOWS) string(REPLACE "/" "\\" sleef_footer_input_file "${SLEEF_ORG_FOOTER}") @@ -35,6 +37,7 @@ add_custom_command(OUTPUT ${SLEEF_INCLUDE_HEADER} ${SLEEF_ORG_HEADER} ${SLEEF_ORG_FOOTER} ${TARGET_MKRENAME} + ${TARGET_MKSTATIC} ) # -------------------------------------------------------------------- @@ -155,6 +158,13 @@ set_target_properties( PROPERTIES C_STANDARD 99 ) +# -------------------------------------------------------------------- +# TARGET_MKDISP +# -------------------------------------------------------------------- +# Helper executable: dispatcher for the vector extensions +add_host_executable(${TARGET_MKSTATIC} mkstatic.c) +target_include_directories(${TARGET_MKSTATIC} PRIVATE ${PROJECT_BINARY_DIR}/include) + # -------------------------------------------------------------------- # TARGET_LIBSLEEF # -------------------------------------------------------------------- diff --git a/src/libm/mkstatic.c b/src/libm/mkstatic.c new file mode 100644 index 00000000..28efcaab --- /dev/null +++ b/src/libm/mkstatic.c @@ -0,0 +1,150 @@ +// Copyright Naoki Shibata and contributors 2010 - 2020. +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include +#include +#include +#include +#include + +#include "funcproto.h" +#include + +static const size_t vecSizes[] = { + 0, 16, 32, 64, +}; + +static const struct variantInfo { + size_t vecSize; + const char* ppTest; + const char* suffix; +} variantList[] = { + + /* Arm */ + + #if defined(COMPILER_SUPPORTS_SVE) + { 0, "defined(__ARM_SVE)", "sve" }, + #endif + #if defined(COMPILER_SUPPORTS_SVENOFMA) + { 0, "defined(__ARM_SVE)", "svenofma" }, + #endif + + #if defined(COMPILER_SUPPORTS_ADVSIMD) + /* Not sure what the feature check for FMA should look like */ + { 16, "defined(__ARM_NEON) && defined(__aarch64__)", "advsimd" }, + #endif + #if defined(COMPILER_SUPPORTS_ADVSIMDNOFMA) + { 16, "defined(__ARM_NEON) && defined(__aarch64__)", "advsimdnofma" }, + #endif + + #if defined(COMPILER_SUPPORTS_NEON32VFPV4) + { 16, "defined(__ARM_NEON) && (__ARM_NEON_FP >= 4)", "neonvfpv4" }, + #endif + #if defined(COMPILER_SUPPORTS_NEON32VFPV4) + { 16, "defined(__ARM_NEON)", "neon" }, + #endif + + /* POWER */ + + #if defined(COMPILER_SUPPORTS_VSX) + /* Not sure what the feature check for FMA should look like */ + { 16, "defined(__VSX__) && defined(__ARCH_PWR8) && defined(__LITTLE_ENDIAN__)", "vsx" }, + #endif + #if defined(COMPILER_SUPPORTS_VSXNOFMA) + { 16, "defined(__VSX__) && defined(__ARCH_PWR8) && defined(__LITTLE_ENDIAN__)", "vsxnofma" }, + #endif + + /* x86 */ + + #if defined(COMPILER_SUPPORTS_AVX512F) + { 64, "defined(__AVX512F__) && defined(__FMA4__)", "avx512f" }, + #endif + #if defined(COMPILER_SUPPORTS_AVX512FNOFMA) + { 64, "defined(__AVX512F__)", "avx512fnofma" }, + #endif + + #if defined(COMPILER_SUPPORTS_FMA4) + { 32, "defined(__FMA4__)", "fma4" }, + #endif + #if defined(COMPILER_SUPPORTS_AVX2) + { 32, "defined(__AVX2__)", "avx2" }, + #endif + #if defined(COMPILER_SUPPORTS_AVX) + { 32, "defined(__AVX__)", "avx" }, + #endif + + #if defined(COMPILER_SUPPORTS_AVX2128) + { 16, "defined(__AVX2__)", "avx2128" }, + #endif + #if defined(COMPILER_SUPPORTS_SSE4) + { 16, "defined(__SSE4_1__)", "sse4" }, + #endif + #if defined(COMPILER_SUPPORTS_SSE2) + { 16, "defined(__SSE2__)", "sse2" }, + #endif + + { 0, NULL, NULL } +}; + +void +write_static_dispatch(FILE* fp, size_t vecSize) { + int first = 1; + for (const struct variantInfo* vi = variantList ; vi->suffix != NULL ; vi++) { + if (vi->vecSize != vecSize) + continue; + + if (first) { + first = 0; + fprintf(fp, "#if %s\n", vi->ppTest); + } else { + fprintf(fp, "#elif %s\n", vi->ppTest); + } + + for (funcSpec* func = funcList ; func->name != NULL ; func++) { + if (func->funcType >= 7) { + continue; + } + + if (vecSize != 0) { + if (func->ulp > 0) { + fprintf(fp, "# define Sleef_%sf%zu_u%02dstatic Sleef_%sf%zu_u%02d%s\n", + func->name, vecSize / sizeof(float), func->ulp, + func->name, vecSize / sizeof(float), func->ulp, vi->suffix); + } else { + fprintf(fp, "# define Sleef_%sf%zu_static Sleef_%sf%zu_%s\n", + func->name, vecSize / sizeof(float), + func->name, vecSize / sizeof(float), vi->suffix); + } + } else { + if (func->ulp > 0) { + fprintf(fp, "# define Sleef_%sfx_u%02dstatic Sleef_%sfx_u%02d%s\n", + func->name, func->ulp, + func->name, func->ulp, vi->suffix); + } else { + fprintf(fp, "# define Sleef_%sfx_static Sleef_%sfx_%s\n", + func->name, + func->name, vi->suffix); + } + } + } + } + + if (!first) { + fputs("#endif\n\n", fp); + } +} + +int +main(void) { + fprintf(stdout, "\n/* Begin static dispatch macros */\n\n"); + + for (size_t i = 0 ; i < (sizeof(vecSizes) / sizeof(vecSizes[0])) ; i++) { + write_static_dispatch(stdout, vecSizes[i]); + } + + fprintf(stdout, "/* End static distpatch macros */\n\n"); + + return 0; +}