diff --git a/flang/runtime/Float128Math/CMakeLists.txt b/flang/runtime/Float128Math/CMakeLists.txt index 2e20f4fd612f2..8d276e8f12272 100644 --- a/flang/runtime/Float128Math/CMakeLists.txt +++ b/flang/runtime/Float128Math/CMakeLists.txt @@ -14,8 +14,9 @@ # will have a dependency on the third-party library that is being # used for building this FortranFloat128Math library. -if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath" OR - ${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "quadmath") +include(CheckLibraryExists) + +if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath") check_include_file(quadmath.h FOUND_QUADMATH_HEADER) if(FOUND_QUADMATH_HEADER) add_compile_definitions(HAS_QUADMATHLIB) @@ -25,7 +26,18 @@ if (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libquadmath" OR "to be available: ${FLANG_RUNTIME_F128_MATH_LIB}" ) endif() -else() +elseif (${FLANG_RUNTIME_F128_MATH_LIB} STREQUAL "libm") + check_library_exists(m sinl "" FOUND_LIBM) + check_library_exists(m sinf128 "" FOUND_LIBMF128) + if (FOUND_LIBM) + add_compile_definitions(HAS_LIBM) + endif() + if (FOUND_LIBMF128) + add_compile_definitions(HAS_LIBMF128) + endif() +endif() + +if (NOT FOUND_QUADMATH_HEADER AND NOT FOUND_LIBM) message(FATAL_ERROR "Unsupported third-party library for Fortran F128 math runtime: " "${FLANG_RUNTIME_F128_MATH_LIB}" diff --git a/flang/runtime/Float128Math/math-entries.h b/flang/runtime/Float128Math/math-entries.h index d7896ac827913..fe1525468edca 100644 --- a/flang/runtime/Float128Math/math-entries.h +++ b/flang/runtime/Float128Math/math-entries.h @@ -12,6 +12,7 @@ #include "tools.h" #include "flang/Common/float128.h" #include "flang/Runtime/entry-names.h" +#include #include namespace Fortran::runtime { @@ -42,7 +43,8 @@ namespace Fortran::runtime { #define DEFINE_SIMPLE_ALIAS(caller, callee) \ template struct caller

{ \ static RT invoke(ATs... args) { \ - static_assert(std::is_invocable_r_v); \ + static_assert(std::is_invocable_r_v()...))(ATs...), ATs...>); \ if constexpr (std::is_same_v) { \ callee(args...); \ } else { \ @@ -98,7 +100,69 @@ typedef _Complex float __attribute__((mode(TC))) ComplexF128; typedef _Complex float __attribute__((mode(KC))) ComplexF128; #endif -#if HAS_QUADMATHLIB +#if HAS_LIBM +// Define wrapper callers for libm. +#include +#include + +#if LDBL_MANT_DIG == 113 +// Use STD math functions. They provide IEEE-754 128-bit float +// support either via 'long double' or __float128. +// The Bessel's functions are not present in STD namespace. +DEFINE_SIMPLE_ALIAS(Acos, std::acos) +DEFINE_SIMPLE_ALIAS(Acosh, std::acosh) +DEFINE_SIMPLE_ALIAS(Asin, std::asin) +DEFINE_SIMPLE_ALIAS(Asinh, std::asinh) +DEFINE_SIMPLE_ALIAS(Atan, std::atan) +DEFINE_SIMPLE_ALIAS(Atan2, std::atan2) +DEFINE_SIMPLE_ALIAS(Atanh, std::atanh) +// TODO: enable complex abs, when ABI adjustment for complex +// data type is resolved. +// DEFINE_SIMPLE_ALIAS(CAbs, std::abs) +DEFINE_SIMPLE_ALIAS(Ceil, std::ceil) +DEFINE_SIMPLE_ALIAS(Cos, std::cos) +DEFINE_SIMPLE_ALIAS(Cosh, std::cosh) +DEFINE_SIMPLE_ALIAS(Erf, std::erf) +DEFINE_SIMPLE_ALIAS(Erfc, std::erfc) +DEFINE_SIMPLE_ALIAS(Exp, std::exp) +DEFINE_SIMPLE_ALIAS(Floor, std::floor) +DEFINE_SIMPLE_ALIAS(Hypot, std::hypot) +DEFINE_SIMPLE_ALIAS(J0, j0l) +DEFINE_SIMPLE_ALIAS(J1, j1l) +DEFINE_SIMPLE_ALIAS(Jn, jnl) +DEFINE_SIMPLE_ALIAS(Lgamma, std::lgamma) +DEFINE_SIMPLE_ALIAS(Llround, std::llround) +DEFINE_SIMPLE_ALIAS(Lround, std::lround) +DEFINE_SIMPLE_ALIAS(Log, std::log) +DEFINE_SIMPLE_ALIAS(Log10, std::log10) +DEFINE_SIMPLE_ALIAS(Pow, std::pow) +DEFINE_SIMPLE_ALIAS(Round, std::round) +DEFINE_SIMPLE_ALIAS(Sin, std::sin) +DEFINE_SIMPLE_ALIAS(Sinh, std::sinh) +DEFINE_SIMPLE_ALIAS(Sqrt, std::sqrt) +DEFINE_SIMPLE_ALIAS(Tan, std::tan) +DEFINE_SIMPLE_ALIAS(Tanh, std::tanh) +DEFINE_SIMPLE_ALIAS(Tgamma, std::tgamma) +DEFINE_SIMPLE_ALIAS(Trunc, std::trunc) +DEFINE_SIMPLE_ALIAS(Y0, y0l) +DEFINE_SIMPLE_ALIAS(Y1, y1l) +DEFINE_SIMPLE_ALIAS(Yn, ynl) +#else // LDBL_MANT_DIG != 113 +#if !HAS_LIBMF128 +// glibc >=2.26 seems to have complete support for __float128 +// versions of the math functions. +#error "FLANG_RUNTIME_F128_MATH_LIB=libm build requires libm >=2.26" +#endif + +// We can use __float128 versions of libm functions. +// __STDC_WANT_IEC_60559_TYPES_EXT__ needs to be defined +// before including cmath to enable the *f128 prototypes. +// TODO: this needs to be enabled separately, especially +// for complex data types that require C++ complex to C complex +// adjustment to match the ABIs. +#error "Unsupported FLANG_RUNTIME_F128_MATH_LIB=libm build" +#endif // LDBL_MANT_DIG != 113 +#elif HAS_QUADMATHLIB // Define wrapper callers for libquadmath. #include "quadmath.h" DEFINE_SIMPLE_ALIAS(Acos, acosq)