9#ifndef FORTRAN_EVALUATE_HOST_H_
10#define FORTRAN_EVALUATE_HOST_H_
21#include "quadmath_wrapper.h"
22#include "flang/Common/float128.h"
24#include "flang/Evaluate/type.h"
39 bool hasSubnormalFlushingHardwareControl()
const {
40 return hasSubnormalFlushingHardwareControl_;
42 void SetFlag(RealFlag flag) { flags_.set(flag); }
43 bool hardwareFlagsAreReliable()
const {
return hardwareFlagsAreReliable_; }
46 std::fenv_t originalFenv_;
48 unsigned int originalMxcsr;
51 bool hasSubnormalFlushingHardwareControl_{
false};
52 bool hardwareFlagsAreReliable_{
true};
61template <
typename FTN_T>
using HostType =
typename HostTypeHelper<FTN_T>::Type;
63template <
typename... T>
constexpr inline bool HostTypeExists() {
72template <
typename FTN_T>
73inline constexpr Scalar<FTN_T> CastHostToFortran(
const HostType<FTN_T> &x) {
74 static_assert(HostTypeExists<FTN_T>());
75 if constexpr (FTN_T::category == TypeCategory::Complex &&
76 Scalar<FTN_T>::bytesStored() !=
sizeof(HostType<FTN_T>)) {
79 return Scalar<FTN_T>{CastHostToFortran<typename FTN_T::Part>(std::real(x)),
80 CastHostToFortran<typename FTN_T::Part>(std::imag(x))};
82 static_assert(Scalar<FTN_T>::bytesStored() ==
sizeof(HostType<FTN_T>));
83 return Scalar<FTN_T>::FromRawBytes(&x,
sizeof(x));
88template <
typename FTN_T>
89inline constexpr HostType<FTN_T> CastFortranToHost(
const Scalar<FTN_T> &x) {
90 static_assert(HostTypeExists<FTN_T>());
91 if constexpr (FTN_T::category == TypeCategory::Complex &&
92 Scalar<FTN_T>::bytesStored() !=
sizeof(HostType<FTN_T>)) {
93 using FortranPartType =
typename FTN_T::Part;
94 return HostType<FTN_T>{CastFortranToHost<FortranPartType>(x.REAL()),
95 CastFortranToHost<FortranPartType>(x.AIMAG())};
97 static_assert(Scalar<FTN_T>::bytesStored() ==
sizeof(HostType<FTN_T>));
98 HostType<FTN_T> result;
99 x.StoreRawBytes(&result,
sizeof(result));
105 using Type = std::int8_t;
109 using Type = std::int16_t;
113 using Type = std::int32_t;
117 using Type = std::int64_t;
121#if (defined(__GNUC__) || defined(__clang__)) && defined(__SIZEOF_INT128__)
122 using Type = __int128_t;
133 Type<TypeCategory::Real, common::RealKindForPrecision(24)>> {
135 using Type = std::conditional_t<
sizeof(float) == 4 &&
136 std::numeric_limits<float>::is_iec559,
142 Type<TypeCategory::Real, common::RealKindForPrecision(53)>> {
144 using Type = std::conditional_t<
sizeof(double) == 8 &&
145 std::numeric_limits<double>::is_iec559,
151 Type<TypeCategory::Real, common::RealKindForPrecision(64)>> {
153 using Type = std::conditional_t<
sizeof(
long double) >= 10 &&
154 std::numeric_limits<long double>::digits == 64 &&
155 std::numeric_limits<long double>::max_exponent == 16384,
162 using Type = __float128;
167 using Type = std::conditional_t<
sizeof(
long double) == 16 &&
168 std::numeric_limits<long double>::digits == 113 &&
169 std::numeric_limits<long double>::max_exponent == 16384,
176 using Type = std::conditional_t<HostTypeExists<RealT>(),
183 using Type = __complex128;
188 using Type = std::conditional_t<KIND <= 8, std::uint8_t, UnsupportedType>;
193 Scalar<typename Fortran::evaluate::Type<TypeCategory::Character, KIND>>;
199template <
typename T,
typename... TT>
201 static constexpr int value{common::TypeIndex<T, TT...>};
205 using HostTypeMapping =
206 common::MapTemplate<HostType, AllIntrinsicTypes, std::tuple>;
207 static constexpr int index{
211 using Type = std::conditional_t<index >= 0,
212 std::tuple_element_t<(index >= 0) ? index : 0, AllIntrinsicTypes>,
216template <
typename HOST_T>
217using FortranType =
typename FortranTypeHelper<HOST_T>::Type;
219template <
typename... HT>
constexpr inline bool FortranTypeExists() {
220 return (... && (!std::is_same_v<FortranType<HT>,
UnknownType>));