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