1 //===-- Conversion between floating-point types -----------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_CAST_H
10 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_CAST_H
13 #include "dyadic_float.h"
14 #include "hdr/fenv_macros.h"
15 #include "src/__support/CPP/algorithm.h"
16 #include "src/__support/CPP/type_traits.h"
17 #include "src/__support/macros/properties/types.h"
19 namespace LIBC_NAMESPACE::fputil
{
21 template <typename OutType
, typename InType
>
22 LIBC_INLINE
constexpr cpp::enable_if_t
<cpp::is_floating_point_v
<OutType
> &&
23 cpp::is_floating_point_v
<InType
>,
26 #if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
27 if constexpr (cpp::is_same_v
<OutType
, float16
> ||
28 cpp::is_same_v
<InType
, float16
>) {
29 using InFPBits
= FPBits
<InType
>;
30 using InStorageType
= typename
InFPBits::StorageType
;
31 using OutFPBits
= FPBits
<OutType
>;
32 using OutStorageType
= typename
OutFPBits::StorageType
;
36 if (x_bits
.is_nan()) {
37 if (x_bits
.is_signaling_nan()) {
38 raise_except_if_required(FE_INVALID
);
39 return OutFPBits::quiet_nan().get_val();
42 InStorageType x_mant
= x_bits
.get_mantissa();
43 if (InFPBits::FRACTION_LEN
> OutFPBits::FRACTION_LEN
)
44 x_mant
>>= InFPBits::FRACTION_LEN
- OutFPBits::FRACTION_LEN
;
45 return OutFPBits::quiet_nan(x_bits
.sign(),
46 static_cast<OutStorageType
>(x_mant
))
51 return OutFPBits::inf(x_bits
.sign()).get_val();
53 constexpr size_t MAX_FRACTION_LEN
=
54 cpp::max(OutFPBits::FRACTION_LEN
, InFPBits::FRACTION_LEN
);
55 DyadicFloat
<cpp::bit_ceil(MAX_FRACTION_LEN
)> xd(x
);
56 return xd
.template as
<OutType
, /*ShouldSignalExceptions=*/true>();
60 return static_cast<OutType
>(x
);
63 } // namespace LIBC_NAMESPACE::fputil
65 #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_CAST_H