From 25fdedf0d33e01ad4c950b7e4d58da498649aa29 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Fri, 20 Nov 2020 12:11:08 -0800 Subject: [PATCH] softfloat: Split out parts_uncanon_normal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We will need to treat the non-normal cases of floatx80 specially, so split out the normal case that we can reuse. Reviewed-by: Alex Bennée Signed-off-by: Richard Henderson --- fpu/softfloat-parts.c.inc | 59 +++++++++++++++++++++------------------ fpu/softfloat.c | 8 ++++++ 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc index d69f357352..e05909db8c 100644 --- a/fpu/softfloat-parts.c.inc +++ b/fpu/softfloat-parts.c.inc @@ -140,8 +140,8 @@ static void partsN(canonicalize)(FloatPartsN *p, float_status *status, * fraction; these bits will be removed. The exponent will be biased * by EXP_BIAS and must be bounded by [EXP_MAX-1, 0]. */ -static void partsN(uncanon)(FloatPartsN *p, float_status *s, - const FloatFmt *fmt) +static void partsN(uncanon_normal)(FloatPartsN *p, float_status *s, + const FloatFmt *fmt) { const int exp_max = fmt->exp_max; const int frac_shift = fmt->frac_shift; @@ -150,33 +150,9 @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s, const uint64_t round_mask = fmt->round_mask; const uint64_t roundeven_mask = fmt->roundeven_mask; uint64_t inc; - bool overflow_norm; + bool overflow_norm = false; int exp, flags = 0; - if (unlikely(p->cls != float_class_normal)) { - switch (p->cls) { - case float_class_zero: - p->exp = 0; - frac_clear(p); - return; - case float_class_inf: - g_assert(!fmt->arm_althp); - p->exp = fmt->exp_max; - frac_clear(p); - return; - case float_class_qnan: - case float_class_snan: - g_assert(!fmt->arm_althp); - p->exp = fmt->exp_max; - frac_shr(p, fmt->frac_shift); - return; - default: - break; - } - g_assert_not_reached(); - } - - overflow_norm = false; switch (s->float_rounding_mode) { case float_round_nearest_even: inc = ((p->frac_lo & roundeven_mask) != frac_lsbm1 ? frac_lsbm1 : 0); @@ -284,6 +260,35 @@ static void partsN(uncanon)(FloatPartsN *p, float_status *s, float_raise(flags, s); } +static void partsN(uncanon)(FloatPartsN *p, float_status *s, + const FloatFmt *fmt) +{ + if (likely(p->cls == float_class_normal)) { + parts_uncanon_normal(p, s, fmt); + } else { + switch (p->cls) { + case float_class_zero: + p->exp = 0; + frac_clear(p); + return; + case float_class_inf: + g_assert(!fmt->arm_althp); + p->exp = fmt->exp_max; + frac_clear(p); + return; + case float_class_qnan: + case float_class_snan: + g_assert(!fmt->arm_althp); + p->exp = fmt->exp_max; + frac_shr(p, fmt->frac_shift); + return; + default: + break; + } + g_assert_not_reached(); + } +} + /* * Returns the result of adding or subtracting the values of the * floating-point values `a' and `b'. The operation is performed diff --git a/fpu/softfloat.c b/fpu/softfloat.c index 0f2eed8d29..ea7ee13201 100644 --- a/fpu/softfloat.c +++ b/fpu/softfloat.c @@ -764,6 +764,14 @@ static void parts128_canonicalize(FloatParts128 *p, float_status *status, #define parts_canonicalize(A, S, F) \ PARTS_GENERIC_64_128(canonicalize, A)(A, S, F) +static void parts64_uncanon_normal(FloatParts64 *p, float_status *status, + const FloatFmt *fmt); +static void parts128_uncanon_normal(FloatParts128 *p, float_status *status, + const FloatFmt *fmt); + +#define parts_uncanon_normal(A, S, F) \ + PARTS_GENERIC_64_128(uncanon_normal, A)(A, S, F) + static void parts64_uncanon(FloatParts64 *p, float_status *status, const FloatFmt *fmt); static void parts128_uncanon(FloatParts128 *p, float_status *status,