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