From: Jacob Lifshay Date: Thu, 17 Aug 2017 21:46:09 +0000 (-0700) Subject: added ExtendedFloat::fromHalfPrecision X-Git-Tag: gsoc-2017~42 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=d4eb36864f7f7cb6e907d9818648a029955d8e7a;p=kazan.git added ExtendedFloat::fromHalfPrecision --- diff --git a/src/util/soft_float.cpp b/src/util/soft_float.cpp index 7f4d402..0a581f3 100644 --- a/src/util/soft_float.cpp +++ b/src/util/soft_float.cpp @@ -35,7 +35,7 @@ namespace { using namespace vulkan_cpu::util::soft_float; -std::string hexValue(const ExtendedFloat &v) +[[gnu::unused]] std::string hexValue(const ExtendedFloat &v) { if(v.isNaN()) { @@ -387,6 +387,14 @@ void mainFn() { return log10(ExtendedFloat(a)); }; + auto fromHalf_1 = [](std::uint16_t a, long double b) -> ExtendedFloat + { + return ExtendedFloat::fromHalfPrecision(a); + }; + auto fromHalf_2 = [](std::uint16_t a, long double b) -> ExtendedFloat + { + return ExtendedFloat(b); + }; const long double NaN = std::numeric_limits::quiet_NaN(); const long double Infinity = std::numeric_limits::infinity(); testCase("add", add1, add2, +0.0L, +0.0L); @@ -526,6 +534,21 @@ void mainFn() testCase("log2", log2_1, log2_2, static_cast(ExtendedFloat::LogOf2())); testCase("log10", log10_1, log10_2, 1e1001L); testCase("log10", log10_1, log10_2, 1.5L); + testCase("fromHalf", + fromHalf_1, + fromHalf_2, + static_cast(0x1U), + 5.9604644775390625e-8L); + testCase("fromHalf", + fromHalf_1, + fromHalf_2, + static_cast(0x8001U), + -5.9604644775390625e-8L); + testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast(0x3C00U), 1.0L); + testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast(0xBC00U), -1.0L); + testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast(0x7C00U), Infinity); + testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast(0xFC00U), -Infinity); + testCase("fromHalf", fromHalf_1, fromHalf_2, static_cast(0x7C01U), NaN); } struct Init { diff --git a/src/util/soft_float.h b/src/util/soft_float.h index e8b7efb..b0ca4de 100644 --- a/src/util/soft_float.h +++ b/src/util/soft_float.h @@ -561,6 +561,23 @@ struct ExtendedFloat final // modeled after IEEE754 standard value = std::scalbn(value, 63 - static_cast(exponent) + exponentBias()); mantissa = value; } + static constexpr ExtendedFloat fromHalfPrecision(std::uint16_t value) noexcept + { + bool sign = (value & 0x8000U) != 0; + std::uint16_t exponentField = (value & 0x7C00U) >> 10; + std::uint16_t mantissaField = value & 0x3FFU; + if(exponentField == 0x1FU) + { + if(mantissaField != 0) + return NaN(); + return Infinity(sign); + } + if(exponentField != 0) + mantissaField |= 0x400U; // add in implicit 1 + else + exponentField = 1; + return ExtendedFloat(mantissaField, static_cast(exponentField) - 15 - 10 + exponentBias() + 63, sign); + } explicit operator long double() const noexcept { if(exponent == infinityNaNExponent())