xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/builtins/int_math.h (revision 415efcecd8b80f68e76376ef2b854cb6f5c84b5a)
10b57cec5SDimitry Andric //===-- int_math.h - internal math inlines --------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file is not part of the interface of this library.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // This file defines substitutes for the libm functions used in some of the
120b57cec5SDimitry Andric // compiler-rt implementations, defined in such a way that there is not a direct
130b57cec5SDimitry Andric // dependency on libm or math.h. Instead, we use the compiler builtin versions
140b57cec5SDimitry Andric // where available. This reduces our dependencies on the system SDK by foisting
150b57cec5SDimitry Andric // the responsibility onto the compiler.
160b57cec5SDimitry Andric //
170b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric #ifndef INT_MATH_H
200b57cec5SDimitry Andric #define INT_MATH_H
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #ifndef __has_builtin
230b57cec5SDimitry Andric #define __has_builtin(x) 0
240b57cec5SDimitry Andric #endif
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
270b57cec5SDimitry Andric #include <math.h>
280b57cec5SDimitry Andric #include <stdlib.h>
290b57cec5SDimitry Andric #endif
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
320b57cec5SDimitry Andric #define CRT_INFINITY INFINITY
330b57cec5SDimitry Andric #else
340b57cec5SDimitry Andric #define CRT_INFINITY __builtin_huge_valf()
350b57cec5SDimitry Andric #endif
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
380b57cec5SDimitry Andric #define crt_isfinite(x) _finite((x))
390b57cec5SDimitry Andric #define crt_isinf(x) !_finite((x))
400b57cec5SDimitry Andric #define crt_isnan(x) _isnan((x))
410b57cec5SDimitry Andric #else
420b57cec5SDimitry Andric // Define crt_isfinite in terms of the builtin if available, otherwise provide
430b57cec5SDimitry Andric // an alternate version in terms of our other functions. This supports some
440b57cec5SDimitry Andric // versions of GCC which didn't have __builtin_isfinite.
450b57cec5SDimitry Andric #if __has_builtin(__builtin_isfinite)
460b57cec5SDimitry Andric #define crt_isfinite(x) __builtin_isfinite((x))
470b57cec5SDimitry Andric #elif defined(__GNUC__)
480b57cec5SDimitry Andric #define crt_isfinite(x)                                                        \
490b57cec5SDimitry Andric   __extension__(({                                                             \
500b57cec5SDimitry Andric     __typeof((x)) x_ = (x);                                                    \
510b57cec5SDimitry Andric     !crt_isinf(x_) && !crt_isnan(x_);                                          \
520b57cec5SDimitry Andric   }))
530b57cec5SDimitry Andric #else
540b57cec5SDimitry Andric #error "Do not know how to check for infinity"
550b57cec5SDimitry Andric #endif // __has_builtin(__builtin_isfinite)
560b57cec5SDimitry Andric #define crt_isinf(x) __builtin_isinf((x))
570b57cec5SDimitry Andric #define crt_isnan(x) __builtin_isnan((x))
580b57cec5SDimitry Andric #endif // _MSC_VER
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
610b57cec5SDimitry Andric #define crt_copysign(x, y) copysign((x), (y))
620b57cec5SDimitry Andric #define crt_copysignf(x, y) copysignf((x), (y))
630b57cec5SDimitry Andric #define crt_copysignl(x, y) copysignl((x), (y))
640b57cec5SDimitry Andric #else
650b57cec5SDimitry Andric #define crt_copysign(x, y) __builtin_copysign((x), (y))
660b57cec5SDimitry Andric #define crt_copysignf(x, y) __builtin_copysignf((x), (y))
670b57cec5SDimitry Andric #define crt_copysignl(x, y) __builtin_copysignl((x), (y))
68*415efcecSDimitry Andric // We define __has_builtin to always return 0 for GCC versions below 10,
69*415efcecSDimitry Andric // but __builtin_copysignf128 is available since version 7.
70*415efcecSDimitry Andric #if __has_builtin(__builtin_copysignf128) ||                                   \
71*415efcecSDimitry Andric     (defined(__GNUC__) && __GNUC__ >= 7)
725f757f3fSDimitry Andric #define crt_copysignf128(x, y) __builtin_copysignf128((x), (y))
73*415efcecSDimitry Andric #elif __has_builtin(__builtin_copysignq)
745f757f3fSDimitry Andric #define crt_copysignf128(x, y) __builtin_copysignq((x), (y))
755f757f3fSDimitry Andric #endif
760b57cec5SDimitry Andric #endif
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
790b57cec5SDimitry Andric #define crt_fabs(x) fabs((x))
800b57cec5SDimitry Andric #define crt_fabsf(x) fabsf((x))
810b57cec5SDimitry Andric #define crt_fabsl(x) fabs((x))
820b57cec5SDimitry Andric #else
830b57cec5SDimitry Andric #define crt_fabs(x) __builtin_fabs((x))
840b57cec5SDimitry Andric #define crt_fabsf(x) __builtin_fabsf((x))
850b57cec5SDimitry Andric #define crt_fabsl(x) __builtin_fabsl((x))
86*415efcecSDimitry Andric // We define __has_builtin to always return 0 for GCC versions below 10,
87*415efcecSDimitry Andric // but __builtin_fabsf128 is available since version 7.
88*415efcecSDimitry Andric #if __has_builtin(__builtin_fabsf128) || (defined(__GNUC__) && __GNUC__ >= 7)
895f757f3fSDimitry Andric #define crt_fabsf128(x) __builtin_fabsf128((x))
90*415efcecSDimitry Andric #elif __has_builtin(__builtin_fabsq)
915f757f3fSDimitry Andric #define crt_fabsf128(x) __builtin_fabsq((x))
925f757f3fSDimitry Andric #endif
930b57cec5SDimitry Andric #endif
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
960b57cec5SDimitry Andric #define crt_fmaxl(x, y) __max((x), (y))
970b57cec5SDimitry Andric #else
980b57cec5SDimitry Andric #define crt_fmaxl(x, y) __builtin_fmaxl((x), (y))
990b57cec5SDimitry Andric #endif
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
1020b57cec5SDimitry Andric #define crt_logbl(x) logbl((x))
1030b57cec5SDimitry Andric #else
1040b57cec5SDimitry Andric #define crt_logbl(x) __builtin_logbl((x))
1050b57cec5SDimitry Andric #endif
1060b57cec5SDimitry Andric 
1070b57cec5SDimitry Andric #if defined(_MSC_VER) && !defined(__clang__)
1080b57cec5SDimitry Andric #define crt_scalbnl(x, y) scalbnl((x), (y))
1090b57cec5SDimitry Andric #else
1100b57cec5SDimitry Andric #define crt_scalbnl(x, y) __builtin_scalbnl((x), (y))
1110b57cec5SDimitry Andric #endif
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric #endif // INT_MATH_H
114