Warning: This file is not a C or C++ file. It does not have highlighting.
1 | /*===-- flang/Common/float128.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 | *===----------------------------------------------------------------------===*/ |
8 | |
9 | /* This header is usable in both C and C++ code. |
10 | * Isolates build compiler checks to determine the presence of an IEEE-754 |
11 | * quad-precision type named __float128 type that isn't __ibm128 |
12 | * (double/double). We don't care whether the type has underlying hardware |
13 | * support or is emulated. |
14 | * |
15 | * 128-bit arithmetic may be available via "long double"; this can |
16 | * be determined by LDBL_MANT_DIG == 113. A machine may have both 128-bit |
17 | * long double and __float128; prefer long double by testing for it first. |
18 | */ |
19 | |
20 | #ifndef FORTRAN_COMMON_FLOAT128_H_ |
21 | #define FORTRAN_COMMON_FLOAT128_H_ |
22 | |
23 | #include <float.h> |
24 | |
25 | #ifdef __cplusplus |
26 | /* |
27 | * libc++ does not fully support __float128 right now, e.g. |
28 | * std::complex<__float128> multiplication ends up calling |
29 | * copysign() that is not defined for __float128. |
30 | * In order to check for libc++'s _LIBCPP_VERSION macro |
31 | * we need to include at least one libc++ header file. |
32 | */ |
33 | #include <cstddef> |
34 | #endif |
35 | |
36 | #undef HAS_FLOAT128 |
37 | #if (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)) && \ |
38 | !defined(_LIBCPP_VERSION) && !defined(__CUDA_ARCH__) |
39 | /* |
40 | * It may still be worth checking for compiler versions, |
41 | * since earlier versions may define the macros above, but |
42 | * still do not support __float128 fully. |
43 | */ |
44 | #if __x86_64__ |
45 | #if __GNUC__ >= 7 || __clang_major__ >= 7 |
46 | #define HAS_FLOAT128 1 |
47 | #endif |
48 | #elif defined __PPC__ && __GNUC__ >= 8 |
49 | #define HAS_FLOAT128 1 |
50 | #endif |
51 | #endif /* (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)) && \ |
52 | !defined(_LIBCPP_VERSION) && !defined(__CUDA_ARCH__) */ |
53 | |
54 | /* Define pure C CFloat128Type and CFloat128ComplexType. */ |
55 | #if LDBL_MANT_DIG == 113 |
56 | typedef long double CFloat128Type; |
57 | #ifndef __cplusplus |
58 | typedef long double _Complex CFloat128ComplexType; |
59 | #endif |
60 | #elif HAS_FLOAT128 |
61 | typedef __float128 CFloat128Type; |
62 | |
63 | #ifndef __cplusplus |
64 | /* |
65 | * Use mode() attribute supported by GCC and Clang. |
66 | * Adjust it for other compilers as needed. |
67 | */ |
68 | #if !defined(_ARCH_PPC) || defined(__LONG_DOUBLE_IEEE128__) |
69 | typedef _Complex float __attribute__((mode(TC))) CFloat128ComplexType; |
70 | #else |
71 | typedef _Complex float __attribute__((mode(KC))) CFloat128ComplexType; |
72 | #endif |
73 | #endif // __cplusplus |
74 | #endif |
75 | #endif /* FORTRAN_COMMON_FLOAT128_H_ */ |
76 |
Warning: This file is not a C or C++ file. It does not have highlighting.