diff --git a/libc/src/__support/common.h b/libc/src/__support/common.h index da157a864645..b3bbb08d4ed2 100644 --- a/libc/src/__support/common.h +++ b/libc/src/__support/common.h @@ -37,7 +37,9 @@ // clang-format on #define LLVM_LIBC_EMPTY +#define GET_NOTHING(...) 0 #define GET_SECOND(first, second, ...) second +#define GET_FIFTH(first, second, third, fourth, fifth, ...) fifth #define EXPAND_THEN_SECOND(name) GET_SECOND(name, LLVM_LIBC_EMPTY) #define LLVM_LIBC_ATTR(name) EXPAND_THEN_SECOND(LLVM_LIBC_FUNCTION_ATTR_##name) @@ -48,25 +50,33 @@ // symbol. Moreover, a C symbol `func` in macOS is mangled as `_func`. #if defined(LIBC_COPT_PUBLIC_PACKAGING) && !defined(LIBC_COMPILER_IS_MSVC) #ifndef __APPLE__ -#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \ +#define LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, c_alias) \ LLVM_LIBC_ATTR(name) \ LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \ - __##name##_impl__ asm(#name); \ - decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \ + __##name##_impl__ asm(c_alias); \ + decltype(LIBC_NAMESPACE::name) name [[gnu::alias(c_alias)]]; \ type __##name##_impl__ arglist #else // __APPLE__ -#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) \ +#define LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, c_alias) \ LLVM_LIBC_ATTR(name) \ - LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) name asm("_" #name); \ + LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) name asm( \ + "_" c_alias); \ type name arglist #endif // __APPLE__ + #else // LIBC_COPT_PUBLIC_PACKAGING -#define LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) type name arglist +#define LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, c_alias) \ + type name arglist #endif // LIBC_COPT_PUBLIC_PACKAGING -// This extra layer of macro allows `name` to be a macro to rename a function. -#define LLVM_LIBC_FUNCTION(type, name, arglist) \ - LLVM_LIBC_FUNCTION_IMPL(type, name, arglist) +#define LLVM_LIBC_FUNCTION_IMPL_3(type, name, arglist) \ + LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, #name) + +// LLVM_LIBC_FUNCTION(type, name, arglist) is equivalent to +// LLVM_LIBC_FUNCTION(type, name, arglist, #name) +#define LLVM_LIBC_FUNCTION(...) \ + GET_FIFTH(__VA_ARGS__, LLVM_LIBC_FUNCTION_IMPL_4, LLVM_LIBC_FUNCTION_IMPL_3, \ + GET_NOTHING)(__VA_ARGS__) // At the moment, [[gnu::alias()]] is not supported on MacOS, and it is needed // to cleanly export and alias the C++ symbol `LIBC_NAMESPACE::func` with the C diff --git a/libc/src/mathvec/generic/CMakeLists.txt b/libc/src/mathvec/generic/CMakeLists.txt index c2abbfbe265c..d5d94d5ed56b 100644 --- a/libc/src/mathvec/generic/CMakeLists.txt +++ b/libc/src/mathvec/generic/CMakeLists.txt @@ -5,6 +5,7 @@ add_entrypoint_object( HDRS ../expf.h DEPENDS + libc.src.__support.macros.properties.cpu_features libc.src.__support.mathvec.expf FLAGS ROUND_OPT diff --git a/libc/src/mathvec/generic/expf.cpp b/libc/src/mathvec/generic/expf.cpp index d86c21d40644..e269fa82e08f 100644 --- a/libc/src/mathvec/generic/expf.cpp +++ b/libc/src/mathvec/generic/expf.cpp @@ -7,10 +7,33 @@ //===----------------------------------------------------------------------===// #include "src/mathvec/expf.h" +#include "src/__support/common.h" +#include "src/__support/macros/properties/cpu_features.h" #include "src/__support/mathvec/expf.h" +#ifndef LIBC_MATHVEC_EXPF_SYM +#if defined(LIBC_TARGET_CPU_HAS_AVX512F) +#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVeN16v_" +#elif defined(LIBC_TARGET_CPU_HAS_AVX2) +#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVdN8v_" +#elif defined(LIBC_TARGET_CPU_HAS_AVX) +#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVcN8v_" +#elif defined(LIBC_TARGET_CPU_HAS_SSE2) +#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVbN4v_" +#elif defined(LIBC_TARGET_CPU_HAS_ARM_NEON) +#define LIBC_MATHVEC_EXPF_SYM_PREFIX "_ZGVnN4v_" +#else +#define LIBC_MATHVEC_EXPF_SYM_PREFIX "__" +#endif // LIBC_TARGET_CPU_HAS_* + +#define LIBC_MATHVEC_EXPF_SYM LIBC_MATHVEC_EXPF_SYM_PREFIX "expf" +#endif // LIBC_MATHVEC_EXPF_SYM + namespace LIBC_NAMESPACE_DECL { -cpp::simd expf(cpp::simd x) { return mathvec::expf(x); } +LLVM_LIBC_FUNCTION(cpp::simd, expf, (cpp::simd x), + LIBC_MATHVEC_EXPF_SYM) { + return mathvec::expf(x); +} } // namespace LIBC_NAMESPACE_DECL