• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===------ Pretty print function for FPBits --------------------*- 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_SRC___SUPPORT_FPUTIL_FPBITS_STR_H
10 #define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H
11 
12 #include "src/__support/CPP/string.h"
13 #include "src/__support/CPP/type_traits.h"
14 #include "src/__support/FPUtil/FPBits.h"
15 #include "src/__support/integer_to_string.h"
16 #include "src/__support/macros/attributes.h"
17 
18 namespace LIBC_NAMESPACE {
19 
20 namespace details {
21 
22 // Format T as uppercase hexadecimal number with leading zeros.
23 template <typename T>
24 using ZeroPaddedHexFmt = IntegerToString<
25     T, typename radix::Hex::WithWidth<(sizeof(T) * 2)>::WithPrefix::Uppercase>;
26 
27 } // namespace details
28 
29 // Converts the bits to a string in the following format:
30 //    "0x<NNN...N> = S: N, E: 0xNNNN, M:0xNNN...N"
31 // 1. N is a hexadecimal digit.
32 // 2. The hexadecimal number on the LHS is the raw numerical representation
33 //    of the bits.
34 // 3. The exponent is always 16 bits wide irrespective of the type of the
35 //    floating encoding.
str(fputil::FPBits<T> x)36 template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
37   using StorageType = typename fputil::FPBits<T>::StorageType;
38 
39   if (x.is_nan())
40     return "(NaN)";
41   if (x.is_inf())
42     return x.is_neg() ? "(-Infinity)" : "(+Infinity)";
43 
44   const auto sign_char = [](Sign sign) -> char {
45     return sign.is_neg() ? '1' : '0';
46   };
47 
48   cpp::string s;
49 
50   const details::ZeroPaddedHexFmt<StorageType> bits(x.uintval());
51   s += bits.view();
52 
53   s += " = (S: ";
54   s += sign_char(x.sign());
55 
56   s += ", E: ";
57   const details::ZeroPaddedHexFmt<uint16_t> exponent(x.get_biased_exponent());
58   s += exponent.view();
59 
60   if constexpr (fputil::get_fp_type<T>() == fputil::FPType::X86_Binary80) {
61     s += ", I: ";
62     s += sign_char(x.get_implicit_bit() ? Sign::NEG : Sign::POS);
63   }
64 
65   s += ", M: ";
66   const details::ZeroPaddedHexFmt<StorageType> mantissa(x.get_mantissa());
67   s += mantissa.view();
68 
69   s += ')';
70   return s;
71 }
72 
73 } // namespace LIBC_NAMESPACE
74 
75 #endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_FPBITS_STR_H
76