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 "api-attrs.h" 24 #include <float.h> 25 26 #ifdef __cplusplus 27 /* 28 * libc++ does not fully support __float128 right now, e.g. 29 * std::complex<__float128> multiplication ends up calling 30 * copysign() that is not defined for __float128. 31 * In order to check for libc++'s _LIBCPP_VERSION macro 32 * we need to include at least one libc++ header file. 33 */ 34 #include <cstddef> 35 #endif 36 37 #undef HAS_FLOAT128 38 #if (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)) && \ 39 !defined(_LIBCPP_VERSION) && !defined(__CUDA_ARCH__) 40 /* 41 * It may still be worth checking for compiler versions, 42 * since earlier versions may define the macros above, but 43 * still do not support __float128 fully. 44 */ 45 #if __x86_64__ 46 #if __GNUC__ >= 7 || __clang_major__ >= 7 47 #define HAS_FLOAT128 1 48 #endif 49 #elif defined __PPC__ && __GNUC__ >= 8 50 #define HAS_FLOAT128 1 51 #endif 52 #endif /* (defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)) && \ 53 !defined(_LIBCPP_VERSION) && !defined(__CUDA_ARCH__) */ 54 55 #if LDBL_MANT_DIG == 113 56 #define HAS_LDBL128 1 57 #endif 58 59 #if defined(RT_DEVICE_COMPILATION) && defined(__CUDACC__) 60 /* 61 * Most offload targets do not support 128-bit 'long double'. 62 * Disable HAS_LDBL128 for __CUDACC__ for the time being. 63 */ 64 #undef HAS_LDBL128 65 #endif 66 67 /* Define pure C CFloat128Type and CFloat128ComplexType. */ 68 #if HAS_LDBL128 69 typedef long double CFloat128Type; 70 #ifndef __cplusplus 71 typedef long double _Complex CFloat128ComplexType; 72 #endif 73 #elif HAS_FLOAT128 74 typedef __float128 CFloat128Type; 75 76 #ifndef __cplusplus 77 /* 78 * Use mode() attribute supported by GCC and Clang. 79 * Adjust it for other compilers as needed. 80 */ 81 #if !defined(_ARCH_PPC) || defined(__LONG_DOUBLE_IEEE128__) 82 typedef _Complex float __attribute__((mode(TC))) CFloat128ComplexType; 83 #else 84 typedef _Complex float __attribute__((mode(KC))) CFloat128ComplexType; 85 #endif 86 #endif // __cplusplus 87 #endif 88 #endif /* FORTRAN_COMMON_FLOAT128_H_ */ 89