1 //===-- Properties of 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_PROPERTIES_H
10 #define LLVM_LIBC_UTILS_FPUTIL_FLOAT_PROPERTIES_H
11 
12 #include <stdint.h>
13 
14 namespace __llvm_libc {
15 namespace fputil {
16 
17 template <typename T> struct FloatProperties {};
18 
19 template <> struct FloatProperties<float> {
20   typedef uint32_t BitsType;
21   static_assert(sizeof(BitsType) == sizeof(float),
22                 "Unexpected size of 'float' type.");
23 
24   static constexpr uint32_t bitWidth = sizeof(BitsType) << 3;
25 
26   static constexpr uint32_t mantissaWidth = 23;
27   static constexpr BitsType mantissaMask = 0x007fffffU;
28   static constexpr BitsType signMask = 0x80000000U;
29   static constexpr BitsType exponentMask = ~(signMask | mantissaMask);
30   static constexpr uint32_t exponentOffset = 127;
31 
32   // If a number x is a NAN, then it is a quiet NAN if:
33   //   QuietNaNMask & bits(x) != 0
34   // Else, it is a signalling NAN.
35   static constexpr BitsType quietNaNMask = 0x00400000U;
36 };
37 
38 template <> struct FloatProperties<double> {
39   typedef uint64_t BitsType;
40   static_assert(sizeof(BitsType) == sizeof(double),
41                 "Unexpected size of 'double' type.");
42 
43   static constexpr uint32_t bitWidth = sizeof(BitsType) << 3;
44 
45   static constexpr uint32_t mantissaWidth = 52;
46   static constexpr BitsType mantissaMask = 0x000fffffffffffffU;
47   static constexpr BitsType signMask = 0x8000000000000000ULL;
48   static constexpr BitsType exponentMask = ~(signMask | mantissaMask);
49   static constexpr uint32_t exponentOffset = 1023;
50 
51   // If a number x is a NAN, then it is a quiet NAN if:
52   //   QuietNaNMask & bits(x) != 0
53   // Else, it is a signalling NAN.
54   static constexpr BitsType quietNaNMask = 0x0008000000000000ULL;
55 };
56 
57 // Define the float type corresponding to the BitsType.
58 template <typename BitsType> struct FloatType;
59 
60 template <> struct FloatType<uint32_t> {
61   static_assert(sizeof(uint32_t) == sizeof(float),
62                 "Unexpected size of 'float' type.");
63   typedef float Type;
64 };
65 
66 template <> struct FloatType<uint64_t> {
67   static_assert(sizeof(uint64_t) == sizeof(double),
68                 "Unexpected size of 'double' type.");
69   typedef double Type;
70 };
71 
72 template <typename BitsType>
73 using FloatTypeT = typename FloatType<BitsType>::Type;
74 
75 } // namespace fputil
76 } // namespace __llvm_libc
77 
78 #endif // LLVM_LIBC_UTILS_FPUTIL_FLOAT_PROPERTIES_H
79