Index: lldb/source/Core/DumpDataExtractor.cpp =================================================================== --- lldb/source/Core/DumpDataExtractor.cpp +++ lldb/source/Core/DumpDataExtractor.cpp @@ -228,6 +228,29 @@ s.Printf("\\x%2.2x", c); } +/// Dump a floating point type. +template +void DumpFloatingPoint(std::ostringstream &ss, FloatT f) { + static_assert(std::is_floating_point::value, + "Only floating point types can be dumped."); + // NaN and Inf are potentially implementation defined and on Darwin it + // seems NaNs are printed without their sign. Manually implement dumping them + // here to avoid having to deal with platform differences. + if (std::isnan(f)) { + if (std::signbit(f)) + ss << '-'; + ss << "nan"; + return; + } + if (std::isinf(f)) { + if (std::signbit(f)) + ss << '-'; + ss << "inf"; + return; + } + ss << f; +} + lldb::offset_t lldb_private::DumpDataExtractor( const DataExtractor &DE, Stream *s, offset_t start_offset, lldb::Format item_format, size_t item_byte_size, size_t item_count, @@ -568,14 +591,14 @@ f = DE.GetFloat(&offset); } ss.precision(std::numeric_limits::digits10); - ss << f; + DumpFloatingPoint(ss, f); } else if (item_byte_size == sizeof(double)) { ss.precision(std::numeric_limits::digits10); - ss << DE.GetDouble(&offset); + DumpFloatingPoint(ss, DE.GetDouble(&offset)); } else if (item_byte_size == sizeof(long double) || item_byte_size == 10) { ss.precision(std::numeric_limits::digits10); - ss << DE.GetLongDouble(&offset); + DumpFloatingPoint(ss, DE.GetLongDouble(&offset)); } else { s->Printf("error: unsupported byte size (%" PRIu64 ") for float format", Index: lldb/unittests/Core/DumpDataExtractorTest.cpp =================================================================== --- lldb/unittests/Core/DumpDataExtractorTest.cpp +++ lldb/unittests/Core/DumpDataExtractorTest.cpp @@ -174,8 +174,30 @@ "{0x0000000000000000 0xaaaabbbbccccdddd}"); // See half2float for format details. + // Test zeroes. + TestDump(std::vector{0x0000, 0x8000}, + lldb::Format::eFormatVectorOfFloat16, "{0 -0}"); + // Some subnormal numbers. + TestDump(std::vector{0x0001, 0x8001}, + lldb::Format::eFormatVectorOfFloat16, "{5.96046e-08 -5.96046e-08}"); + // A full mantisse and empty expontent. + TestDump(std::vector{0x83ff, 0x03ff}, + lldb::Format::eFormatVectorOfFloat16, "{-6.09756e-05 6.09756e-05}"); + // Some normal numbers. + TestDump(std::vector{0b0100001001001000}, + lldb::Format::eFormatVectorOfFloat16, "{3.14062}"); TestDump(std::vector{0xabcd, 0x1234}, lldb::Format::eFormatVectorOfFloat16, "{-0.0609436 0.000757217}"); + // Largest and smallest normal number. + TestDump(std::vector{0x0400, 0x7bff}, + lldb::Format::eFormatVectorOfFloat16, "{6.10352e-05 65504}"); + // quiet/signaling NaNs. + TestDump(std::vector{0xffff, 0xffc0, 0x7fff, 0x7fc0}, + lldb::Format::eFormatVectorOfFloat16, "{-nan -nan nan nan}"); + // +/-Inf. + TestDump(std::vector{0xfc00, 0x7c00}, + lldb::Format::eFormatVectorOfFloat16, "{-inf inf}"); + TestDump(std::vector{std::numeric_limits::min(), std::numeric_limits::max()}, lldb::Format::eFormatVectorOfFloat32, "{1.17549e-38 3.40282e+38}");