1 //===-- Floating point classification functions -----------------*- 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_CLASSIFICATION_FUNCTIONS_H
10 #define LLVM_LIBC_UTILS_FPUTIL_CLASSIFICATION_FUNCTIONS_H
11 
12 #include "BitPatterns.h"
13 #include "FloatOperations.h"
14 #include "FloatProperties.h"
15 
16 #include "utils/CPP/TypeTraits.h"
17 
18 namespace __llvm_libc {
19 namespace fputil {
20 
bitsAreInf(BitsType bits)21 template <typename BitsType> static inline bool bitsAreInf(BitsType bits) {
22   using FPType = typename FloatType<BitsType>::Type;
23   return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
24          ((bits & FloatProperties<FPType>::mantissaMask) == 0);
25 }
26 
27 // Return true if x is infinity (positive or negative.)
28 template <typename T,
29           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isInf(T x)30 static inline bool isInf(T x) {
31   return bitsAreInf(valueAsBits(x));
32 }
33 
bitsAreNaN(BitsType bits)34 template <typename BitsType> static inline bool bitsAreNaN(BitsType bits) {
35   using FPType = typename FloatType<BitsType>::Type;
36   return ((bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf) &&
37          ((bits & FloatProperties<FPType>::mantissaMask) != 0);
38 }
39 
40 // Return true if x is a NAN (quiet or signalling.)
41 template <typename T,
42           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isNaN(T x)43 static inline bool isNaN(T x) {
44   return bitsAreNaN(valueAsBits(x));
45 }
46 
bitsAreInfOrNaN(BitsType bits)47 template <typename BitsType> static inline bool bitsAreInfOrNaN(BitsType bits) {
48   using FPType = typename FloatType<BitsType>::Type;
49   return (bits & BitPatterns<FPType>::inf) == BitPatterns<FPType>::inf;
50 }
51 
bitsAreZero(BitsType bits)52 template <typename BitsType> static inline bool bitsAreZero(BitsType bits) {
53   using FPType = typename FloatType<BitsType>::Type;
54   return (bits == BitPatterns<FPType>::zero) ||
55          (bits == BitPatterns<FPType>::negZero);
56 }
57 
58 // Return true if x is any kind of NaN or infinity.
59 template <typename T,
60           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isInfOrNaN(T x)61 static inline bool isInfOrNaN(T x) {
62   return bitsAreInfOrNaN(valueAsBits(x));
63 }
64 
65 // Return true if x is a quiet NAN.
66 template <typename T,
67           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isQuietNaN(T x)68 static inline bool isQuietNaN(T x) {
69   using Properties = FloatProperties<T>;
70   using BitsType = typename FloatProperties<T>::BitsType;
71   BitsType bits = valueAsBits(x);
72   return ((bits & BitPatterns<T>::inf) == BitPatterns<T>::inf) &&
73          ((bits & Properties::quietNaNMask) != 0);
74 }
75 
76 // Return true if x is a quiet NAN with sign bit set.
77 template <typename T,
78           cpp::EnableIfType<cpp::IsFloatingPointType<T>::Value, int> = 0>
isNegativeQuietNaN(T x)79 static inline bool isNegativeQuietNaN(T x) {
80   using Properties = FloatProperties<T>;
81   using BitsType = typename FloatProperties<T>::BitsType;
82   BitsType bits = valueAsBits(x);
83   return ((bits & BitPatterns<T>::negInf) == BitPatterns<T>::negInf) &&
84          ((bits & Properties::quietNaNMask) != 0);
85 }
86 
87 } // namespace fputil
88 } // namespace __llvm_libc
89 
90 #endif // LLVM_LIBC_UTILS_FPUTIL_CLASSIFICATION_FUNCTIONS_H
91