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 <string> 14 15 namespace __llvm_libc { 16 namespace fputil { 17 namespace testing { 18 19 // Return the first N hex digits of an integer as a string in upper case. 20 template <typename T> 21 cpp::EnableIfType<cpp::IsIntegral<T>::Value, std::string> 22 uintToHex(T X, size_t Length = sizeof(T) * 2) { 23 std::string s(Length, '0'); 24 25 for (auto it = s.rbegin(), end = s.rend(); it != end; ++it, X >>= 4) { 26 unsigned char Mod = static_cast<unsigned char>(X) & 15; 27 *it = (Mod < 10 ? '0' + Mod : 'a' + Mod - 10); 28 } 29 30 return s; 31 } 32 33 template <typename ValType> 34 cpp::EnableIfType<cpp::IsFloatingPointType<ValType>::Value, void> 35 describeValue(const char *label, ValType value, 36 testutils::StreamWrapper &stream) { 37 stream << label; 38 39 FPBits<ValType> bits(value); 40 if (bits.isNaN()) { 41 stream << "(NaN)"; 42 } else if (bits.isInf()) { 43 if (bits.getSign()) 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 53 stream << "Sign: " << (bits.getSign() ? '1' : '0') << ", " 54 << "Exponent: 0x" 55 << uintToHex<uint16_t>(bits.getUnbiasedExponent(), 56 exponentWidthInHex) 57 << ", " 58 << "Mantissa: 0x" 59 << uintToHex<typename fputil::FPBits<ValType>::UIntType>( 60 bits.getMantissa(), 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