From ef2faa1fb2a209e68960bc6eacd4bff246bf57d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20S=C3=A9chet?= Date: Sun, 9 Jul 2023 00:17:44 +0000 Subject: [PATCH] Extract float materialization in its own function. --- src/source/packedfloat.d | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/source/packedfloat.d b/src/source/packedfloat.d index 2150d336e..162e48d1b 100644 --- a/src/source/packedfloat.d +++ b/src/source/packedfloat.d @@ -270,9 +270,7 @@ struct SoftFloat { enum MantissaBits = C.MantissaExplicitBits; auto shift = (upperbit + 64 - MantissaBits - 3); - auto mask = (4UL << shift) - 1; - auto m = approx >> shift; int e = power(exponent) + upperbit - lz + C.ExponentOffset; /** @@ -287,7 +285,7 @@ struct SoftFloat { } // Recompute m with the new shift. - m = approx >> shift; + auto m = approx >> shift; // We can't have both "round-to-even" and subnormals because // "round-to-even" only occurs for powers close to 0, so just @@ -304,9 +302,13 @@ struct SoftFloat { * this after rounding. */ e = m >= (1UL << MantissaBits); - goto Materialize; + + return materialize!T(m, e); } + auto m = approx >> shift; + auto mask = (4UL << shift) - 1; + /** * /!\ If the value is right in the middle of two float, * we must round down! @@ -326,15 +328,26 @@ struct SoftFloat { return T.infinity; } - Materialize: - enum MantissaMask = (1UL << MantissaBits) - 1; - enum ExponentMask = (1UL << (8 * T.sizeof - 1 - MantissaBits)) - 1; - - ulong raw = (m & MantissaMask) | ((e & ExponentMask) << MantissaBits); - return *(cast(T*) &raw); + return materialize!T(m, e); } } +T materialize(T)(ulong mantissa, int exponent) if (isFloatingPoint!T) { + alias C = TypeConstants!T; + enum MantissaBits = C.MantissaExplicitBits; + enum MantissaMask = (1UL << MantissaBits) - 1; + enum ExponentMask = (1UL << (8 * T.sizeof - 1 - MantissaBits)) - 1; + + ulong m = mantissa & MantissaMask; + assert((m ^ mantissa) <= (MantissaMask + 1)); + + ulong e = exponent; + assert((e & ExponentMask) == exponent); + + ulong raw = m | (e << MantissaBits); + return *(cast(T*) &raw); +} + /** * Compute an aproximation of mantissa * 5^exponent. *