All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, danielhb413@gmail.com,
	alex.bennee@linaro.org, clg@kaod.org
Subject: [PATCH 27/35] softfloat: Add float64r32 arithmetic routines
Date: Fri, 19 Nov 2021 17:04:54 +0100	[thread overview]
Message-ID: <20211119160502.17432-28-richard.henderson@linaro.org> (raw)
In-Reply-To: <20211119160502.17432-1-richard.henderson@linaro.org>

These variants take a float64 as input, compute the result to
infinite precision (as we do with FloatParts), round the result
to the precision and dynamic range of float32, and then return
the result in the format of float64.

This is the operation PowerPC requires for its float32 operations.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat.h |  12 +++++
 fpu/softfloat.c         | 110 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 122 insertions(+)

diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 0d3b407807..d34b2c44d2 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -908,6 +908,18 @@ static inline bool float64_unordered_quiet(float64 a, float64 b,
 *----------------------------------------------------------------------------*/
 float64 float64_default_nan(float_status *status);
 
+/*----------------------------------------------------------------------------
+| Software IEC/IEEE double-precision operations, rounding to single precision,
+| returning a result in double precision, with only one rounding step.
+*----------------------------------------------------------------------------*/
+
+float64 float64r32_add(float64, float64, float_status *status);
+float64 float64r32_sub(float64, float64, float_status *status);
+float64 float64r32_mul(float64, float64, float_status *status);
+float64 float64r32_div(float64, float64, float_status *status);
+float64 float64r32_muladd(float64, float64, float64, int, float_status *status);
+float64 float64r32_sqrt(float64, float_status *status);
+
 /*----------------------------------------------------------------------------
 | Software IEC/IEEE extended double-precision conversion routines.
 *----------------------------------------------------------------------------*/
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 834ed3a054..7f524d4377 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1693,6 +1693,50 @@ static float64 float64_round_pack_canonical(FloatParts64 *p,
     return float64_pack_raw(p);
 }
 
+static float64 float64r32_round_pack_canonical(FloatParts64 *p,
+                                               float_status *s)
+{
+    parts_uncanon(p, s, &float32_params);
+
+    /*
+     * In parts_uncanon, we placed the fraction for float32 at the lsb.
+     * We need to adjust the fraction higher so that the least N bits are
+     * zero, and the fraction is adjacent to the float64 implicit bit.
+     */
+    switch (p->cls) {
+    case float_class_normal:
+        if (unlikely(p->exp == 0)) {
+            /*
+             * The result is denormal for float32, but can be represented
+             * in normalized form for float64.  Adjust, per canonicalize.
+             */
+            int shift = frac_normalize(p);
+            p->exp = (float32_params.frac_shift -
+                      float32_params.exp_bias - shift + 1 +
+                      float64_params.exp_bias);
+            frac_shr(p, float64_params.frac_shift);
+        } else {
+            frac_shl(p, float32_params.frac_shift - float64_params.frac_shift);
+            p->exp += float64_params.exp_bias - float32_params.exp_bias;
+        }
+        break;
+    case float_class_snan:
+    case float_class_qnan:
+        frac_shl(p, float32_params.frac_shift - float64_params.frac_shift);
+        p->exp = float64_params.exp_max;
+        break;
+    case float_class_inf:
+        p->exp = float64_params.exp_max;
+        break;
+    case float_class_zero:
+        break;
+    default:
+        g_assert_not_reached();
+    }
+
+    return float64_pack_raw(p);
+}
+
 static void float128_unpack_canonical(FloatParts128 *p, float128 f,
                                       float_status *s)
 {
@@ -1938,6 +1982,28 @@ float64_sub(float64 a, float64 b, float_status *s)
     return float64_addsub(a, b, s, hard_f64_sub, soft_f64_sub);
 }
 
+static float64 float64r32_addsub(float64 a, float64 b, float_status *status,
+                                 bool subtract)
+{
+    FloatParts64 pa, pb, *pr;
+
+    float64_unpack_canonical(&pa, a, status);
+    float64_unpack_canonical(&pb, b, status);
+    pr = parts_addsub(&pa, &pb, status, subtract);
+
+    return float64r32_round_pack_canonical(pr, status);
+}
+
+float64 float64r32_add(float64 a, float64 b, float_status *status)
+{
+    return float64r32_addsub(a, b, status, false);
+}
+
+float64 float64r32_sub(float64 a, float64 b, float_status *status)
+{
+    return float64r32_addsub(a, b, status, true);
+}
+
 static bfloat16 QEMU_FLATTEN
 bfloat16_addsub(bfloat16 a, bfloat16 b, float_status *status, bool subtract)
 {
@@ -2069,6 +2135,17 @@ float64_mul(float64 a, float64 b, float_status *s)
                         f64_is_zon2, f64_addsubmul_post);
 }
 
+float64 float64r32_mul(float64 a, float64 b, float_status *status)
+{
+    FloatParts64 pa, pb, *pr;
+
+    float64_unpack_canonical(&pa, a, status);
+    float64_unpack_canonical(&pb, b, status);
+    pr = parts_mul(&pa, &pb, status);
+
+    return float64r32_round_pack_canonical(pr, status);
+}
+
 bfloat16 QEMU_FLATTEN
 bfloat16_mul(bfloat16 a, bfloat16 b, float_status *status)
 {
@@ -2296,6 +2373,19 @@ float64_muladd(float64 xa, float64 xb, float64 xc, int flags, float_status *s)
     return soft_f64_muladd(ua.s, ub.s, uc.s, flags, s);
 }
 
+float64 float64r32_muladd(float64 a, float64 b, float64 c,
+                          int flags, float_status *status)
+{
+    FloatParts64 pa, pb, pc, *pr;
+
+    float64_unpack_canonical(&pa, a, status);
+    float64_unpack_canonical(&pb, b, status);
+    float64_unpack_canonical(&pc, c, status);
+    pr = parts_muladd(&pa, &pb, &pc, flags, status);
+
+    return float64r32_round_pack_canonical(pr, status);
+}
+
 bfloat16 QEMU_FLATTEN bfloat16_muladd(bfloat16 a, bfloat16 b, bfloat16 c,
                                       int flags, float_status *status)
 {
@@ -2419,6 +2509,17 @@ float64_div(float64 a, float64 b, float_status *s)
                         f64_div_pre, f64_div_post);
 }
 
+float64 float64r32_div(float64 a, float64 b, float_status *status)
+{
+    FloatParts64 pa, pb, *pr;
+
+    float64_unpack_canonical(&pa, a, status);
+    float64_unpack_canonical(&pb, b, status);
+    pr = parts_div(&pa, &pb, status);
+
+    return float64r32_round_pack_canonical(pr, status);
+}
+
 bfloat16 QEMU_FLATTEN
 bfloat16_div(bfloat16 a, bfloat16 b, float_status *status)
 {
@@ -4285,6 +4386,15 @@ float64 QEMU_FLATTEN float64_sqrt(float64 xa, float_status *s)
     return soft_f64_sqrt(ua.s, s);
 }
 
+float64 float64r32_sqrt(float64 a, float_status *status)
+{
+    FloatParts64 p;
+
+    float64_unpack_canonical(&p, a, status);
+    parts_sqrt(&p, status, &float64_params);
+    return float64r32_round_pack_canonical(&p, status);
+}
+
 bfloat16 QEMU_FLATTEN bfloat16_sqrt(bfloat16 a, float_status *status)
 {
     FloatParts64 p;
-- 
2.25.1



  parent reply	other threads:[~2021-11-19 16:33 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
2021-11-19 16:04 ` [PATCH 01/35] softfloat: Extend float_exception_flags to 16 bits Richard Henderson
2021-12-03 21:33   ` Philippe Mathieu-Daudé
2021-11-19 16:04 ` [PATCH 02/35] softfloat: Add flag specific to Inf - Inf Richard Henderson
2021-11-19 16:04 ` [PATCH 03/35] softfloat: Add flag specific to Inf * 0 Richard Henderson
2021-11-19 16:04 ` [PATCH 04/35] softfloat: Add flags specific to Inf / Inf and 0 / 0 Richard Henderson
2021-11-19 16:04 ` [PATCH 05/35] softfloat: Add flag specific to sqrt(-x) Richard Henderson
2021-11-19 16:04 ` [PATCH 06/35] softfloat: Add flag specific to convert non-nan to int Richard Henderson
2021-11-19 16:04 ` [PATCH 07/35] softfloat: Add flag specific to signaling nans Richard Henderson
2021-11-19 16:04 ` [PATCH 08/35] target/ppc: Update float_invalid_op_addsub for new flags Richard Henderson
2021-11-19 16:04 ` [PATCH 09/35] target/ppc: Update float_invalid_op_mul " Richard Henderson
2021-11-19 16:04 ` [PATCH 10/35] target/ppc: Update float_invalid_op_div " Richard Henderson
2021-11-19 16:04 ` [PATCH 11/35] target/ppc: Move float_check_status from FPU_FCTI to translate Richard Henderson
2021-11-19 16:04 ` [PATCH 12/35] target/ppc: Update float_invalid_cvt for new flags Richard Henderson
2021-11-19 16:04 ` [PATCH 13/35] target/ppc: Fix VXCVI return value Richard Henderson
2021-11-19 16:04 ` [PATCH 14/35] target/ppc: Remove inline from do_fri Richard Henderson
2021-12-03 21:33   ` Philippe Mathieu-Daudé
2021-11-19 16:04 ` [PATCH 15/35] target/ppc: Use FloatRoundMode in do_fri Richard Henderson
2021-12-03 21:33   ` Philippe Mathieu-Daudé
2021-11-19 16:04 ` [PATCH 16/35] target/ppc: Tidy inexact handling " Richard Henderson
2021-11-19 16:04 ` [PATCH 17/35] target/ppc: Clean up do_fri Richard Henderson
2021-11-19 16:04 ` [PATCH 18/35] target/ppc: Update fmadd for new flags Richard Henderson
2021-11-19 16:04 ` [PATCH 19/35] target/ppc: Split out do_fmadd Richard Henderson
2021-11-19 16:04 ` [PATCH 20/35] target/ppc: Do not call do_float_check_status from do_fmadd Richard Henderson
2021-11-19 16:04 ` [PATCH 21/35] target/ppc: Split out do_frsp Richard Henderson
2021-11-19 16:04 ` [PATCH 22/35] target/ppc: Update do_frsp for new flags Richard Henderson
2021-11-19 16:04 ` [PATCH 23/35] target/ppc: Use helper_todouble in do_frsp Richard Henderson
2021-11-19 16:04 ` [PATCH 24/35] target/ppc: Update sqrt for new flags Richard Henderson
2021-11-19 16:04 ` [PATCH 25/35] target/ppc: Update xsrqpi and xsrqpxp to " Richard Henderson
2021-11-19 16:04 ` [PATCH 26/35] target/ppc: Update fre " Richard Henderson
2021-11-19 16:04 ` Richard Henderson [this message]
2021-11-19 16:04 ` [PATCH 28/35] target/ppc: Add helpers for fmadds et al Richard Henderson
2021-11-19 16:04 ` [PATCH 29/35] target/ppc: Add helper for fsqrts Richard Henderson
2021-11-19 16:04 ` [PATCH 30/35] target/ppc: Add helpers for fadds, fsubs, fdivs Richard Henderson
2021-11-19 16:04 ` [PATCH 31/35] target/ppc: Add helper for fmuls Richard Henderson
2021-11-19 16:04 ` [PATCH 32/35] target/ppc: Add helper for frsqrtes Richard Henderson
2021-11-19 16:05 ` [PATCH 33/35] target/ppc: Update fres to new flags and float64r32 Richard Henderson
2021-11-19 16:05 ` [PATCH 34/35] target/ppc: Use helper_todouble/tosingle in helper_xststdcsp Richard Henderson
2021-11-19 16:05 ` [PATCH 35/35] test/tcg/ppc64le: Add float reference files Richard Henderson
2021-11-21 17:47   ` Cédric Le Goater
2021-11-22  9:43     ` Richard Henderson
2021-11-22  9:51       ` Cédric Le Goater
2021-11-22 11:16       ` Richard Henderson
2021-11-22 13:04         ` Cédric Le Goater
2021-11-22 13:14           ` Richard Henderson
2021-11-24  9:17             ` Cédric Le Goater
2021-11-24  9:27               ` Richard Henderson
2021-11-29 14:45         ` Cédric Le Goater
2021-12-03 10:36 ` [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Cédric Le Goater
2021-12-03 16:10 ` Matheus K. Ferst
2021-12-15 16:42 ` Cédric Le Goater

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211119160502.17432-28-richard.henderson@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=alex.bennee@linaro.org \
    --cc=clg@kaod.org \
    --cc=danielhb413@gmail.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.