Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
Signed-off-by: Richard Henderson <[email protected]>
---
 include/fpu/softfloat-parts.h |  3 +++
 fpu/softfloat.c               | 22 +++++++++++++++++++---
 2 files changed, 22 insertions(+), 3 deletions(-)

diff --git a/include/fpu/softfloat-parts.h b/include/fpu/softfloat-parts.h
index 8c3a94bbbc..1876264d43 100644
--- a/include/fpu/softfloat-parts.h
+++ b/include/fpu/softfloat-parts.h
@@ -196,4 +196,7 @@ FloatParts128 parts128_round_to_int(const FloatParts128 *a,
                                     int scale, float_status *s,
                                     const FloatFmt *fmt);
 
+FloatParts64 parts64_round_to_fmt(const FloatParts64 *p, float_status *s,
+                                  const FloatFmt *fmt);
+
 #endif
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index b71bd49483..b6cf0c8188 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -1396,6 +1396,24 @@ float64 float64_round_pack_canonical(FloatParts64 *p, 
float_status *s)
     return pack_raw64(p, &float64_params);
 }
 
+/*
+ * Round to Fmt while remaining canonicalized.
+ */
+FloatParts64 parts64_round_to_fmt(const FloatParts64 *p, float_status *s,
+                                  const FloatFmt *fmt)
+{
+    FloatParts64 r = *p;
+
+    parts64_uncanon(&r, s, fmt, false);
+    /*
+     * We normally expect uncanon to be followed by pack_raw,
+     * so we don't actually crop the bits.  Do so now.
+     */
+    r.frac &= MAKE_64BIT_MASK(0, fmt->frac_size);
+    parts64_canonicalize(&r, s, fmt);
+    return r;
+}
+
 static float64 float64r32_pack_raw(FloatParts64 *p)
 {
     /*
@@ -5176,10 +5194,8 @@ static void parts_s390_divide_to_integer(FloatParts64 
*a, FloatParts64 *b,
         /* Round remainder to the target format */
         *r = *r_precise;
         status->float_exception_flags = 0;
-        parts64_uncanon(r, status, fmt, false);
+        *r = parts64_round_to_fmt(r, status, fmt);
         r_flags = status->float_exception_flags;
-        r->frac &= (1ULL << fmt->frac_size) - 1;
-        parts64_canonicalize(r, status, fmt);
 
         /* POp table "Results: DIVIDE TO INTEGER (Part 2 of 2)" */
         if (is_q_smallish) {
-- 
2.43.0


Reply via email to