1 //===-- TestMatchers.cpp ----------------------------------------*- 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 #include "TestHelpers.h"
10
11 #include "FPBits.h"
12
13 #include "llvm/ADT/StringExtras.h"
14
15 #include <string>
16
17 namespace __llvm_libc {
18 namespace fputil {
19 namespace testing {
20
21 // Return the first N hex digits of an integer as a string in upper case.
22 template <typename T>
23 cpp::EnableIfType<cpp::IsIntegral<T>::Value, std::string>
uintToHex(T X,size_t Length=sizeof (T)* 2)24 uintToHex(T X, size_t Length = sizeof(T) * 2) {
25 std::string s(Length, '0');
26
27 for (auto it = s.rbegin(), end = s.rend(); it != end; ++it, X >>= 4) {
28 unsigned char Mod = static_cast<unsigned char>(X) & 15;
29 *it = llvm::hexdigit(Mod, true);
30 }
31
32 return s;
33 }
34
35 template <typename ValType>
36 cpp::EnableIfType<cpp::IsFloatingPointType<ValType>::Value, void>
describeValue(const char * label,ValType value,testutils::StreamWrapper & stream)37 describeValue(const char *label, ValType value,
38 testutils::StreamWrapper &stream) {
39 stream << label;
40
41 FPBits<ValType> bits(value);
42 if (bits.isNaN()) {
43 stream << "(NaN)";
44 } else if (bits.isInf()) {
45 if (bits.sign)
46 stream << "(-Infinity)";
47 else
48 stream << "(+Infinity)";
49 } else {
50 constexpr int exponentWidthInHex =
51 (fputil::ExponentWidth<ValType>::value - 1) / 4 + 1;
52 constexpr int mantissaWidthInHex =
53 (fputil::MantissaWidth<ValType>::value - 1) / 4 + 1;
54
55 stream << "Sign: " << (bits.sign ? '1' : '0') << ", "
56 << "Exponent: 0x"
57 << uintToHex<uint16_t>(bits.exponent, exponentWidthInHex) << ", "
58 << "Mantissa: 0x"
59 << uintToHex<typename fputil::FPBits<ValType>::UIntType>(
60 bits.mantissa, mantissaWidthInHex);
61 }
62
63 stream << '\n';
64 }
65
66 template void describeValue<float>(const char *, float,
67 testutils::StreamWrapper &);
68 template void describeValue<double>(const char *, double,
69 testutils::StreamWrapper &);
70 template void describeValue<long double>(const char *, long double,
71 testutils::StreamWrapper &);
72
73 } // namespace testing
74 } // namespace fputil
75 } // namespace __llvm_libc
76