1 //===-- Common operations on floating point numbers -------------*- 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 #ifndef LLVM_LIBC_UTILS_FPUTIL_FLOAT_OPERATIONS_H
10 #define LLVM_LIBC_UTILS_FPUTIL_FLOAT_OPERATIONS_H
11 
12 #include "BitPatterns.h"
13 #include "FloatProperties.h"
14 
15 #include "utils/CPP/TypeTraits.h"
16 
17 namespace __llvm_libc {
18 namespace fputil {
19 
20 // Return the bits of a float value.
21 template <typename T,
22           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
valueAsBits(T x)23 static inline typename FloatProperties<T>::BitsType valueAsBits(T x) {
24   using BitsType = typename FloatProperties<T>::BitsType;
25   return *reinterpret_cast<BitsType *>(&x);
26 }
27 
28 // Return the float value from bits.
29 template <typename BitsType,
30           cpp::EnableIfType<
31               cpp::IsFloatingPointType<FloatTypeT<BitsType>>::Value, int> = 0>
valueFromBits(BitsType bits)32 static inline FloatTypeT<BitsType> valueFromBits(BitsType bits) {
33   return *reinterpret_cast<FloatTypeT<BitsType> *>(&bits);
34 }
35 
36 // Return the bits of abs(x).
37 template <typename T,
38           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
absBits(T x)39 static inline typename FloatProperties<T>::BitsType absBits(T x) {
40   return valueAsBits(x) & (~FloatProperties<T>::signMask);
41 }
42 
43 template <typename BitsType>
getExponentFromBits(BitsType bits)44 static inline int getExponentFromBits(BitsType bits) {
45   using FPType = typename FloatType<BitsType>::Type;
46   using Properties = FloatProperties<FPType>;
47   bits &= Properties::exponentMask;
48   int e = (bits >> Properties::mantissaWidth); // Shift out the mantissa.
49   e -= Properties::exponentOffset;             // Zero adjust.
50   return e;
51 }
52 
53 // Return the zero adjusted exponent value of x.
54 template <typename T,
55           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
getExponent(T x)56 static inline int getExponent(T x) {
57   return getExponentFromBits(valueAsBits(x));
58 }
59 
60 } // namespace fputil
61 } // namespace __llvm_libc
62 
63 #endif // LLVM_LIBC_UTILS_FPUTIL_FLOAT_OPERATIONS_H
64