[libc++][Android] Allow testing libc++ with clang-r536225 (#116149)
[llvm-project.git] / flang / runtime / Float128Math / math-entries.h
bloba94503fe8e67a09ed8a465435744e863b1fdb3c2
1 //===-- runtime/Float128Math/math-entries.h ---------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef FORTRAN_RUNTIME_FLOAT128MATH_MATH_ENTRIES_H_
10 #define FORTRAN_RUNTIME_FLOAT128MATH_MATH_ENTRIES_H_
11 #include "terminator.h"
12 #include "tools.h"
13 #include "flang/Common/float128.h"
14 #include "flang/Runtime/entry-names.h"
15 #include <cfloat>
16 #include <cmath>
17 #include <type_traits>
19 namespace {
20 using namespace Fortran::runtime;
21 using F128RetType = CppTypeFor<TypeCategory::Real, 16>;
22 using I32RetType = CppTypeFor<TypeCategory::Integer, 4>;
23 using I64RetType = CppTypeFor<TypeCategory::Integer, 8>;
24 } // namespace
26 namespace Fortran::runtime {
28 // Define a class template to gracefully fail, when
29 // there is no specialized template that implements
30 // the required function via using the third-party
31 // implementation.
32 #define DEFINE_FALLBACK(caller, ret_type) \
33 template <bool = false, typename RT = ret_type> struct caller { \
34 template <typename... ATs> [[noreturn]] static RT invoke(ATs... args) { \
35 Terminator terminator{__FILE__, __LINE__}; \
36 terminator.Crash("Float128 variant of '%s' is unsupported", #caller); \
37 } \
40 // Define template specialization that is calling the third-party
41 // implementation.
43 // Defining the specialization for any target library requires
44 // adding the generic template via DEFINE_FALLBACK, so that
45 // a build with another target library that does not define
46 // the same alias can gracefully fail in runtime.
47 #define DEFINE_SIMPLE_ALIAS(caller, callee) \
48 template <typename RT> struct caller<true, RT> { \
49 template <typename... ATs> static RT invoke(ATs... args) { \
50 static_assert(std::is_invocable_r_v<RT, \
51 decltype(callee(std::declval<ATs>()...))(ATs...), ATs...>); \
52 if constexpr (std::is_same_v<RT, void>) { \
53 callee(args...); \
54 } else { \
55 return callee(args...); \
56 } \
57 } \
60 // Define fallback callers.
61 #define DEFINE_FALLBACK_F128(caller) DEFINE_FALLBACK(caller, ::F128RetType)
62 #define DEFINE_FALLBACK_I32(caller) DEFINE_FALLBACK(caller, ::I32RetType)
63 #define DEFINE_FALLBACK_I64(caller) DEFINE_FALLBACK(caller, ::I64RetType)
65 DEFINE_FALLBACK_F128(Abs)
66 DEFINE_FALLBACK_F128(Acos)
67 DEFINE_FALLBACK_F128(Acosh)
68 DEFINE_FALLBACK_F128(Asin)
69 DEFINE_FALLBACK_F128(Asinh)
70 DEFINE_FALLBACK_F128(Atan)
71 DEFINE_FALLBACK_F128(Atan2)
72 DEFINE_FALLBACK_F128(Atanh)
73 DEFINE_FALLBACK_F128(Ceil)
74 DEFINE_FALLBACK_F128(Cos)
75 DEFINE_FALLBACK_F128(Cosh)
76 DEFINE_FALLBACK_F128(Erf)
77 DEFINE_FALLBACK_F128(Erfc)
78 DEFINE_FALLBACK_F128(Exp)
79 DEFINE_FALLBACK_F128(Floor)
80 DEFINE_FALLBACK_F128(Fma)
81 DEFINE_FALLBACK_F128(Frexp)
82 DEFINE_FALLBACK_F128(Hypot)
83 DEFINE_FALLBACK_I32(Ilogb)
84 DEFINE_FALLBACK_I32(Isinf)
85 DEFINE_FALLBACK_I32(Isnan)
86 DEFINE_FALLBACK_F128(J0)
87 DEFINE_FALLBACK_F128(J1)
88 DEFINE_FALLBACK_F128(Jn)
89 DEFINE_FALLBACK_F128(Ldexp)
90 DEFINE_FALLBACK_F128(Lgamma)
91 DEFINE_FALLBACK_I64(Llround)
92 DEFINE_FALLBACK_F128(Log)
93 DEFINE_FALLBACK_F128(Log10)
94 DEFINE_FALLBACK_I32(Lround)
95 DEFINE_FALLBACK_F128(Nearbyint)
96 DEFINE_FALLBACK_F128(Nextafter)
97 DEFINE_FALLBACK_F128(Pow)
98 DEFINE_FALLBACK_F128(Qnan)
99 DEFINE_FALLBACK_F128(Remainder)
100 DEFINE_FALLBACK_F128(Round)
101 DEFINE_FALLBACK_F128(Sin)
102 DEFINE_FALLBACK_F128(Sinh)
103 DEFINE_FALLBACK_F128(Sqrt)
104 DEFINE_FALLBACK_F128(Tan)
105 DEFINE_FALLBACK_F128(Tanh)
106 DEFINE_FALLBACK_F128(Tgamma)
107 DEFINE_FALLBACK_F128(Trunc)
108 DEFINE_FALLBACK_F128(Y0)
109 DEFINE_FALLBACK_F128(Y1)
110 DEFINE_FALLBACK_F128(Yn)
112 #if HAS_QUADMATHLIB
113 // Define wrapper callers for libquadmath.
114 #include "quadmath.h"
115 DEFINE_SIMPLE_ALIAS(Abs, fabsq)
116 DEFINE_SIMPLE_ALIAS(Acos, acosq)
117 DEFINE_SIMPLE_ALIAS(Acosh, acoshq)
118 DEFINE_SIMPLE_ALIAS(Asin, asinq)
119 DEFINE_SIMPLE_ALIAS(Asinh, asinhq)
120 DEFINE_SIMPLE_ALIAS(Atan, atanq)
121 DEFINE_SIMPLE_ALIAS(Atan2, atan2q)
122 DEFINE_SIMPLE_ALIAS(Atanh, atanhq)
123 DEFINE_SIMPLE_ALIAS(Ceil, ceilq)
124 DEFINE_SIMPLE_ALIAS(Cos, cosq)
125 DEFINE_SIMPLE_ALIAS(Cosh, coshq)
126 DEFINE_SIMPLE_ALIAS(Erf, erfq)
127 DEFINE_SIMPLE_ALIAS(Erfc, erfcq)
128 DEFINE_SIMPLE_ALIAS(Exp, expq)
129 DEFINE_SIMPLE_ALIAS(Floor, floorq)
130 DEFINE_SIMPLE_ALIAS(Fma, fmaq)
131 DEFINE_SIMPLE_ALIAS(Frexp, frexpq)
132 DEFINE_SIMPLE_ALIAS(Hypot, hypotq)
133 DEFINE_SIMPLE_ALIAS(Ilogb, ilogbq)
134 DEFINE_SIMPLE_ALIAS(Isinf, isinfq)
135 DEFINE_SIMPLE_ALIAS(Isnan, isnanq)
136 DEFINE_SIMPLE_ALIAS(J0, j0q)
137 DEFINE_SIMPLE_ALIAS(J1, j1q)
138 DEFINE_SIMPLE_ALIAS(Jn, jnq)
139 DEFINE_SIMPLE_ALIAS(Ldexp, ldexpq)
140 DEFINE_SIMPLE_ALIAS(Lgamma, lgammaq)
141 DEFINE_SIMPLE_ALIAS(Llround, llroundq)
142 DEFINE_SIMPLE_ALIAS(Log, logq)
143 DEFINE_SIMPLE_ALIAS(Log10, log10q)
144 DEFINE_SIMPLE_ALIAS(Lround, lroundq)
145 DEFINE_SIMPLE_ALIAS(Nearbyint, nearbyintq)
146 DEFINE_SIMPLE_ALIAS(Nextafter, nextafterq)
147 DEFINE_SIMPLE_ALIAS(Pow, powq)
148 DEFINE_SIMPLE_ALIAS(Remainder, remainderq)
149 DEFINE_SIMPLE_ALIAS(Round, roundq)
150 DEFINE_SIMPLE_ALIAS(Sin, sinq)
151 DEFINE_SIMPLE_ALIAS(Sinh, sinhq)
152 DEFINE_SIMPLE_ALIAS(Sqrt, sqrtq)
153 DEFINE_SIMPLE_ALIAS(Tan, tanq)
154 DEFINE_SIMPLE_ALIAS(Tanh, tanhq)
155 DEFINE_SIMPLE_ALIAS(Tgamma, tgammaq)
156 DEFINE_SIMPLE_ALIAS(Trunc, truncq)
157 DEFINE_SIMPLE_ALIAS(Y0, y0q)
158 DEFINE_SIMPLE_ALIAS(Y1, y1q)
159 DEFINE_SIMPLE_ALIAS(Yn, ynq)
161 // Use cmath INFINITY/NAN definition. Rely on C implicit conversions.
162 #define F128_RT_INFINITY (INFINITY)
163 #define F128_RT_QNAN (NAN)
164 #elif HAS_LDBL128
165 // Define wrapper callers for libm.
166 #include <limits>
168 // Use STD math functions. They provide IEEE-754 128-bit float
169 // support either via 'long double' or __float128.
170 // The Bessel's functions are not present in STD namespace.
171 DEFINE_SIMPLE_ALIAS(Abs, std::abs)
172 DEFINE_SIMPLE_ALIAS(Acos, std::acos)
173 DEFINE_SIMPLE_ALIAS(Acosh, std::acosh)
174 DEFINE_SIMPLE_ALIAS(Asin, std::asin)
175 DEFINE_SIMPLE_ALIAS(Asinh, std::asinh)
176 DEFINE_SIMPLE_ALIAS(Atan, std::atan)
177 DEFINE_SIMPLE_ALIAS(Atan2, std::atan2)
178 DEFINE_SIMPLE_ALIAS(Atanh, std::atanh)
179 DEFINE_SIMPLE_ALIAS(Ceil, std::ceil)
180 DEFINE_SIMPLE_ALIAS(Cos, std::cos)
181 DEFINE_SIMPLE_ALIAS(Cosh, std::cosh)
182 DEFINE_SIMPLE_ALIAS(Erf, std::erf)
183 DEFINE_SIMPLE_ALIAS(Erfc, std::erfc)
184 DEFINE_SIMPLE_ALIAS(Exp, std::exp)
185 DEFINE_SIMPLE_ALIAS(Floor, std::floor)
186 DEFINE_SIMPLE_ALIAS(Fma, std::fma)
187 DEFINE_SIMPLE_ALIAS(Frexp, std::frexp)
188 DEFINE_SIMPLE_ALIAS(Hypot, std::hypot)
189 DEFINE_SIMPLE_ALIAS(Ilogb, std::ilogb)
190 DEFINE_SIMPLE_ALIAS(Isinf, std::isinf)
191 DEFINE_SIMPLE_ALIAS(Isnan, std::isnan)
192 DEFINE_SIMPLE_ALIAS(Ldexp, std::ldexp)
193 DEFINE_SIMPLE_ALIAS(Lgamma, std::lgamma)
194 DEFINE_SIMPLE_ALIAS(Llround, std::llround)
195 DEFINE_SIMPLE_ALIAS(Log, std::log)
196 DEFINE_SIMPLE_ALIAS(Log10, std::log10)
197 DEFINE_SIMPLE_ALIAS(Lround, std::lround)
198 DEFINE_SIMPLE_ALIAS(Nearbyint, std::nearbyint)
199 DEFINE_SIMPLE_ALIAS(Nextafter, std::nextafter)
200 DEFINE_SIMPLE_ALIAS(Pow, std::pow)
201 DEFINE_SIMPLE_ALIAS(Remainder, std::remainder)
202 DEFINE_SIMPLE_ALIAS(Round, std::round)
203 DEFINE_SIMPLE_ALIAS(Sin, std::sin)
204 DEFINE_SIMPLE_ALIAS(Sinh, std::sinh)
205 DEFINE_SIMPLE_ALIAS(Sqrt, std::sqrt)
206 DEFINE_SIMPLE_ALIAS(Tan, std::tan)
207 DEFINE_SIMPLE_ALIAS(Tanh, std::tanh)
208 DEFINE_SIMPLE_ALIAS(Tgamma, std::tgamma)
209 DEFINE_SIMPLE_ALIAS(Trunc, std::trunc)
211 #if defined(__GLIBC__) && defined(_GNU_SOURCE)
212 DEFINE_SIMPLE_ALIAS(J0, j0l)
213 DEFINE_SIMPLE_ALIAS(J1, j1l)
214 DEFINE_SIMPLE_ALIAS(Jn, jnl)
215 DEFINE_SIMPLE_ALIAS(Y0, y0l)
216 DEFINE_SIMPLE_ALIAS(Y1, y1l)
217 DEFINE_SIMPLE_ALIAS(Yn, ynl)
218 #endif
220 // Use numeric_limits to produce infinity of the right type.
221 #define F128_RT_INFINITY \
222 (std::numeric_limits<CppTypeFor<TypeCategory::Real, 16>>::infinity())
223 #define F128_RT_QNAN \
224 (std::numeric_limits<CppTypeFor<TypeCategory::Real, 16>>::quiet_NaN())
225 #elif HAS_LIBMF128
226 // We can use __float128 versions of libm functions.
227 // __STDC_WANT_IEC_60559_TYPES_EXT__ needs to be defined
228 // before including cmath to enable the *f128 prototypes.
229 #error "Float128Math build with glibc>=2.26 is unsupported yet"
230 #endif
232 } // namespace Fortran::runtime
234 #endif // FORTRAN_RUNTIME_FLOAT128MATH_MATH_ENTRIES_H_