All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups
@ 2021-11-19 16:04 Richard Henderson
  2021-11-19 16:04 ` [PATCH 01/35] softfloat: Extend float_exception_flags to 16 bits Richard Henderson
                   ` (37 more replies)
  0 siblings, 38 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

This is a partial patch set showing the direction I believe
the cleanups should go, as opposed to a complete conversion.

I add a bunch of float_flag_* bits that diagnose the reason
for most float_flag_invalid, as guided by the requirements
of the PowerPC VX* bits.  I have converted some helpers to
use these new flags but not all.  A good signal for unconverted
routines is the use of float*_is_signalling_nan, which should
now be using float_flag_invalid_snan.

I added float64x32_* arithmetic routines, which take float64
arguments and round the result to the range and precision of
float32, while giving the result in float64 form.  This is
exactly what PowerPC requires for its single-precision math.
This fixes double-rounding problems that exist in the current
code, and are visible in the float_madds test.

I add test reference files for float_madds and float_convs
after fixing the bugs required to make the tests pass.


r~


Richard Henderson (35):
  softfloat: Extend float_exception_flags to 16 bits
  softfloat: Add flag specific to Inf - Inf
  softfloat: Add flag specific to Inf * 0
  softfloat: Add flags specific to Inf / Inf and 0 / 0
  softfloat: Add flag specific to sqrt(-x)
  softfloat: Add flag specific to convert non-nan to int
  softfloat: Add flag specific to signaling nans
  target/ppc: Update float_invalid_op_addsub for new flags
  target/ppc: Update float_invalid_op_mul for new flags
  target/ppc: Update float_invalid_op_div for new flags
  target/ppc: Move float_check_status from FPU_FCTI to translate
  target/ppc: Update float_invalid_cvt for new flags
  target/ppc: Fix VXCVI return value
  target/ppc: Remove inline from do_fri
  target/ppc: Use FloatRoundMode in do_fri
  target/ppc: Tidy inexact handling in do_fri
  target/ppc: Clean up do_fri
  target/ppc: Update fmadd for new flags
  target/ppc: Split out do_fmadd
  target/ppc: Do not call do_float_check_status from do_fmadd
  target/ppc: Split out do_frsp
  target/ppc: Update do_frsp for new flags
  target/ppc: Use helper_todouble in do_frsp
  target/ppc: Update sqrt for new flags
  target/ppc: Update xsrqpi and xsrqpxp to new flags
  target/ppc: Update fre to new flags
  softfloat: Add float64r32 arithmetic routines
  target/ppc: Add helpers for fmadds et al
  target/ppc: Add helper for fsqrts
  target/ppc: Add helpers for fadds, fsubs, fdivs
  target/ppc: Add helper for fmuls
  target/ppc: Add helper for frsqrtes
  target/ppc: Update fres to new flags and float64r32
  target/ppc: Use helper_todouble/tosingle in helper_xststdcsp
  test/tcg/ppc64le: Add float reference files

 include/fpu/softfloat-types.h      |  23 +-
 include/fpu/softfloat.h            |  14 +-
 target/ppc/helper.h                |  10 +
 fpu/softfloat.c                    | 114 ++++-
 target/ppc/fpu_helper.c            | 531 ++++++++++----------
 fpu/softfloat-parts.c.inc          |  57 ++-
 fpu/softfloat-specialize.c.inc     |  12 +-
 target/ppc/translate/fp-impl.c.inc |  44 +-
 tests/tcg/ppc64le/float_convs.ref  | 748 ++++++++++++++++++++++++++++
 tests/tcg/ppc64le/float_madds.ref  | 768 +++++++++++++++++++++++++++++
 10 files changed, 1996 insertions(+), 325 deletions(-)
 create mode 100644 tests/tcg/ppc64le/float_convs.ref
 create mode 100644 tests/tcg/ppc64le/float_madds.ref

-- 
2.25.1



^ permalink raw reply	[flat|nested] 51+ messages in thread

* [PATCH 01/35] softfloat: Extend float_exception_flags to 16 bits
  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 ` 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
                   ` (36 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

We will shortly have more than 8 bits of exceptions.
Repack the existing flags into low bits and reformat to hex.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h | 16 ++++++++--------
 include/fpu/softfloat.h       |  2 +-
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 5bcbd041f7..65a43aff59 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -145,13 +145,13 @@ typedef enum __attribute__((__packed__)) {
  */
 
 enum {
-    float_flag_invalid   =  1,
-    float_flag_divbyzero =  4,
-    float_flag_overflow  =  8,
-    float_flag_underflow = 16,
-    float_flag_inexact   = 32,
-    float_flag_input_denormal = 64,
-    float_flag_output_denormal = 128
+    float_flag_invalid         = 0x0001,
+    float_flag_divbyzero       = 0x0002,
+    float_flag_overflow        = 0x0004,
+    float_flag_underflow       = 0x0008,
+    float_flag_inexact         = 0x0010,
+    float_flag_input_denormal  = 0x0020,
+    float_flag_output_denormal = 0x0040,
 };
 
 /*
@@ -171,8 +171,8 @@ typedef enum __attribute__((__packed__)) {
  */
 
 typedef struct float_status {
+    uint16_t float_exception_flags;
     FloatRoundMode float_rounding_mode;
-    uint8_t     float_exception_flags;
     FloatX80RoundPrec floatx80_rounding_precision;
     bool tininess_before_rounding;
     /* should denormalised results go to zero and set the inexact flag? */
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index a249991e61..0d3b407807 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -100,7 +100,7 @@ typedef enum {
 | Routine to raise any or all of the software IEC/IEEE floating-point
 | exception flags.
 *----------------------------------------------------------------------------*/
-static inline void float_raise(uint8_t flags, float_status *status)
+static inline void float_raise(uint16_t flags, float_status *status)
 {
     status->float_exception_flags |= flags;
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 02/35] softfloat: Add flag specific to Inf - Inf
  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-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 03/35] softfloat: Add flag specific to Inf * 0 Richard Henderson
                   ` (35 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

PowerPC has this flag, and it's easier to compute it here
than after the fact.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h | 1 +
 fpu/softfloat-parts.c.inc     | 3 ++-
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 65a43aff59..eaa12e1e00 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -152,6 +152,7 @@ enum {
     float_flag_inexact         = 0x0010,
     float_flag_input_denormal  = 0x0020,
     float_flag_output_denormal = 0x0040,
+    float_flag_invalid_isi     = 0x0080,  /* inf - inf */
 };
 
 /*
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 41d4b17e41..eb2b475ca4 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -354,7 +354,7 @@ static FloatPartsN *partsN(addsub)(FloatPartsN *a, FloatPartsN *b,
                 return a;
             }
             /* Inf - Inf */
-            float_raise(float_flag_invalid, s);
+            float_raise(float_flag_invalid | float_flag_invalid_isi, s);
             parts_default_nan(a, s);
             return a;
         }
@@ -494,6 +494,7 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
 
         if (ab_mask & float_cmask_inf) {
             if (c->cls == float_class_inf && a->sign != c->sign) {
+                float_raise(float_flag_invalid | float_flag_invalid_isi, s);
                 goto d_nan;
             }
             goto return_inf;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 03/35] softfloat: Add flag specific to Inf * 0
  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-11-19 16:04 ` [PATCH 02/35] softfloat: Add flag specific to Inf - Inf Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 04/35] softfloat: Add flags specific to Inf / Inf and 0 / 0 Richard Henderson
                   ` (34 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

PowerPC has this flag, and it's easier to compute it here
than after the fact.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h  |  1 +
 fpu/softfloat-parts.c.inc      |  4 ++--
 fpu/softfloat-specialize.c.inc | 12 ++++++------
 3 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index eaa12e1e00..56b4cf7835 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -153,6 +153,7 @@ enum {
     float_flag_input_denormal  = 0x0020,
     float_flag_output_denormal = 0x0040,
     float_flag_invalid_isi     = 0x0080,  /* inf - inf */
+    float_flag_invalid_imz     = 0x0100,  /* inf * 0 */
 };
 
 /*
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index eb2b475ca4..3ed793347b 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -423,7 +423,7 @@ static FloatPartsN *partsN(mul)(FloatPartsN *a, FloatPartsN *b,
 
     /* Inf * Zero == NaN */
     if (unlikely(ab_mask == float_cmask_infzero)) {
-        float_raise(float_flag_invalid, s);
+        float_raise(float_flag_invalid | float_flag_invalid_imz, s);
         parts_default_nan(a, s);
         return a;
     }
@@ -489,6 +489,7 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
 
     if (unlikely(ab_mask != float_cmask_normal)) {
         if (unlikely(ab_mask == float_cmask_infzero)) {
+            float_raise(float_flag_invalid | float_flag_invalid_imz, s);
             goto d_nan;
         }
 
@@ -567,7 +568,6 @@ static FloatPartsN *partsN(muladd)(FloatPartsN *a, FloatPartsN *b,
     goto finish_sign;
 
  d_nan:
-    float_raise(float_flag_invalid, s);
     parts_default_nan(a, s);
     return a;
 }
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index f2ad0f335e..943e3301d2 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -506,7 +506,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
      * the default NaN
      */
     if (infzero && is_qnan(c_cls)) {
-        float_raise(float_flag_invalid, status);
+        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
         return 3;
     }
 
@@ -533,7 +533,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
          * case sets InvalidOp and returns the default NaN
          */
         if (infzero) {
-            float_raise(float_flag_invalid, status);
+            float_raise(float_flag_invalid | float_flag_invalid_imz, status);
             return 3;
         }
         /* Prefer sNaN over qNaN, in the a, b, c order. */
@@ -556,7 +556,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
          * case sets InvalidOp and returns the input value 'c'
          */
         if (infzero) {
-            float_raise(float_flag_invalid, status);
+            float_raise(float_flag_invalid | float_flag_invalid_imz, status);
             return 2;
         }
         /* Prefer sNaN over qNaN, in the c, a, b order. */
@@ -580,7 +580,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
      * a default NaN
      */
     if (infzero) {
-        float_raise(float_flag_invalid, status);
+        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
         return 2;
     }
 
@@ -597,7 +597,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
 #elif defined(TARGET_RISCV)
     /* For RISC-V, InvalidOp is set when multiplicands are Inf and zero */
     if (infzero) {
-        float_raise(float_flag_invalid, status);
+        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
     }
     return 3; /* default NaN */
 #elif defined(TARGET_XTENSA)
@@ -606,7 +606,7 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
      * an input NaN if we have one (ie c).
      */
     if (infzero) {
-        float_raise(float_flag_invalid, status);
+        float_raise(float_flag_invalid | float_flag_invalid_imz, status);
         return 2;
     }
     if (status->use_first_nan) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 04/35] softfloat: Add flags specific to Inf / Inf and 0 / 0
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (2 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 03/35] softfloat: Add flag specific to Inf * 0 Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 05/35] softfloat: Add flag specific to sqrt(-x) Richard Henderson
                   ` (33 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

PowerPC has these flags, and it's easier to compute them here
than after the fact.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h |  2 ++
 fpu/softfloat-parts.c.inc     | 16 +++++++++++-----
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 56b4cf7835..5a9671e564 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -154,6 +154,8 @@ enum {
     float_flag_output_denormal = 0x0040,
     float_flag_invalid_isi     = 0x0080,  /* inf - inf */
     float_flag_invalid_imz     = 0x0100,  /* inf * 0 */
+    float_flag_invalid_idi     = 0x0200,  /* inf / inf */
+    float_flag_invalid_zdz     = 0x0400,  /* 0 / 0 */
 };
 
 /*
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index 3ed793347b..b8563cd2df 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -590,11 +590,13 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b,
     }
 
     /* 0/0 or Inf/Inf => NaN */
-    if (unlikely(ab_mask == float_cmask_zero) ||
-        unlikely(ab_mask == float_cmask_inf)) {
-        float_raise(float_flag_invalid, s);
-        parts_default_nan(a, s);
-        return a;
+    if (unlikely(ab_mask == float_cmask_zero)) {
+        float_raise(float_flag_invalid | float_flag_invalid_zdz, s);
+        goto d_nan;
+    }
+    if (unlikely(ab_mask == float_cmask_inf)) {
+        float_raise(float_flag_invalid | float_flag_invalid_idi, s);
+        goto d_nan;
     }
 
     /* All the NaN cases */
@@ -625,6 +627,10 @@ static FloatPartsN *partsN(div)(FloatPartsN *a, FloatPartsN *b,
     float_raise(float_flag_divbyzero, s);
     a->cls = float_class_inf;
     return a;
+
+ d_nan:
+    parts_default_nan(a, s);
+    return a;
 }
 
 /*
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 05/35] softfloat: Add flag specific to sqrt(-x)
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (3 preceding siblings ...)
  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 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 06/35] softfloat: Add flag specific to convert non-nan to int Richard Henderson
                   ` (32 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

PowerPC has this flag, and it's easier to compute it here
than after the fact.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h | 1 +
 fpu/softfloat-parts.c.inc     | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 5a9671e564..33224b5f22 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -156,6 +156,7 @@ enum {
     float_flag_invalid_imz     = 0x0100,  /* inf * 0 */
     float_flag_invalid_idi     = 0x0200,  /* inf / inf */
     float_flag_invalid_zdz     = 0x0400,  /* 0 / 0 */
+    float_flag_invalid_sqrt    = 0x0800,  /* sqrt(-x) */
 };
 
 /*
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index b8563cd2df..cc8c2c3aee 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -869,7 +869,7 @@ static void partsN(sqrt)(FloatPartsN *a, float_status *status,
     return;
 
  d_nan:
-    float_raise(float_flag_invalid, status);
+    float_raise(float_flag_invalid | float_flag_invalid_sqrt, status);
     parts_default_nan(a, status);
 }
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 06/35] softfloat: Add flag specific to convert non-nan to int
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (4 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 05/35] softfloat: Add flag specific to sqrt(-x) Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 07/35] softfloat: Add flag specific to signaling nans Richard Henderson
                   ` (31 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

PowerPC has this flag, and it's easier to compute it here
than after the fact.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h |  1 +
 fpu/softfloat-parts.c.inc     | 14 +++++++-------
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 33224b5f22..9ca50e930b 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -157,6 +157,7 @@ enum {
     float_flag_invalid_idi     = 0x0200,  /* inf / inf */
     float_flag_invalid_zdz     = 0x0400,  /* 0 / 0 */
     float_flag_invalid_sqrt    = 0x0800,  /* sqrt(-x) */
+    float_flag_invalid_cvti    = 0x1000,  /* non-nan to integer */
 };
 
 /*
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index cc8c2c3aee..ce580347dd 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -1055,7 +1055,7 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
         break;
 
     case float_class_inf:
-        flags = float_flag_invalid;
+        flags = float_flag_invalid | float_flag_invalid_cvti;
         r = p->sign ? min : max;
         break;
 
@@ -1077,11 +1077,11 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
             if (r <= -(uint64_t)min) {
                 r = -r;
             } else {
-                flags = float_flag_invalid;
+                flags = float_flag_invalid | float_flag_invalid_cvti;
                 r = min;
             }
         } else if (r > max) {
-            flags = float_flag_invalid;
+            flags = float_flag_invalid | float_flag_invalid_cvti;
             r = max;
         }
         break;
@@ -1120,7 +1120,7 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
         break;
 
     case float_class_inf:
-        flags = float_flag_invalid;
+        flags = float_flag_invalid | float_flag_invalid_cvti;
         r = p->sign ? 0 : max;
         break;
 
@@ -1138,15 +1138,15 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
         }
 
         if (p->sign) {
-            flags = float_flag_invalid;
+            flags = float_flag_invalid | float_flag_invalid_cvti;
             r = 0;
         } else if (p->exp > DECOMPOSED_BINARY_POINT) {
-            flags = float_flag_invalid;
+            flags = float_flag_invalid | float_flag_invalid_cvti;
             r = max;
         } else {
             r = p->frac_hi >> (DECOMPOSED_BINARY_POINT - p->exp);
             if (r > max) {
-                flags = float_flag_invalid;
+                flags = float_flag_invalid | float_flag_invalid_cvti;
                 r = max;
             }
         }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 07/35] softfloat: Add flag specific to signaling nans
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (5 preceding siblings ...)
  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 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 08/35] target/ppc: Update float_invalid_op_addsub for new flags Richard Henderson
                   ` (30 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

PowerPC has this flag, and it's easier to compute it here
than after the fact.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/fpu/softfloat-types.h |  1 +
 fpu/softfloat.c               |  4 +++-
 fpu/softfloat-parts.c.inc     | 18 ++++++++++++------
 3 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 9ca50e930b..8abd9ab4ec 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -158,6 +158,7 @@ enum {
     float_flag_invalid_zdz     = 0x0400,  /* 0 / 0 */
     float_flag_invalid_sqrt    = 0x0800,  /* sqrt(-x) */
     float_flag_invalid_cvti    = 0x1000,  /* non-nan to integer */
+    float_flag_invalid_snan    = 0x2000,  /* any operand was snan */
 };
 
 /*
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9a28720d82..834ed3a054 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -2543,8 +2543,10 @@ floatx80 floatx80_mod(floatx80 a, floatx80 b, float_status *status)
 static void parts_float_to_ahp(FloatParts64 *a, float_status *s)
 {
     switch (a->cls) {
-    case float_class_qnan:
     case float_class_snan:
+        float_raise(float_flag_invalid_snan, s);
+        /* fall through */
+    case float_class_qnan:
         /*
          * There is no NaN in the destination format.  Raise Invalid
          * and return a zero with the sign of the input NaN.
diff --git a/fpu/softfloat-parts.c.inc b/fpu/softfloat-parts.c.inc
index ce580347dd..db3e1f393d 100644
--- a/fpu/softfloat-parts.c.inc
+++ b/fpu/softfloat-parts.c.inc
@@ -19,7 +19,7 @@ static void partsN(return_nan)(FloatPartsN *a, float_status *s)
 {
     switch (a->cls) {
     case float_class_snan:
-        float_raise(float_flag_invalid, s);
+        float_raise(float_flag_invalid | float_flag_invalid_snan, s);
         if (s->default_nan_mode) {
             parts_default_nan(a, s);
         } else {
@@ -40,7 +40,7 @@ static FloatPartsN *partsN(pick_nan)(FloatPartsN *a, FloatPartsN *b,
                                      float_status *s)
 {
     if (is_snan(a->cls) || is_snan(b->cls)) {
-        float_raise(float_flag_invalid, s);
+        float_raise(float_flag_invalid | float_flag_invalid_snan, s);
     }
 
     if (s->default_nan_mode) {
@@ -68,7 +68,7 @@ static FloatPartsN *partsN(pick_nan_muladd)(FloatPartsN *a, FloatPartsN *b,
     int which;
 
     if (unlikely(abc_mask & float_cmask_snan)) {
-        float_raise(float_flag_invalid, s);
+        float_raise(float_flag_invalid | float_flag_invalid_snan, s);
     }
 
     which = pickNaNMulAdd(a->cls, b->cls, c->cls,
@@ -1049,8 +1049,10 @@ static int64_t partsN(float_to_sint)(FloatPartsN *p, FloatRoundMode rmode,
 
     switch (p->cls) {
     case float_class_snan:
+        flags |= float_flag_invalid_snan;
+        /* fall through */
     case float_class_qnan:
-        flags = float_flag_invalid;
+        flags |= float_flag_invalid;
         r = max;
         break;
 
@@ -1114,8 +1116,10 @@ static uint64_t partsN(float_to_uint)(FloatPartsN *p, FloatRoundMode rmode,
 
     switch (p->cls) {
     case float_class_snan:
+        flags |= float_flag_invalid_snan;
+        /* fall through */
     case float_class_qnan:
-        flags = float_flag_invalid;
+        flags |= float_flag_invalid;
         r = max;
         break;
 
@@ -1341,7 +1345,9 @@ static FloatRelation partsN(compare)(FloatPartsN *a, FloatPartsN *b,
     }
 
     if (unlikely(ab_mask & float_cmask_anynan)) {
-        if (!is_quiet || (ab_mask & float_cmask_snan)) {
+        if (ab_mask & float_cmask_snan) {
+            float_raise(float_flag_invalid | float_flag_invalid_snan, s);
+        } else if (!is_quiet) {
             float_raise(float_flag_invalid, s);
         }
         return float_relation_unordered;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 08/35] target/ppc: Update float_invalid_op_addsub for new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (6 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 07/35] softfloat: Add flag specific to signaling nans Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 09/35] target/ppc: Update float_invalid_op_mul " Richard Henderson
                   ` (29 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Now that vxisi and vxsnan are computed directly by
softfloat, we don't need to recompute it via classes.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 38 ++++++++++++++------------------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index c4896cecc8..f0deada84b 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -450,13 +450,12 @@ void helper_reset_fpstatus(CPUPPCState *env)
     set_float_exception_flags(0, &env->fp_status);
 }
 
-static void float_invalid_op_addsub(CPUPPCState *env, bool set_fpcc,
-                                    uintptr_t retaddr, int classes)
+static void float_invalid_op_addsub(CPUPPCState *env, int flags,
+                                    bool set_fpcc, uintptr_t retaddr)
 {
-    if ((classes & ~is_neg) == is_inf) {
-        /* Magnitude subtraction of infinities */
+    if (flags & float_flag_invalid_isi) {
         float_invalid_op_vxisi(env, set_fpcc, retaddr);
-    } else if (classes & is_snan) {
+    } else if (flags & float_flag_invalid_snan) {
         float_invalid_op_vxsnan(env, retaddr);
     }
 }
@@ -465,12 +464,10 @@ static void float_invalid_op_addsub(CPUPPCState *env, bool set_fpcc,
 float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2)
 {
     float64 ret = float64_add(arg1, arg2, &env->fp_status);
-    int status = get_float_exception_flags(&env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    if (unlikely(status & float_flag_invalid)) {
-        float_invalid_op_addsub(env, 1, GETPC(),
-                                float64_classify(arg1) |
-                                float64_classify(arg2));
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_addsub(env, flags, 1, GETPC());
     }
 
     return ret;
@@ -480,12 +477,10 @@ float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2)
 float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2)
 {
     float64 ret = float64_sub(arg1, arg2, &env->fp_status);
-    int status = get_float_exception_flags(&env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    if (unlikely(status & float_flag_invalid)) {
-        float_invalid_op_addsub(env, 1, GETPC(),
-                                float64_classify(arg1) |
-                                float64_classify(arg2));
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_addsub(env, flags, 1, GETPC());
     }
 
     return ret;
@@ -1616,9 +1611,8 @@ void helper_##name(CPUPPCState *env, ppc_vsr_t *xt,                          \
         env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
                                                                              \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
-            float_invalid_op_addsub(env, sfprf, GETPC(),                     \
-                                    tp##_classify(xa->fld) |                 \
-                                    tp##_classify(xb->fld));                 \
+            float_invalid_op_addsub(env, tstat.float_exception_flags,        \
+                                    sfprf, GETPC());                         \
         }                                                                    \
                                                                              \
         if (r2sp) {                                                          \
@@ -1660,9 +1654,7 @@ void helper_xsaddqp(CPUPPCState *env, uint32_t opcode,
     env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
     if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-        float_invalid_op_addsub(env, 1, GETPC(),
-                                float128_classify(xa->f128) |
-                                float128_classify(xb->f128));
+        float_invalid_op_addsub(env, tstat.float_exception_flags, 1, GETPC());
     }
 
     helper_compute_fprf_float128(env, t.f128);
@@ -3278,9 +3270,7 @@ void helper_xssubqp(CPUPPCState *env, uint32_t opcode,
     env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
     if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-        float_invalid_op_addsub(env, 1, GETPC(),
-                                float128_classify(xa->f128) |
-                                float128_classify(xb->f128));
+        float_invalid_op_addsub(env, tstat.float_exception_flags, 1, GETPC());
     }
 
     helper_compute_fprf_float128(env, t.f128);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 09/35] target/ppc: Update float_invalid_op_mul for new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (7 preceding siblings ...)
  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 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 10/35] target/ppc: Update float_invalid_op_div " Richard Henderson
                   ` (28 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Now that vximz and vxsnan are computed directly by
softfloat, we don't need to recompute it via classes.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 26 ++++++++++----------------
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index f0deada84b..23264e6528 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -486,13 +486,12 @@ float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2)
     return ret;
 }
 
-static void float_invalid_op_mul(CPUPPCState *env, bool set_fprc,
-                                 uintptr_t retaddr, int classes)
+static void float_invalid_op_mul(CPUPPCState *env, int flags,
+                                 bool set_fprc, uintptr_t retaddr)
 {
-    if ((classes & (is_zero | is_inf)) == (is_zero | is_inf)) {
-        /* Multiplication of zero by infinity */
+    if (flags & float_flag_invalid_imz) {
         float_invalid_op_vximz(env, set_fprc, retaddr);
-    } else if (classes & is_snan) {
+    } else if (flags & float_flag_invalid_snan) {
         float_invalid_op_vxsnan(env, retaddr);
     }
 }
@@ -501,12 +500,10 @@ static void float_invalid_op_mul(CPUPPCState *env, bool set_fprc,
 float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2)
 {
     float64 ret = float64_mul(arg1, arg2, &env->fp_status);
-    int status = get_float_exception_flags(&env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    if (unlikely(status & float_flag_invalid)) {
-        float_invalid_op_mul(env, 1, GETPC(),
-                             float64_classify(arg1) |
-                             float64_classify(arg2));
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_mul(env, flags, 1, GETPC());
     }
 
     return ret;
@@ -1687,9 +1684,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,                            \
         env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
                                                                              \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
-            float_invalid_op_mul(env, sfprf, GETPC(),                        \
-                                 tp##_classify(xa->fld) |                    \
-                                 tp##_classify(xb->fld));                    \
+            float_invalid_op_mul(env, tstat.float_exception_flags,           \
+                                 sfprf, GETPC());                            \
         }                                                                    \
                                                                              \
         if (r2sp) {                                                          \
@@ -1727,9 +1723,7 @@ void helper_xsmulqp(CPUPPCState *env, uint32_t opcode,
     env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
     if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-        float_invalid_op_mul(env, 1, GETPC(),
-                             float128_classify(xa->f128) |
-                             float128_classify(xb->f128));
+        float_invalid_op_mul(env, tstat.float_exception_flags, 1, GETPC());
     }
     helper_compute_fprf_float128(env, t.f128);
 
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 10/35] target/ppc: Update float_invalid_op_div for new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (8 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 09/35] target/ppc: Update float_invalid_op_mul " Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 11/35] target/ppc: Move float_check_status from FPU_FCTI to translate Richard Henderson
                   ` (27 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Now that vxidi, vxzdz, and vxsnan are computed directly by
softfloat, we don't need to recompute it via classes.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 38 ++++++++++++++------------------------
 1 file changed, 14 insertions(+), 24 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 23264e6528..2ab34236a3 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -509,17 +509,14 @@ float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2)
     return ret;
 }
 
-static void float_invalid_op_div(CPUPPCState *env, bool set_fprc,
-                                 uintptr_t retaddr, int classes)
+static void float_invalid_op_div(CPUPPCState *env, int flags,
+                                 bool set_fprc, uintptr_t retaddr)
 {
-    classes &= ~is_neg;
-    if (classes == is_inf) {
-        /* Division of infinity by infinity */
+    if (flags & float_flag_invalid_idi) {
         float_invalid_op_vxidi(env, set_fprc, retaddr);
-    } else if (classes == is_zero) {
-        /* Division of zero by zero */
+    } else if (flags & float_flag_invalid_zdz) {
         float_invalid_op_vxzdz(env, set_fprc, retaddr);
-    } else if (classes & is_snan) {
+    } else if (flags & float_flag_invalid_snan) {
         float_invalid_op_vxsnan(env, retaddr);
     }
 }
@@ -528,17 +525,13 @@ static void float_invalid_op_div(CPUPPCState *env, bool set_fprc,
 float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2)
 {
     float64 ret = float64_div(arg1, arg2, &env->fp_status);
-    int status = get_float_exception_flags(&env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    if (unlikely(status)) {
-        if (status & float_flag_invalid) {
-            float_invalid_op_div(env, 1, GETPC(),
-                                 float64_classify(arg1) |
-                                 float64_classify(arg2));
-        }
-        if (status & float_flag_divbyzero) {
-            float_zero_divide_excp(env, GETPC());
-        }
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_div(env, flags, 1, GETPC());
+    }
+    if (unlikely(flags & float_flag_divbyzero)) {
+        float_zero_divide_excp(env, GETPC());
     }
 
     return ret;
@@ -1755,9 +1748,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,                             \
         env->fp_status.float_exception_flags |= tstat.float_exception_flags;  \
                                                                               \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {     \
-            float_invalid_op_div(env, sfprf, GETPC(),                         \
-                                 tp##_classify(xa->fld) |                     \
-                                 tp##_classify(xb->fld));                     \
+            float_invalid_op_div(env, tstat.float_exception_flags,            \
+                                 sfprf, GETPC());                             \
         }                                                                     \
         if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) {   \
             float_zero_divide_excp(env, GETPC());                             \
@@ -1798,9 +1790,7 @@ void helper_xsdivqp(CPUPPCState *env, uint32_t opcode,
     env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
     if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-        float_invalid_op_div(env, 1, GETPC(),
-                             float128_classify(xa->f128) |
-                             float128_classify(xb->f128));
+        float_invalid_op_div(env, tstat.float_exception_flags, 1, GETPC());
     }
     if (unlikely(tstat.float_exception_flags & float_flag_divbyzero)) {
         float_zero_divide_excp(env, GETPC());
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 11/35] target/ppc: Move float_check_status from FPU_FCTI to translate
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (9 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 10/35] target/ppc: Update float_invalid_op_div " Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 12/35] target/ppc: Update float_invalid_cvt for new flags Richard Henderson
                   ` (26 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Fixes a bug in which e.g XE enabled causes inexact to be raised
before the writeback to the architectural register.

All of the users of GEN_FLOAT_B either set set_fprf, or are one
of the convert-to-integer instructions that require this behaviour.
Split out the two gen_helper_* calls in gen_compute_fprf_float64
and protect only the first with set_fprf.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c            | 9 +++------
 target/ppc/translate/fp-impl.c.inc | 3 ++-
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 2ab34236a3..0d58fd82a6 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -552,12 +552,9 @@ uint64_t helper_##op(CPUPPCState *env, float64 arg)                    \
     uint64_t ret = float64_to_##cvt(arg, &env->fp_status);             \
     int status = get_float_exception_flags(&env->fp_status);           \
                                                                        \
-    if (unlikely(status)) {                                            \
-        if (status & float_flag_invalid) {                             \
-            float_invalid_cvt(env, 1, GETPC(), float64_classify(arg)); \
-            ret = nanval;                                              \
-        }                                                              \
-        do_float_check_status(env, GETPC());                           \
+    if (unlikely(status & float_flag_invalid)) {                       \
+        float_invalid_cvt(env, 1, GETPC(), float64_classify(arg));     \
+        ret = nanval;                                                  \
     }                                                                  \
     return ret;                                                        \
 }
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index c9e05201d9..aad97a12e8 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -157,8 +157,9 @@ static void gen_f##name(DisasContext *ctx)                                    \
     gen_helper_f##name(t1, cpu_env, t0);                                      \
     set_fpr(rD(ctx->opcode), t1);                                             \
     if (set_fprf) {                                                           \
-        gen_compute_fprf_float64(t1);                                         \
+        gen_helper_compute_fprf_float64(cpu_env, t1);                         \
     }                                                                         \
+    gen_helper_float_check_status(cpu_env);                                   \
     if (unlikely(Rc(ctx->opcode) != 0)) {                                     \
         gen_set_cr1_from_fpscr(ctx);                                          \
     }                                                                         \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 12/35] target/ppc: Update float_invalid_cvt for new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (10 preceding siblings ...)
  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 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 13/35] target/ppc: Fix VXCVI return value Richard Henderson
                   ` (25 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Now that vxsnan is computed directly by softfloat,
we don't need to recompute it via classes.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 0d58fd82a6..6b8367a105 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -537,11 +537,11 @@ float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2)
     return ret;
 }
 
-static void float_invalid_cvt(CPUPPCState *env, bool set_fprc,
-                              uintptr_t retaddr, int class1)
+static void float_invalid_cvt(CPUPPCState *env, int flags,
+                              bool set_fprc, uintptr_t retaddr)
 {
     float_invalid_op_vxcvi(env, set_fprc, retaddr);
-    if (class1 & is_snan) {
+    if (flags & float_flag_invalid_snan) {
         float_invalid_op_vxsnan(env, retaddr);
     }
 }
@@ -550,10 +550,10 @@ static void float_invalid_cvt(CPUPPCState *env, bool set_fprc,
 uint64_t helper_##op(CPUPPCState *env, float64 arg)                    \
 {                                                                      \
     uint64_t ret = float64_to_##cvt(arg, &env->fp_status);             \
-    int status = get_float_exception_flags(&env->fp_status);           \
+    int flags = get_float_exception_flags(&env->fp_status);            \
                                                                        \
-    if (unlikely(status & float_flag_invalid)) {                       \
-        float_invalid_cvt(env, 1, GETPC(), float64_classify(arg));     \
+    if (unlikely(flags & float_flag_invalid)) {                        \
+        float_invalid_cvt(env, flags, 1, GETPC());                     \
         ret = nanval;                                                  \
     }                                                                  \
     return ret;                                                        \
@@ -2746,7 +2746,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)             \
         t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status);  \
         flags = env->fp_status.float_exception_flags;                        \
         if (unlikely(flags & float_flag_invalid)) {                          \
-            float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb->sfld));    \
+            float_invalid_cvt(env, flags, 0, GETPC());                       \
             t.tfld = rnan;                                                   \
         }                                                                    \
         all_flags |= flags;                                                  \
@@ -2789,10 +2789,12 @@ void helper_##op(CPUPPCState *env, uint32_t opcode,                          \
                  ppc_vsr_t *xt, ppc_vsr_t *xb)                               \
 {                                                                            \
     ppc_vsr_t t = { };                                                       \
+    int flags;                                                               \
                                                                              \
     t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status);      \
-    if (env->fp_status.float_exception_flags & float_flag_invalid) {         \
-        float_invalid_cvt(env, 0, GETPC(), stp##_classify(xb->sfld));        \
+    flags = get_float_exception_flags(&env->fp_status);                      \
+    if (flags & float_flag_invalid) {                                        \
+        float_invalid_cvt(env, flags, 0, GETPC());                           \
         t.tfld = rnan;                                                       \
     }                                                                        \
                                                                              \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 13/35] target/ppc: Fix VXCVI return value
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (11 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 12/35] target/ppc: Update float_invalid_cvt for new flags Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 14/35] target/ppc: Remove inline from do_fri Richard Henderson
                   ` (24 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

We were returning nanval for any instance of invalid being set,
but that is an incorrect for VXCVI.  This failure can be seen
in the float_convs tests.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 6b8367a105..ee1047d7e5 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -537,13 +537,20 @@ float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2)
     return ret;
 }
 
-static void float_invalid_cvt(CPUPPCState *env, int flags,
-                              bool set_fprc, uintptr_t retaddr)
+static uint64_t float_invalid_cvt(CPUPPCState *env, int flags,
+                                  uint64_t ret, uint64_t ret_nan,
+                                  bool set_fprc, uintptr_t retaddr)
 {
-    float_invalid_op_vxcvi(env, set_fprc, retaddr);
+    /*
+     * VXCVI is different from most in that it sets two exception bits,
+     * VXCVI and VXSNAN for an SNaN input.
+     */
     if (flags & float_flag_invalid_snan) {
-        float_invalid_op_vxsnan(env, retaddr);
+        env->fpscr |= FP_VXSNAN;
     }
+    float_invalid_op_vxcvi(env, set_fprc, retaddr);
+
+    return flags & float_flag_invalid_cvti ? ret : ret_nan;
 }
 
 #define FPU_FCTI(op, cvt, nanval)                                      \
@@ -551,10 +558,8 @@ uint64_t helper_##op(CPUPPCState *env, float64 arg)                    \
 {                                                                      \
     uint64_t ret = float64_to_##cvt(arg, &env->fp_status);             \
     int flags = get_float_exception_flags(&env->fp_status);            \
-                                                                       \
     if (unlikely(flags & float_flag_invalid)) {                        \
-        float_invalid_cvt(env, flags, 1, GETPC());                     \
-        ret = nanval;                                                  \
+        ret = float_invalid_cvt(env, flags, ret, nanval, 1, GETPC());  \
     }                                                                  \
     return ret;                                                        \
 }
@@ -2746,8 +2751,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)             \
         t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status);  \
         flags = env->fp_status.float_exception_flags;                        \
         if (unlikely(flags & float_flag_invalid)) {                          \
-            float_invalid_cvt(env, flags, 0, GETPC());                       \
-            t.tfld = rnan;                                                   \
+            t.tfld = float_invalid_cvt(env, flags, t.tfld, rnan, 0, GETPC());\
         }                                                                    \
         all_flags |= flags;                                                  \
     }                                                                        \
@@ -2794,8 +2798,7 @@ void helper_##op(CPUPPCState *env, uint32_t opcode,                          \
     t.tfld = stp##_to_##ttp##_round_to_zero(xb->sfld, &env->fp_status);      \
     flags = get_float_exception_flags(&env->fp_status);                      \
     if (flags & float_flag_invalid) {                                        \
-        float_invalid_cvt(env, flags, 0, GETPC());                           \
-        t.tfld = rnan;                                                       \
+        t.tfld = float_invalid_cvt(env, flags, t.tfld, rnan, 0, GETPC());    \
     }                                                                        \
                                                                              \
     *xt = t;                                                                 \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 14/35] target/ppc: Remove inline from do_fri
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (12 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 13/35] target/ppc: Fix VXCVI return value Richard Henderson
@ 2021-11-19 16:04 ` 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
                   ` (23 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

There's no reason the callers can't tail call to one function.
Leave it up to the compiler either way.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index ee1047d7e5..9439dd7f21 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -593,8 +593,8 @@ FPU_FCFI(fcfids, int64_to_float32, 1)
 FPU_FCFI(fcfidu, uint64_to_float64, 0)
 FPU_FCFI(fcfidus, uint64_to_float32, 1)
 
-static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg,
-                              int rounding_mode)
+static uint64_t do_fri(CPUPPCState *env, uint64_t arg,
+                       int rounding_mode)
 {
     CPU_DoubleU farg;
     FloatRoundMode old_rounding_mode = get_float_rounding_mode(&env->fp_status);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 15/35] target/ppc: Use FloatRoundMode in do_fri
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (13 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 14/35] target/ppc: Remove inline from do_fri Richard Henderson
@ 2021-11-19 16:04 ` 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
                   ` (22 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

This is the proper type for the enumeration.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 9439dd7f21..535002741a 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -594,7 +594,7 @@ FPU_FCFI(fcfidu, uint64_to_float64, 0)
 FPU_FCFI(fcfidus, uint64_to_float32, 1)
 
 static uint64_t do_fri(CPUPPCState *env, uint64_t arg,
-                       int rounding_mode)
+                       FloatRoundMode rounding_mode)
 {
     CPU_DoubleU farg;
     FloatRoundMode old_rounding_mode = get_float_rounding_mode(&env->fp_status);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 16/35] target/ppc: Tidy inexact handling in do_fri
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (14 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 15/35] target/ppc: Use FloatRoundMode in do_fri Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 17/35] target/ppc: Clean up do_fri Richard Henderson
                   ` (21 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

In GEN_FLOAT_B, we called helper_reset_fpstatus immediately
before calling helper_fri*.  Therefore get_float_exception_flags
is known to be zero, and this code can be simplified.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 535002741a..ec0288df01 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -606,16 +606,12 @@ static uint64_t do_fri(CPUPPCState *env, uint64_t arg,
         float_invalid_op_vxsnan(env, GETPC());
         farg.ll = arg | 0x0008000000000000ULL;
     } else {
-        int inexact = get_float_exception_flags(&env->fp_status) &
-                      float_flag_inexact;
         set_float_rounding_mode(rounding_mode, &env->fp_status);
         farg.ll = float64_round_to_int(farg.d, &env->fp_status);
         set_float_rounding_mode(old_rounding_mode, &env->fp_status);
 
         /* fri* does not set FPSCR[XX] */
-        if (!inexact) {
-            env->fp_status.float_exception_flags &= ~float_flag_inexact;
-        }
+        env->fp_status.float_exception_flags &= ~float_flag_inexact;
     }
     do_float_check_status(env, GETPC());
     return farg.ll;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 17/35] target/ppc: Clean up do_fri
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (15 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 16/35] target/ppc: Tidy inexact handling " Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 18/35] target/ppc: Update fmadd for new flags Richard Henderson
                   ` (20 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Let float64_round_to_int detect and silence snans.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 24 +++++++++++-------------
 1 file changed, 11 insertions(+), 13 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index ec0288df01..3a462e5596 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -596,25 +596,23 @@ FPU_FCFI(fcfidus, uint64_to_float32, 1)
 static uint64_t do_fri(CPUPPCState *env, uint64_t arg,
                        FloatRoundMode rounding_mode)
 {
-    CPU_DoubleU farg;
     FloatRoundMode old_rounding_mode = get_float_rounding_mode(&env->fp_status);
+    int flags;
 
-    farg.ll = arg;
+    set_float_rounding_mode(rounding_mode, &env->fp_status);
+    arg = float64_round_to_int(arg, &env->fp_status);
+    set_float_rounding_mode(old_rounding_mode, &env->fp_status);
 
-    if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
-        /* sNaN round */
+    flags = get_float_exception_flags(&env->fp_status);
+    if (flags & float_flag_invalid_snan) {
         float_invalid_op_vxsnan(env, GETPC());
-        farg.ll = arg | 0x0008000000000000ULL;
-    } else {
-        set_float_rounding_mode(rounding_mode, &env->fp_status);
-        farg.ll = float64_round_to_int(farg.d, &env->fp_status);
-        set_float_rounding_mode(old_rounding_mode, &env->fp_status);
-
-        /* fri* does not set FPSCR[XX] */
-        env->fp_status.float_exception_flags &= ~float_flag_inexact;
     }
+
+    /* fri* does not set FPSCR[XX] */
+    set_float_exception_flags(flags & ~float_flag_inexact, &env->fp_status);
     do_float_check_status(env, GETPC());
-    return farg.ll;
+
+    return arg;
 }
 
 uint64_t helper_frin(CPUPPCState *env, uint64_t arg)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 18/35] target/ppc: Update fmadd for new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (16 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 17/35] target/ppc: Clean up do_fri Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 19/35] target/ppc: Split out do_fmadd Richard Henderson
                   ` (19 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Now that vximz, vxisi, and vxsnan are computed directly by
softfloat, we don't need to recompute it.  This replaces the
separate float{32,64}_maddsub_update_excp functions with a
single float_invalid_op_madd function.

Fix VSX_MADD by passing sfprf to float_invalid_op_madd,
whereas the previous *_maddsub_update_excp assumed it true.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 46 ++++++++++-------------------------------
 1 file changed, 11 insertions(+), 35 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 3a462e5596..fdf06f6dc5 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -635,38 +635,15 @@ uint64_t helper_frim(CPUPPCState *env, uint64_t arg)
     return do_fri(env, arg, float_round_down);
 }
 
-#define FPU_MADDSUB_UPDATE(NAME, TP)                                    \
-static void NAME(CPUPPCState *env, TP arg1, TP arg2, TP arg3,           \
-                 unsigned int madd_flags, uintptr_t retaddr)            \
-{                                                                       \
-    if (TP##_is_signaling_nan(arg1, &env->fp_status) ||                 \
-        TP##_is_signaling_nan(arg2, &env->fp_status) ||                 \
-        TP##_is_signaling_nan(arg3, &env->fp_status)) {                 \
-        /* sNaN operation */                                            \
-        float_invalid_op_vxsnan(env, retaddr);                          \
-    }                                                                   \
-    if ((TP##_is_infinity(arg1) && TP##_is_zero(arg2)) ||               \
-        (TP##_is_zero(arg1) && TP##_is_infinity(arg2))) {               \
-        /* Multiplication of zero by infinity */                        \
-        float_invalid_op_vximz(env, 1, retaddr);                        \
-    }                                                                   \
-    if ((TP##_is_infinity(arg1) || TP##_is_infinity(arg2)) &&           \
-        TP##_is_infinity(arg3)) {                                       \
-        uint8_t aSign, bSign, cSign;                                    \
-                                                                        \
-        aSign = TP##_is_neg(arg1);                                      \
-        bSign = TP##_is_neg(arg2);                                      \
-        cSign = TP##_is_neg(arg3);                                      \
-        if (madd_flags & float_muladd_negate_c) {                       \
-            cSign ^= 1;                                                 \
-        }                                                               \
-        if (aSign ^ bSign ^ cSign) {                                    \
-            float_invalid_op_vxisi(env, 1, retaddr);                    \
-        }                                                               \
-    }                                                                   \
+static void float_invalid_op_madd(CPUPPCState *env, int flags,
+                                  bool set_fpcc, uintptr_t retaddr)
+{
+    if (flags & float_flag_invalid_imz) {
+        float_invalid_op_vximz(env, set_fpcc, retaddr);
+    } else {
+        float_invalid_op_addsub(env, flags, set_fpcc, retaddr);
+    }
 }
-FPU_MADDSUB_UPDATE(float32_maddsub_update_excp, float32)
-FPU_MADDSUB_UPDATE(float64_maddsub_update_excp, float64)
 
 #define FPU_FMADD(op, madd_flags)                                       \
 uint64_t helper_##op(CPUPPCState *env, uint64_t arg1,                   \
@@ -678,8 +655,7 @@ uint64_t helper_##op(CPUPPCState *env, uint64_t arg1,                   \
     flags = get_float_exception_flags(&env->fp_status);                 \
     if (flags) {                                                        \
         if (flags & float_flag_invalid) {                               \
-            float64_maddsub_update_excp(env, arg1, arg2, arg3,          \
-                                        madd_flags, GETPC());           \
+            float_invalid_op_madd(env, flags, 1, GETPC());              \
         }                                                               \
         do_float_check_status(env, GETPC());                            \
     }                                                                   \
@@ -2083,8 +2059,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,                             \
         env->fp_status.float_exception_flags |= tstat.float_exception_flags;  \
                                                                               \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {     \
-            tp##_maddsub_update_excp(env, xa->fld, b->fld,                    \
-                                     c->fld, maddflgs, GETPC());              \
+            float_invalid_op_madd(env, tstat.float_exception_flags,           \
+                                  sfprf, GETPC());                            \
         }                                                                     \
                                                                               \
         if (r2sp) {                                                           \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 19/35] target/ppc: Split out do_fmadd
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (17 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 18/35] target/ppc: Update fmadd for new flags Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 20/35] target/ppc: Do not call do_float_check_status from do_fmadd Richard Henderson
                   ` (18 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Create a common function for all of the madd helpers.
Let the compiler tail call or inline as it chooses.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 33 ++++++++++++++++++---------------
 1 file changed, 18 insertions(+), 15 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index fdf06f6dc5..d2a7bf5e63 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -645,23 +645,26 @@ static void float_invalid_op_madd(CPUPPCState *env, int flags,
     }
 }
 
-#define FPU_FMADD(op, madd_flags)                                       \
-uint64_t helper_##op(CPUPPCState *env, uint64_t arg1,                   \
-                     uint64_t arg2, uint64_t arg3)                      \
-{                                                                       \
-    uint32_t flags;                                                     \
-    float64 ret = float64_muladd(arg1, arg2, arg3, madd_flags,          \
-                                 &env->fp_status);                      \
-    flags = get_float_exception_flags(&env->fp_status);                 \
-    if (flags) {                                                        \
-        if (flags & float_flag_invalid) {                               \
-            float_invalid_op_madd(env, flags, 1, GETPC());              \
-        }                                                               \
-        do_float_check_status(env, GETPC());                            \
-    }                                                                   \
-    return ret;                                                         \
+static float64 do_fmadd(CPUPPCState *env, float64 a, float64 b,
+                         float64 c, int madd_flags, uintptr_t retaddr)
+{
+    float64 ret = float64_muladd(a, b, c, madd_flags, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
+
+    if (flags) {
+        if (flags & float_flag_invalid) {
+            float_invalid_op_madd(env, flags, 1, retaddr);
+        }
+        do_float_check_status(env, retaddr);
+    }
+    return ret;
 }
 
+#define FPU_FMADD(op, madd_flags)                                    \
+    uint64_t helper_##op(CPUPPCState *env, uint64_t arg1,            \
+                         uint64_t arg2, uint64_t arg3)               \
+    { return do_fmadd(env, arg1, arg2, arg3, madd_flags, GETPC()); }
+
 #define MADD_FLGS 0
 #define MSUB_FLGS float_muladd_negate_c
 #define NMADD_FLGS float_muladd_negate_result
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 20/35] target/ppc: Do not call do_float_check_status from do_fmadd
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (18 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 19/35] target/ppc: Split out do_fmadd Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 21/35] target/ppc: Split out do_frsp Richard Henderson
                   ` (17 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

We will process flags other than in valid in helper_float_check_status,
which is invoked after the writeback to FRT.
Fixes a bug in which FRT is not written when OE/UE/XE are enabled.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 7 ++-----
 1 file changed, 2 insertions(+), 5 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index d2a7bf5e63..e0c35a3977 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -651,11 +651,8 @@ static float64 do_fmadd(CPUPPCState *env, float64 a, float64 b,
     float64 ret = float64_muladd(a, b, c, madd_flags, &env->fp_status);
     int flags = get_float_exception_flags(&env->fp_status);
 
-    if (flags) {
-        if (flags & float_flag_invalid) {
-            float_invalid_op_madd(env, flags, 1, retaddr);
-        }
-        do_float_check_status(env, retaddr);
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_madd(env, flags, 1, retaddr);
     }
     return ret;
 }
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 21/35] target/ppc: Split out do_frsp
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (19 preceding siblings ...)
  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 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 22/35] target/ppc: Update do_frsp for new flags Richard Henderson
                   ` (16 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Calling helper_frsp directly from other helpers generates
the incorrect retaddr.  Split out a helper that takes the
retaddr as a parameter.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 27 ++++++++++++++++-----------
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index e0c35a3977..e91a6b0212 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -673,7 +673,7 @@ FPU_FMADD(fmsub, MSUB_FLGS)
 FPU_FMADD(fnmsub, NMSUB_FLGS)
 
 /* frsp - frsp. */
-uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
+static uint64_t do_frsp(CPUPPCState *env, uint64_t arg, uintptr_t retaddr)
 {
     CPU_DoubleU farg;
     float32 f32;
@@ -681,7 +681,7 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
     farg.ll = arg;
 
     if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
-        float_invalid_op_vxsnan(env, GETPC());
+        float_invalid_op_vxsnan(env, retaddr);
     }
     f32 = float64_to_float32(farg.d, &env->fp_status);
     farg.d = float32_to_float64(f32, &env->fp_status);
@@ -689,6 +689,11 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
     return farg.ll;
 }
 
+uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
+{
+    return do_frsp(env, arg, GETPC());
+}
+
 /* fsqrt - fsqrt. */
 float64 helper_fsqrt(CPUPPCState *env, float64 arg)
 {
@@ -1578,7 +1583,7 @@ void helper_##name(CPUPPCState *env, ppc_vsr_t *xt,                          \
         }                                                                    \
                                                                              \
         if (r2sp) {                                                          \
-            t.fld = helper_frsp(env, t.fld);                                 \
+            t.fld = do_frsp(env, t.fld, GETPC());                            \
         }                                                                    \
                                                                              \
         if (sfprf) {                                                         \
@@ -1654,7 +1659,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,                            \
         }                                                                    \
                                                                              \
         if (r2sp) {                                                          \
-            t.fld = helper_frsp(env, t.fld);                                 \
+            t.fld = do_frsp(env, t.fld, GETPC());                            \
         }                                                                    \
                                                                              \
         if (sfprf) {                                                         \
@@ -1728,7 +1733,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,                             \
         }                                                                     \
                                                                               \
         if (r2sp) {                                                           \
-            t.fld = helper_frsp(env, t.fld);                                  \
+            t.fld = do_frsp(env, t.fld, GETPC());                             \
         }                                                                     \
                                                                               \
         if (sfprf) {                                                          \
@@ -1796,7 +1801,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)              \
         t.fld = tp##_div(tp##_one, xb->fld, &env->fp_status);                 \
                                                                               \
         if (r2sp) {                                                           \
-            t.fld = helper_frsp(env, t.fld);                                  \
+            t.fld = do_frsp(env, t.fld, GETPC());                             \
         }                                                                     \
                                                                               \
         if (sfprf) {                                                          \
@@ -1844,7 +1849,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)             \
         }                                                                    \
                                                                              \
         if (r2sp) {                                                          \
-            t.fld = helper_frsp(env, t.fld);                                 \
+            t.fld = do_frsp(env, t.fld, GETPC());                            \
         }                                                                    \
                                                                              \
         if (sfprf) {                                                         \
@@ -1893,7 +1898,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)             \
         }                                                                    \
                                                                              \
         if (r2sp) {                                                          \
-            t.fld = helper_frsp(env, t.fld);                                 \
+            t.fld = do_frsp(env, t.fld, GETPC());                            \
         }                                                                    \
                                                                              \
         if (sfprf) {                                                         \
@@ -2064,7 +2069,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt,                             \
         }                                                                     \
                                                                               \
         if (r2sp) {                                                           \
-            t.fld = helper_frsp(env, t.fld);                                  \
+            t.fld = do_frsp(env, t.fld, GETPC());                             \
         }                                                                     \
                                                                               \
         if (sfprf) {                                                          \
@@ -2803,7 +2808,7 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)        \
     for (i = 0; i < nels; i++) {                                        \
         t.tfld = stp##_to_##ttp(xb->sfld, &env->fp_status);             \
         if (r2sp) {                                                     \
-            t.tfld = helper_frsp(env, t.tfld);                          \
+            t.tfld = do_frsp(env, t.tfld, GETPC());                     \
         }                                                               \
         if (sfprf) {                                                    \
             helper_compute_fprf_float64(env, t.tfld);                   \
@@ -2928,7 +2933,7 @@ uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb)
 {
     helper_reset_fpstatus(env);
 
-    uint64_t xt = helper_frsp(env, xb);
+    uint64_t xt = do_frsp(env, xb, GETPC());
 
     helper_compute_fprf_float64(env, xt);
     do_float_check_status(env, GETPC());
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 22/35] target/ppc: Update do_frsp for new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (20 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 21/35] target/ppc: Split out do_frsp Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 23/35] target/ppc: Use helper_todouble in do_frsp Richard Henderson
                   ` (15 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Now that vxsnan is computed directly by softfloat,
we don't need to recompute it.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 13 ++++---------
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index e91a6b0212..38f20e9783 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -675,18 +675,13 @@ FPU_FMADD(fnmsub, NMSUB_FLGS)
 /* frsp - frsp. */
 static uint64_t do_frsp(CPUPPCState *env, uint64_t arg, uintptr_t retaddr)
 {
-    CPU_DoubleU farg;
-    float32 f32;
+    float32 f32 = float64_to_float32(arg, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    farg.ll = arg;
-
-    if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
+    if (unlikely(flags & float_flag_invalid_snan)) {
         float_invalid_op_vxsnan(env, retaddr);
     }
-    f32 = float64_to_float32(farg.d, &env->fp_status);
-    farg.d = float32_to_float64(f32, &env->fp_status);
-
-    return farg.ll;
+    return float32_to_float64(f32, &env->fp_status);
 }
 
 uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 23/35] target/ppc: Use helper_todouble in do_frsp
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (21 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 22/35] target/ppc: Update do_frsp for new flags Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 24/35] target/ppc: Update sqrt for new flags Richard Henderson
                   ` (14 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

We only needed one ieee arithmetic operation to raise
exceptions.  To convert back to register form, we can
use our simpler non-arithmetic function.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 38f20e9783..3a29a994d3 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -681,7 +681,7 @@ static uint64_t do_frsp(CPUPPCState *env, uint64_t arg, uintptr_t retaddr)
     if (unlikely(flags & float_flag_invalid_snan)) {
         float_invalid_op_vxsnan(env, retaddr);
     }
-    return float32_to_float64(f32, &env->fp_status);
+    return helper_todouble(f32);
 }
 
 uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 24/35] target/ppc: Update sqrt for new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (22 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 23/35] target/ppc: Use helper_todouble in do_frsp Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 25/35] target/ppc: Update xsrqpi and xsrqpxp to " Richard Henderson
                   ` (13 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Now that vxsqrt and vxsnan are computed directly by softfloat,
we don't need to recompute it.  Split out float_invalid_op_sqrt
to be used in several places.  This fixes VSX_SQRT, which did
not order its tests correctly to eliminate NaN with sign set.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 72 ++++++++++++++---------------------------
 1 file changed, 25 insertions(+), 47 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 3a29a994d3..f17d5a1af1 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -689,22 +689,24 @@ uint64_t helper_frsp(CPUPPCState *env, uint64_t arg)
     return do_frsp(env, arg, GETPC());
 }
 
+static void float_invalid_op_sqrt(CPUPPCState *env, int flags,
+                                  bool set_fpcc, uintptr_t retaddr)
+{
+    if (unlikely(flags & float_flag_invalid_sqrt)) {
+        float_invalid_op_vxsqrt(env, set_fpcc, retaddr);
+    } else if (unlikely(flags & float_flag_invalid_snan)) {
+        float_invalid_op_vxsnan(env, retaddr);
+    }
+}
+
 /* fsqrt - fsqrt. */
 float64 helper_fsqrt(CPUPPCState *env, float64 arg)
 {
     float64 ret = float64_sqrt(arg, &env->fp_status);
-    int status = get_float_exception_flags(&env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    if (unlikely(status & float_flag_invalid)) {
-        if (unlikely(float64_is_any_nan(arg))) {
-            if (unlikely(float64_is_signaling_nan(arg, &env->fp_status))) {
-                /* sNaN square root */
-                float_invalid_op_vxsnan(env, GETPC());
-            }
-        } else {
-            /* Square root of a negative nonzero number */
-            float_invalid_op_vxsqrt(env, 1, GETPC());
-        }
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_sqrt(env, flags, 1, GETPC());
     }
 
     return ret;
@@ -759,22 +761,14 @@ float64 helper_frsqrte(CPUPPCState *env, float64 arg)
     /* "Estimate" the reciprocal with actual division.  */
     float64 rets = float64_sqrt(arg, &env->fp_status);
     float64 retd = float64_div(float64_one, rets, &env->fp_status);
-    int status = get_float_exception_flags(&env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    if (unlikely(status)) {
-        if (status & float_flag_invalid) {
-            if (float64_is_signaling_nan(arg, &env->fp_status)) {
-                /* sNaN reciprocal */
-                float_invalid_op_vxsnan(env, GETPC());
-            } else {
-                /* Square root of a negative nonzero number */
-                float_invalid_op_vxsqrt(env, 1, GETPC());
-            }
-        }
-        if (status & float_flag_divbyzero) {
-            /* Reciprocal of (square root of) zero.  */
-            float_zero_divide_excp(env, GETPC());
-        }
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_sqrt(env, flags, 1, GETPC());
+    }
+    if (unlikely(flags & float_flag_divbyzero)) {
+        /* Reciprocal of (square root of) zero.  */
+        float_zero_divide_excp(env, GETPC());
     }
 
     return retd;
@@ -1836,11 +1830,8 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)             \
         env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
                                                                              \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
-            if (tp##_is_neg(xb->fld) && !tp##_is_zero(xb->fld)) {            \
-                float_invalid_op_vxsqrt(env, sfprf, GETPC());                \
-            } else if (tp##_is_signaling_nan(xb->fld, &tstat)) {             \
-                float_invalid_op_vxsnan(env, GETPC());                       \
-            }                                                                \
+            float_invalid_op_sqrt(env, tstat.float_exception_flags,          \
+                                  sfprf, GETPC());                           \
         }                                                                    \
                                                                              \
         if (r2sp) {                                                          \
@@ -1883,15 +1874,10 @@ void helper_##op(CPUPPCState *env, ppc_vsr_t *xt, ppc_vsr_t *xb)             \
         t.fld = tp##_sqrt(xb->fld, &tstat);                                  \
         t.fld = tp##_div(tp##_one, t.fld, &tstat);                           \
         env->fp_status.float_exception_flags |= tstat.float_exception_flags; \
-                                                                             \
         if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {    \
-            if (tp##_is_neg(xb->fld) && !tp##_is_zero(xb->fld)) {            \
-                float_invalid_op_vxsqrt(env, sfprf, GETPC());                \
-            } else if (tp##_is_signaling_nan(xb->fld, &tstat)) {             \
-                float_invalid_op_vxsnan(env, GETPC());                       \
-            }                                                                \
+            float_invalid_op_sqrt(env, tstat.float_exception_flags,          \
+                                  sfprf, GETPC());                           \
         }                                                                    \
-                                                                             \
         if (r2sp) {                                                          \
             t.fld = do_frsp(env, t.fld, GETPC());                            \
         }                                                                    \
@@ -3192,15 +3178,7 @@ void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode,
     env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
     if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-        if (float128_is_signaling_nan(xb->f128, &tstat)) {
-            float_invalid_op_vxsnan(env, GETPC());
-            t.f128 = float128_snan_to_qnan(xb->f128);
-        } else if (float128_is_quiet_nan(xb->f128, &tstat)) {
-            t.f128 = xb->f128;
-        } else if (float128_is_neg(xb->f128) && !float128_is_zero(xb->f128)) {
-            float_invalid_op_vxsqrt(env, 1, GETPC());
-            t.f128 = float128_default_nan(&env->fp_status);
-        }
+        float_invalid_op_sqrt(env, tstat.float_exception_flags, 1, GETPC());
     }
 
     helper_compute_fprf_float128(env, t.f128);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 25/35] target/ppc: Update xsrqpi and xsrqpxp to new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (23 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 24/35] target/ppc: Update sqrt for new flags Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 26/35] target/ppc: Update fre " Richard Henderson
                   ` (12 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Use float_flag_invalid_snan instead of recomputing
the snan-ness of the operand.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index f17d5a1af1..f46d529f04 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -3090,11 +3090,8 @@ void helper_xsrqpi(CPUPPCState *env, uint32_t opcode,
     t.f128 = float128_round_to_int(xb->f128, &tstat);
     env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
-    if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-        if (float128_is_signaling_nan(xb->f128, &tstat)) {
-            float_invalid_op_vxsnan(env, GETPC());
-            t.f128 = float128_snan_to_qnan(t.f128);
-        }
+    if (unlikely(tstat.float_exception_flags & float_flag_invalid_snan)) {
+        float_invalid_op_vxsnan(env, GETPC());
     }
 
     if (ex == 0 && (tstat.float_exception_flags & float_flag_inexact)) {
@@ -3148,11 +3145,9 @@ void helper_xsrqpxp(CPUPPCState *env, uint32_t opcode,
     t.f128 = floatx80_to_float128(round_res, &tstat);
     env->fp_status.float_exception_flags |= tstat.float_exception_flags;
 
-    if (unlikely(tstat.float_exception_flags & float_flag_invalid)) {
-        if (float128_is_signaling_nan(xb->f128, &tstat)) {
-            float_invalid_op_vxsnan(env, GETPC());
-            t.f128 = float128_snan_to_qnan(t.f128);
-        }
+    if (unlikely(tstat.float_exception_flags & float_flag_invalid_snan)) {
+        float_invalid_op_vxsnan(env, GETPC());
+        t.f128 = float128_snan_to_qnan(t.f128);
     }
 
     helper_compute_fprf_float128(env, t.f128);
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 26/35] target/ppc: Update fre to new flags
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (24 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 25/35] target/ppc: Update xsrqpi and xsrqpxp to " Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 27/35] softfloat: Add float64r32 arithmetic routines Richard Henderson
                   ` (11 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Use float_flag_invalid_snan instead of recomputing
the snan-ness of the operand.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index f46d529f04..7b4407e189 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -717,20 +717,15 @@ float64 helper_fre(CPUPPCState *env, float64 arg)
 {
     /* "Estimate" the reciprocal with actual division.  */
     float64 ret = float64_div(float64_one, arg, &env->fp_status);
-    int status = get_float_exception_flags(&env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    if (unlikely(status)) {
-        if (status & float_flag_invalid) {
-            if (float64_is_signaling_nan(arg, &env->fp_status)) {
-                /* sNaN reciprocal */
-                float_invalid_op_vxsnan(env, GETPC());
-            }
-        }
-        if (status & float_flag_divbyzero) {
-            float_zero_divide_excp(env, GETPC());
-            /* For FPSCR.ZE == 0, the result is 1/2.  */
-            ret = float64_set_sign(float64_half, float64_is_neg(arg));
-        }
+    if (unlikely(flags & float_flag_invalid_snan)) {
+        float_invalid_op_vxsnan(env, GETPC());
+    }
+    if (unlikely(flags & float_flag_divbyzero)) {
+        float_zero_divide_excp(env, GETPC());
+        /* For FPSCR.ZE == 0, the result is 1/2.  */
+        ret = float64_set_sign(float64_half, float64_is_neg(arg));
     }
 
     return ret;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 27/35] softfloat: Add float64r32 arithmetic routines
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (25 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 26/35] target/ppc: Update fre " Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 28/35] target/ppc: Add helpers for fmadds et al Richard Henderson
                   ` (10 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

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



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 28/35] target/ppc: Add helpers for fmadds et al
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (26 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 27/35] softfloat: Add float64r32 arithmetic routines Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 29/35] target/ppc: Add helper for fsqrts Richard Henderson
                   ` (9 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Use float64r32_muladd.  Fixes a double-rounding issue with performing
the compuation in float64 and then rounding afterward.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/helper.h                |  4 ++++
 target/ppc/fpu_helper.c            | 17 ++++++++++++++++-
 target/ppc/translate/fp-impl.c.inc | 13 +++++--------
 3 files changed, 25 insertions(+), 9 deletions(-)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 627811cefc..ca893e1232 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -100,6 +100,10 @@ DEF_HELPER_4(fmadd, i64, env, i64, i64, i64)
 DEF_HELPER_4(fmsub, i64, env, i64, i64, i64)
 DEF_HELPER_4(fnmadd, i64, env, i64, i64, i64)
 DEF_HELPER_4(fnmsub, i64, env, i64, i64, i64)
+DEF_HELPER_4(fmadds, i64, env, i64, i64, i64)
+DEF_HELPER_4(fmsubs, i64, env, i64, i64, i64)
+DEF_HELPER_4(fnmadds, i64, env, i64, i64, i64)
+DEF_HELPER_4(fnmsubs, i64, env, i64, i64, i64)
 DEF_HELPER_2(fsqrt, f64, env, f64)
 DEF_HELPER_2(fre, i64, env, i64)
 DEF_HELPER_2(fres, i64, env, i64)
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 7b4407e189..5caeed2c45 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -657,10 +657,25 @@ static float64 do_fmadd(CPUPPCState *env, float64 a, float64 b,
     return ret;
 }
 
+static uint64_t do_fmadds(CPUPPCState *env, float64 a, float64 b,
+                          float64 c, int madd_flags, uintptr_t retaddr)
+{
+    float64 ret = float64r32_muladd(a, b, c, madd_flags, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
+
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_madd(env, flags, 1, retaddr);
+    }
+    return ret;
+}
+
 #define FPU_FMADD(op, madd_flags)                                    \
     uint64_t helper_##op(CPUPPCState *env, uint64_t arg1,            \
                          uint64_t arg2, uint64_t arg3)               \
-    { return do_fmadd(env, arg1, arg2, arg3, madd_flags, GETPC()); }
+    { return do_fmadd(env, arg1, arg2, arg3, madd_flags, GETPC()); } \
+    uint64_t helper_##op##s(CPUPPCState *env, uint64_t arg1,         \
+                         uint64_t arg2, uint64_t arg3)               \
+    { return do_fmadds(env, arg1, arg2, arg3, madd_flags, GETPC()); }
 
 #define MADD_FLGS 0
 #define MSUB_FLGS float_muladd_negate_c
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index aad97a12e8..b1af4bef61 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -31,7 +31,7 @@ static void gen_set_cr1_from_fpscr(DisasContext *ctx)
 #endif
 
 /***                       Floating-Point arithmetic                       ***/
-#define _GEN_FLOAT_ACB(name, op, op1, op2, isfloat, set_fprf, type)           \
+#define _GEN_FLOAT_ACB(name, op1, op2, set_fprf, type)                        \
 static void gen_f##name(DisasContext *ctx)                                    \
 {                                                                             \
     TCGv_i64 t0;                                                              \
@@ -50,10 +50,7 @@ static void gen_f##name(DisasContext *ctx)                                    \
     get_fpr(t0, rA(ctx->opcode));                                             \
     get_fpr(t1, rC(ctx->opcode));                                             \
     get_fpr(t2, rB(ctx->opcode));                                             \
-    gen_helper_f##op(t3, cpu_env, t0, t1, t2);                                \
-    if (isfloat) {                                                            \
-        gen_helper_frsp(t3, cpu_env, t3);                                     \
-    }                                                                         \
+    gen_helper_f##name(t3, cpu_env, t0, t1, t2);                              \
     set_fpr(rD(ctx->opcode), t3);                                             \
     if (set_fprf) {                                                           \
         gen_compute_fprf_float64(t3);                                         \
@@ -68,8 +65,8 @@ static void gen_f##name(DisasContext *ctx)                                    \
 }
 
 #define GEN_FLOAT_ACB(name, op2, set_fprf, type)                              \
-_GEN_FLOAT_ACB(name, name, 0x3F, op2, 0, set_fprf, type);                     \
-_GEN_FLOAT_ACB(name##s, name, 0x3B, op2, 1, set_fprf, type);
+_GEN_FLOAT_ACB(name, 0x3F, op2, set_fprf, type);                              \
+_GEN_FLOAT_ACB(name##s, 0x3B, op2, set_fprf, type);
 
 #define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
 static void gen_f##name(DisasContext *ctx)                                    \
@@ -233,7 +230,7 @@ static void gen_frsqrtes(DisasContext *ctx)
 }
 
 /* fsel */
-_GEN_FLOAT_ACB(sel, sel, 0x3F, 0x17, 0, 0, PPC_FLOAT_FSEL);
+_GEN_FLOAT_ACB(sel, 0x3F, 0x17, 0, PPC_FLOAT_FSEL);
 /* fsub - fsubs */
 GEN_FLOAT_AB(sub, 0x14, 0x000007C0, 1, PPC_FLOAT);
 /* Optional: */
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 29/35] target/ppc: Add helper for fsqrts
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (27 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 28/35] target/ppc: Add helpers for fmadds et al Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 30/35] target/ppc: Add helpers for fadds, fsubs, fdivs Richard Henderson
                   ` (8 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Use float64r32_sqrt.  Fixes a double-rounding issue with performing
the compuation in float64 and then rounding afterward.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/helper.h                |  1 +
 target/ppc/fpu_helper.c            | 12 ++++++++++++
 target/ppc/translate/fp-impl.c.inc |  3 +--
 3 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index ca893e1232..a6683dceec 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -105,6 +105,7 @@ DEF_HELPER_4(fmsubs, i64, env, i64, i64, i64)
 DEF_HELPER_4(fnmadds, i64, env, i64, i64, i64)
 DEF_HELPER_4(fnmsubs, i64, env, i64, i64, i64)
 DEF_HELPER_2(fsqrt, f64, env, f64)
+DEF_HELPER_2(fsqrts, f64, env, f64)
 DEF_HELPER_2(fre, i64, env, i64)
 DEF_HELPER_2(fres, i64, env, i64)
 DEF_HELPER_2(frsqrte, i64, env, i64)
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 5caeed2c45..7e275ea134 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -727,6 +727,18 @@ float64 helper_fsqrt(CPUPPCState *env, float64 arg)
     return ret;
 }
 
+/* fsqrts - fsqrts. */
+float64 helper_fsqrts(CPUPPCState *env, float64 arg)
+{
+    float64 ret = float64r32_sqrt(arg, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
+
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_sqrt(env, flags, 1, GETPC());
+    }
+    return ret;
+}
+
 /* fre - fre. */
 float64 helper_fre(CPUPPCState *env, float64 arg)
 {
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index b1af4bef61..898de9fe53 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -270,8 +270,7 @@ static void gen_fsqrts(DisasContext *ctx)
     t1 = tcg_temp_new_i64();
     gen_reset_fpstatus();
     get_fpr(t0, rB(ctx->opcode));
-    gen_helper_fsqrt(t1, cpu_env, t0);
-    gen_helper_frsp(t1, cpu_env, t1);
+    gen_helper_fsqrts(t1, cpu_env, t0);
     set_fpr(rD(ctx->opcode), t1);
     gen_compute_fprf_float64(t1);
     if (unlikely(Rc(ctx->opcode) != 0)) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 30/35] target/ppc: Add helpers for fadds, fsubs, fdivs
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (28 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 29/35] target/ppc: Add helper for fsqrts Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 31/35] target/ppc: Add helper for fmuls Richard Henderson
                   ` (7 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Use float64r32_{add,sub,div}.  Fixes a double-rounding issue with
performing the compuation in float64 and then rounding afterward.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/helper.h                |  3 +++
 target/ppc/fpu_helper.c            | 40 ++++++++++++++++++++++++++++++
 target/ppc/translate/fp-impl.c.inc | 11 +++-----
 3 files changed, 47 insertions(+), 7 deletions(-)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index a6683dceec..f72b547603 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -93,9 +93,12 @@ DEF_HELPER_2(frip, i64, env, i64)
 DEF_HELPER_2(frim, i64, env, i64)
 
 DEF_HELPER_3(fadd, f64, env, f64, f64)
+DEF_HELPER_3(fadds, f64, env, f64, f64)
 DEF_HELPER_3(fsub, f64, env, f64, f64)
+DEF_HELPER_3(fsubs, f64, env, f64, f64)
 DEF_HELPER_3(fmul, f64, env, f64, f64)
 DEF_HELPER_3(fdiv, f64, env, f64, f64)
+DEF_HELPER_3(fdivs, f64, env, f64, f64)
 DEF_HELPER_4(fmadd, i64, env, i64, i64, i64)
 DEF_HELPER_4(fmsub, i64, env, i64, i64, i64)
 DEF_HELPER_4(fnmadd, i64, env, i64, i64, i64)
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 7e275ea134..4048c830e7 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -473,6 +473,18 @@ float64 helper_fadd(CPUPPCState *env, float64 arg1, float64 arg2)
     return ret;
 }
 
+/* fadds - fadds. */
+float64 helper_fadds(CPUPPCState *env, float64 arg1, float64 arg2)
+{
+    float64 ret = float64r32_add(arg1, arg2, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
+
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_addsub(env, flags, 1, GETPC());
+    }
+    return ret;
+}
+
 /* fsub - fsub. */
 float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2)
 {
@@ -486,6 +498,18 @@ float64 helper_fsub(CPUPPCState *env, float64 arg1, float64 arg2)
     return ret;
 }
 
+/* fsubs - fsubs. */
+float64 helper_fsubs(CPUPPCState *env, float64 arg1, float64 arg2)
+{
+    float64 ret = float64r32_sub(arg1, arg2, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
+
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_addsub(env, flags, 1, GETPC());
+    }
+    return ret;
+}
+
 static void float_invalid_op_mul(CPUPPCState *env, int flags,
                                  bool set_fprc, uintptr_t retaddr)
 {
@@ -537,6 +561,22 @@ float64 helper_fdiv(CPUPPCState *env, float64 arg1, float64 arg2)
     return ret;
 }
 
+/* fdivs - fdivs. */
+float64 helper_fdivs(CPUPPCState *env, float64 arg1, float64 arg2)
+{
+    float64 ret = float64r32_div(arg1, arg2, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
+
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_div(env, flags, 1, GETPC());
+    }
+    if (unlikely(flags & float_flag_divbyzero)) {
+        float_zero_divide_excp(env, GETPC());
+    }
+
+    return ret;
+}
+
 static uint64_t float_invalid_cvt(CPUPPCState *env, int flags,
                                   uint64_t ret, uint64_t ret_nan,
                                   bool set_fprc, uintptr_t retaddr)
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index 898de9fe53..6ae556e5de 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -68,7 +68,7 @@ static void gen_f##name(DisasContext *ctx)                                    \
 _GEN_FLOAT_ACB(name, 0x3F, op2, set_fprf, type);                              \
 _GEN_FLOAT_ACB(name##s, 0x3B, op2, set_fprf, type);
 
-#define _GEN_FLOAT_AB(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
+#define _GEN_FLOAT_AB(name, op1, op2, inval, set_fprf, type)                  \
 static void gen_f##name(DisasContext *ctx)                                    \
 {                                                                             \
     TCGv_i64 t0;                                                              \
@@ -84,10 +84,7 @@ static void gen_f##name(DisasContext *ctx)                                    \
     gen_reset_fpstatus();                                                     \
     get_fpr(t0, rA(ctx->opcode));                                             \
     get_fpr(t1, rB(ctx->opcode));                                             \
-    gen_helper_f##op(t2, cpu_env, t0, t1);                                    \
-    if (isfloat) {                                                            \
-        gen_helper_frsp(t2, cpu_env, t2);                                     \
-    }                                                                         \
+    gen_helper_f##name(t2, cpu_env, t0, t1);                                  \
     set_fpr(rD(ctx->opcode), t2);                                             \
     if (set_fprf) {                                                           \
         gen_compute_fprf_float64(t2);                                         \
@@ -100,8 +97,8 @@ static void gen_f##name(DisasContext *ctx)                                    \
     tcg_temp_free_i64(t2);                                                    \
 }
 #define GEN_FLOAT_AB(name, op2, inval, set_fprf, type)                        \
-_GEN_FLOAT_AB(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
-_GEN_FLOAT_AB(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
+_GEN_FLOAT_AB(name, 0x3F, op2, inval, set_fprf, type);                        \
+_GEN_FLOAT_AB(name##s, 0x3B, op2, inval, set_fprf, type);
 
 #define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
 static void gen_f##name(DisasContext *ctx)                                    \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 31/35] target/ppc: Add helper for fmuls
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (29 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 30/35] target/ppc: Add helpers for fadds, fsubs, fdivs Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:04 ` [PATCH 32/35] target/ppc: Add helper for frsqrtes Richard Henderson
                   ` (6 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Use float64r32_mul.  Fixes a double-rounding issue with performing
the compuation in float64 and then rounding afterward.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/helper.h                |  1 +
 target/ppc/fpu_helper.c            | 12 ++++++++++++
 target/ppc/translate/fp-impl.c.inc | 11 ++++-------
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index f72b547603..9810d416cf 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -97,6 +97,7 @@ DEF_HELPER_3(fadds, f64, env, f64, f64)
 DEF_HELPER_3(fsub, f64, env, f64, f64)
 DEF_HELPER_3(fsubs, f64, env, f64, f64)
 DEF_HELPER_3(fmul, f64, env, f64, f64)
+DEF_HELPER_3(fmuls, f64, env, f64, f64)
 DEF_HELPER_3(fdiv, f64, env, f64, f64)
 DEF_HELPER_3(fdivs, f64, env, f64, f64)
 DEF_HELPER_4(fmadd, i64, env, i64, i64, i64)
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 4048c830e7..6278d61d36 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -533,6 +533,18 @@ float64 helper_fmul(CPUPPCState *env, float64 arg1, float64 arg2)
     return ret;
 }
 
+/* fmuls - fmuls. */
+float64 helper_fmuls(CPUPPCState *env, float64 arg1, float64 arg2)
+{
+    float64 ret = float64r32_mul(arg1, arg2, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
+
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_mul(env, flags, 1, GETPC());
+    }
+    return ret;
+}
+
 static void float_invalid_op_div(CPUPPCState *env, int flags,
                                  bool set_fprc, uintptr_t retaddr)
 {
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index 6ae556e5de..17b4d46040 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -100,7 +100,7 @@ static void gen_f##name(DisasContext *ctx)                                    \
 _GEN_FLOAT_AB(name, 0x3F, op2, inval, set_fprf, type);                        \
 _GEN_FLOAT_AB(name##s, 0x3B, op2, inval, set_fprf, type);
 
-#define _GEN_FLOAT_AC(name, op, op1, op2, inval, isfloat, set_fprf, type)     \
+#define _GEN_FLOAT_AC(name, op1, op2, inval, set_fprf, type)                  \
 static void gen_f##name(DisasContext *ctx)                                    \
 {                                                                             \
     TCGv_i64 t0;                                                              \
@@ -116,10 +116,7 @@ static void gen_f##name(DisasContext *ctx)                                    \
     gen_reset_fpstatus();                                                     \
     get_fpr(t0, rA(ctx->opcode));                                             \
     get_fpr(t1, rC(ctx->opcode));                                             \
-    gen_helper_f##op(t2, cpu_env, t0, t1);                                    \
-    if (isfloat) {                                                            \
-        gen_helper_frsp(t2, cpu_env, t2);                                     \
-    }                                                                         \
+    gen_helper_f##name(t2, cpu_env, t0, t1);                                  \
     set_fpr(rD(ctx->opcode), t2);                                             \
     if (set_fprf) {                                                           \
         gen_compute_fprf_float64(t2);                                         \
@@ -132,8 +129,8 @@ static void gen_f##name(DisasContext *ctx)                                    \
     tcg_temp_free_i64(t2);                                                    \
 }
 #define GEN_FLOAT_AC(name, op2, inval, set_fprf, type)                        \
-_GEN_FLOAT_AC(name, name, 0x3F, op2, inval, 0, set_fprf, type);               \
-_GEN_FLOAT_AC(name##s, name, 0x3B, op2, inval, 1, set_fprf, type);
+_GEN_FLOAT_AC(name, 0x3F, op2, inval, set_fprf, type);                        \
+_GEN_FLOAT_AC(name##s, 0x3B, op2, inval, set_fprf, type);
 
 #define GEN_FLOAT_B(name, op2, op3, set_fprf, type)                           \
 static void gen_f##name(DisasContext *ctx)                                    \
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 32/35] target/ppc: Add helper for frsqrtes
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (30 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 31/35] target/ppc: Add helper for fmuls Richard Henderson
@ 2021-11-19 16:04 ` Richard Henderson
  2021-11-19 16:05 ` [PATCH 33/35] target/ppc: Update fres to new flags and float64r32 Richard Henderson
                   ` (5 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:04 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

There is no double-rounding bug here, because the result is
merely an estimate to within 1 part in 32, but perform the
operation with float64r32_div for consistency.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/helper.h                |  1 +
 target/ppc/fpu_helper.c            | 19 +++++++++++++++++++
 target/ppc/translate/fp-impl.c.inc |  3 +--
 3 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 9810d416cf..48d12233ea 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -113,6 +113,7 @@ DEF_HELPER_2(fsqrts, f64, env, f64)
 DEF_HELPER_2(fre, i64, env, i64)
 DEF_HELPER_2(fres, i64, env, i64)
 DEF_HELPER_2(frsqrte, i64, env, i64)
+DEF_HELPER_2(frsqrtes, i64, env, i64)
 DEF_HELPER_4(fsel, i64, env, i64, i64, i64)
 
 DEF_HELPER_FLAGS_2(ftdiv, TCG_CALL_NO_RWG_SE, i32, i64, i64)
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index 6278d61d36..cb511f2050 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -848,6 +848,25 @@ float64 helper_frsqrte(CPUPPCState *env, float64 arg)
     return retd;
 }
 
+/* frsqrtes  - frsqrtes. */
+float64 helper_frsqrtes(CPUPPCState *env, float64 arg)
+{
+    /* "Estimate" the reciprocal with actual division.  */
+    float64 rets = float64_sqrt(arg, &env->fp_status);
+    float64 retd = float64r32_div(float64_one, rets, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
+
+    if (unlikely(flags & float_flag_invalid)) {
+        float_invalid_op_sqrt(env, flags, 1, GETPC());
+    }
+    if (unlikely(flags & float_flag_divbyzero)) {
+        /* Reciprocal of (square root of) zero.  */
+        float_zero_divide_excp(env, GETPC());
+    }
+
+    return retd;
+}
+
 /* fsel - fsel. */
 uint64_t helper_fsel(CPUPPCState *env, uint64_t arg1, uint64_t arg2,
                      uint64_t arg3)
diff --git a/target/ppc/translate/fp-impl.c.inc b/target/ppc/translate/fp-impl.c.inc
index 17b4d46040..9056a773cb 100644
--- a/target/ppc/translate/fp-impl.c.inc
+++ b/target/ppc/translate/fp-impl.c.inc
@@ -212,8 +212,7 @@ static void gen_frsqrtes(DisasContext *ctx)
     t1 = tcg_temp_new_i64();
     gen_reset_fpstatus();
     get_fpr(t0, rB(ctx->opcode));
-    gen_helper_frsqrte(t1, cpu_env, t0);
-    gen_helper_frsp(t1, cpu_env, t1);
+    gen_helper_frsqrtes(t1, cpu_env, t0);
     set_fpr(rD(ctx->opcode), t1);
     gen_compute_fprf_float64(t1);
     if (unlikely(Rc(ctx->opcode) != 0)) {
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 33/35] target/ppc: Update fres to new flags and float64r32
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (31 preceding siblings ...)
  2021-11-19 16:04 ` [PATCH 32/35] target/ppc: Add helper for frsqrtes Richard Henderson
@ 2021-11-19 16:05 ` Richard Henderson
  2021-11-19 16:05 ` [PATCH 34/35] target/ppc: Use helper_todouble/tosingle in helper_xststdcsp Richard Henderson
                   ` (4 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

There is no double-rounding bug here, because the result is
merely an estimate to within 1 part in 256, but perform the
operation with float64r32_div for consistency.

Use float_flag_invalid_snan instead of recomputing the
snan-ness of the operand.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index cb511f2050..ea238929da 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -813,20 +813,20 @@ float64 helper_fre(CPUPPCState *env, float64 arg)
 /* fres - fres. */
 uint64_t helper_fres(CPUPPCState *env, uint64_t arg)
 {
-    CPU_DoubleU farg;
-    float32 f32;
+    /* "Estimate" the reciprocal with actual division.  */
+    float64 ret = float64r32_div(float64_one, arg, &env->fp_status);
+    int flags = get_float_exception_flags(&env->fp_status);
 
-    farg.ll = arg;
-
-    if (unlikely(float64_is_signaling_nan(farg.d, &env->fp_status))) {
-        /* sNaN reciprocal */
+    if (unlikely(flags & float_flag_invalid_snan)) {
         float_invalid_op_vxsnan(env, GETPC());
     }
-    farg.d = float64_div(float64_one, farg.d, &env->fp_status);
-    f32 = float64_to_float32(farg.d, &env->fp_status);
-    farg.d = float32_to_float64(f32, &env->fp_status);
+    if (unlikely(flags & float_flag_divbyzero)) {
+        float_zero_divide_excp(env, GETPC());
+        /* For FPSCR.ZE == 0, the result is 1/2.  */
+        ret = float64_set_sign(float64_half, float64_is_neg(arg));
+    }
 
-    return farg.ll;
+    return ret;
 }
 
 /* frsqrte  - frsqrte. */
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 34/35] target/ppc: Use helper_todouble/tosingle in helper_xststdcsp
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (32 preceding siblings ...)
  2021-11-19 16:05 ` [PATCH 33/35] target/ppc: Update fres to new flags and float64r32 Richard Henderson
@ 2021-11-19 16:05 ` Richard Henderson
  2021-11-19 16:05 ` [PATCH 35/35] test/tcg/ppc64le: Add float reference files Richard Henderson
                   ` (3 subsequent siblings)
  37 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

When computing the predicate "is this value currently formatted
for single precision", we do not want to round the value according
to the current rounding mode, nor perform a floating-point equality.
We want to see if the N bits that make up single-precision are the
only ones set within the register, and then a bitwise equality.

Fixes a bug in which a single-precision NaN is considered !SP,
because float64_eq(nan, nan) is always false.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/ppc/fpu_helper.c | 21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index ea238929da..b81aaca67b 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -3115,26 +3115,25 @@ void helper_xststdcsp(CPUPPCState *env, uint32_t opcode, ppc_vsr_t *xb)
 {
     uint32_t dcmx, sign, exp;
     uint32_t cc, match = 0, not_sp = 0;
+    float64 arg = xb->VsrD(0);
+    float64 arg_sp;
 
     dcmx = DCMX(opcode);
-    exp = (xb->VsrD(0) >> 52) & 0x7FF;
+    exp = (arg >> 52) & 0x7FF;
+    sign = float64_is_neg(arg);
 
-    sign = float64_is_neg(xb->VsrD(0));
-    if (float64_is_any_nan(xb->VsrD(0))) {
+    if (float64_is_any_nan(arg)) {
         match = extract32(dcmx, 6, 1);
-    } else if (float64_is_infinity(xb->VsrD(0))) {
+    } else if (float64_is_infinity(arg)) {
         match = extract32(dcmx, 4 + !sign, 1);
-    } else if (float64_is_zero(xb->VsrD(0))) {
+    } else if (float64_is_zero(arg)) {
         match = extract32(dcmx, 2 + !sign, 1);
-    } else if (float64_is_zero_or_denormal(xb->VsrD(0)) ||
-               (exp > 0 && exp < 0x381)) {
+    } else if (float64_is_zero_or_denormal(arg) || (exp > 0 && exp < 0x381)) {
         match = extract32(dcmx, 0 + !sign, 1);
     }
 
-    not_sp = !float64_eq(xb->VsrD(0),
-                         float32_to_float64(
-                             float64_to_float32(xb->VsrD(0), &env->fp_status),
-                             &env->fp_status), &env->fp_status);
+    arg_sp = helper_todouble(helper_tosingle(arg));
+    not_sp = arg != arg_sp;
 
     cc = sign << CRF_LT_BIT | match << CRF_EQ_BIT | not_sp << CRF_SO_BIT;
     env->fpscr &= ~FP_FPCC;
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (33 preceding siblings ...)
  2021-11-19 16:05 ` [PATCH 34/35] target/ppc: Use helper_todouble/tosingle in helper_xststdcsp Richard Henderson
@ 2021-11-19 16:05 ` Richard Henderson
  2021-11-21 17:47   ` 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
                   ` (2 subsequent siblings)
  37 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2021-11-19 16:05 UTC (permalink / raw)
  To: qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee, clg

Generated on Power9, PowerNV 9006-22P.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 tests/tcg/ppc64le/float_convs.ref | 748 +++++++++++++++++++++++++++++
 tests/tcg/ppc64le/float_madds.ref | 768 ++++++++++++++++++++++++++++++
 2 files changed, 1516 insertions(+)
 create mode 100644 tests/tcg/ppc64le/float_convs.ref
 create mode 100644 tests/tcg/ppc64le/float_madds.ref

diff --git a/tests/tcg/ppc64le/float_convs.ref b/tests/tcg/ppc64le/float_convs.ref
new file mode 100644
index 0000000000..6e6f636834
--- /dev/null
+++ b/tests/tcg/ppc64le/float_convs.ref
@@ -0,0 +1,748 @@
+### Rounding to nearest
+from single: f32(-nan:0xffa00000)
+  to double: f64(-nan:0x00fff4000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-nan:0xffc00000)
+  to double: f64(-nan:0x00fff8000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-inf:0xff800000)
+  to double: f64(-inf:0x00fff0000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+  to double: f64(-0x1.fffffe00000000000000p+127:0x00c7efffffe0000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+  to double: f64(-0x1.1874b200000000000000p+103:0x00c661874b20000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+  to double: f64(-0x1.c0bab600000000000000p+99:0x00c62c0bab60000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+  to double: f64(-0x1.31f75000000000000000p-40:0x00bd731f7500000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+  to double: f64(-0x1.50544400000000000000p-66:0x00bbd5054440000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(-0x1.00000000000000000000p-126:0x80800000)
+  to double: f64(-0x1.00000000000000000000p-126:0x00b810000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x0.00000000000000000000p+0:0000000000)
+  to double: f64(0x0.00000000000000000000p+0:00000000000000000000) (OK)
+   to int32: 0 (OK)
+   to int64: 0 (OK)
+  to uint32: 0 (OK)
+  to uint64: 0 (OK)
+from single: f32(0x1.00000000000000000000p-126:0x00800000)
+  to double: f64(0x1.00000000000000000000p-126:0x003810000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000000000000000000p-25:0x33000000)
+  to double: f64(0x1.00000000000000000000p-25:0x003e60000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+  to double: f64(0x1.ffffe600000000000000p-25:0x003e6ffffe60000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+  to double: f64(0x1.ff801a00000000000000p-15:0x003f0ff801a0000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000c00000000000000p-14:0x38800006)
+  to double: f64(0x1.00000c00000000000000p-14:0x003f100000c0000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000000000000000000p+0:0x3f800000)
+  to double: f64(0x1.00000000000000000000p+0:0x003ff0000000000000) (OK)
+   to int32: 1 (OK)
+   to int64: 1 (OK)
+  to uint32: 1 (OK)
+  to uint64: 1 (OK)
+from single: f32(0x1.00400000000000000000p+0:0x3f802000)
+  to double: f64(0x1.00400000000000000000p+0:0x003ff0040000000000) (OK)
+   to int32: 1 (INEXACT )
+   to int64: 1 (INEXACT )
+  to uint32: 1 (INEXACT )
+  to uint64: 1 (INEXACT )
+from single: f32(0x1.00000000000000000000p+1:0x40000000)
+  to double: f64(0x1.00000000000000000000p+1:0x004000000000000000) (OK)
+   to int32: 2 (OK)
+   to int64: 2 (OK)
+  to uint32: 2 (OK)
+  to uint64: 2 (OK)
+from single: f32(0x1.5bf0a800000000000000p+1:0x402df854)
+  to double: f64(0x1.5bf0a800000000000000p+1:0x004005bf0a80000000) (OK)
+   to int32: 2 (INEXACT )
+   to int64: 2 (INEXACT )
+  to uint32: 2 (INEXACT )
+  to uint64: 2 (INEXACT )
+from single: f32(0x1.921fb600000000000000p+1:0x40490fdb)
+  to double: f64(0x1.921fb600000000000000p+1:0x00400921fb60000000) (OK)
+   to int32: 3 (INEXACT )
+   to int64: 3 (INEXACT )
+  to uint32: 3 (INEXACT )
+  to uint64: 3 (INEXACT )
+from single: f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+  to double: f64(0x1.ffbe0000000000000000p+15:0x0040effbe000000000) (OK)
+   to int32: 65503 (OK)
+   to int64: 65503 (OK)
+  to uint32: 65503 (OK)
+  to uint64: 65503 (OK)
+from single: f32(0x1.ffc00000000000000000p+15:0x477fe000)
+  to double: f64(0x1.ffc00000000000000000p+15:0x0040effc0000000000) (OK)
+   to int32: 65504 (OK)
+   to int64: 65504 (OK)
+  to uint32: 65504 (OK)
+  to uint64: 65504 (OK)
+from single: f32(0x1.ffc20000000000000000p+15:0x477fe100)
+  to double: f64(0x1.ffc20000000000000000p+15:0x0040effc2000000000) (OK)
+   to int32: 65505 (OK)
+   to int64: 65505 (OK)
+  to uint32: 65505 (OK)
+  to uint64: 65505 (OK)
+from single: f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+  to double: f64(0x1.ffbf0000000000000000p+16:0x0040fffbf000000000) (OK)
+   to int32: 131007 (OK)
+   to int64: 131007 (OK)
+  to uint32: 131007 (OK)
+  to uint64: 131007 (OK)
+from single: f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+  to double: f64(0x1.ffc00000000000000000p+16:0x0040fffc0000000000) (OK)
+   to int32: 131008 (OK)
+   to int64: 131008 (OK)
+  to uint32: 131008 (OK)
+  to uint64: 131008 (OK)
+from single: f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+  to double: f64(0x1.ffc10000000000000000p+16:0x0040fffc1000000000) (OK)
+   to int32: 131009 (OK)
+   to int64: 131009 (OK)
+  to uint32: 131009 (OK)
+  to uint64: 131009 (OK)
+from single: f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+  to double: f64(0x1.c0bab600000000000000p+99:0x00462c0bab60000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+  to double: f64(0x1.fffffe00000000000000p+127:0x0047efffffe0000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(inf:0x7f800000)
+  to double: f64(inf:0x007ff0000000000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(nan:0x7fc00000)
+  to double: f64(nan:0x007ff8000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(nan:0x7fa00000)
+  to double: f64(nan:0x007ff4000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+### Rounding upwards
+from single: f32(-nan:0xffa00000)
+  to double: f64(-nan:0x00fff4000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-nan:0xffc00000)
+  to double: f64(-nan:0x00fff8000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-inf:0xff800000)
+  to double: f64(-inf:0x00fff0000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+  to double: f64(-0x1.fffffe00000000000000p+127:0x00c7efffffe0000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+  to double: f64(-0x1.1874b200000000000000p+103:0x00c661874b20000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+  to double: f64(-0x1.c0bab600000000000000p+99:0x00c62c0bab60000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+  to double: f64(-0x1.31f75000000000000000p-40:0x00bd731f7500000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+  to double: f64(-0x1.50544400000000000000p-66:0x00bbd5054440000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(-0x1.00000000000000000000p-126:0x80800000)
+  to double: f64(-0x1.00000000000000000000p-126:0x00b810000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x0.00000000000000000000p+0:0000000000)
+  to double: f64(0x0.00000000000000000000p+0:00000000000000000000) (OK)
+   to int32: 0 (OK)
+   to int64: 0 (OK)
+  to uint32: 0 (OK)
+  to uint64: 0 (OK)
+from single: f32(0x1.00000000000000000000p-126:0x00800000)
+  to double: f64(0x1.00000000000000000000p-126:0x003810000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000000000000000000p-25:0x33000000)
+  to double: f64(0x1.00000000000000000000p-25:0x003e60000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+  to double: f64(0x1.ffffe600000000000000p-25:0x003e6ffffe60000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+  to double: f64(0x1.ff801a00000000000000p-15:0x003f0ff801a0000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000c00000000000000p-14:0x38800006)
+  to double: f64(0x1.00000c00000000000000p-14:0x003f100000c0000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000000000000000000p+0:0x3f800000)
+  to double: f64(0x1.00000000000000000000p+0:0x003ff0000000000000) (OK)
+   to int32: 1 (OK)
+   to int64: 1 (OK)
+  to uint32: 1 (OK)
+  to uint64: 1 (OK)
+from single: f32(0x1.00400000000000000000p+0:0x3f802000)
+  to double: f64(0x1.00400000000000000000p+0:0x003ff0040000000000) (OK)
+   to int32: 1 (INEXACT )
+   to int64: 1 (INEXACT )
+  to uint32: 1 (INEXACT )
+  to uint64: 1 (INEXACT )
+from single: f32(0x1.00000000000000000000p+1:0x40000000)
+  to double: f64(0x1.00000000000000000000p+1:0x004000000000000000) (OK)
+   to int32: 2 (OK)
+   to int64: 2 (OK)
+  to uint32: 2 (OK)
+  to uint64: 2 (OK)
+from single: f32(0x1.5bf0a800000000000000p+1:0x402df854)
+  to double: f64(0x1.5bf0a800000000000000p+1:0x004005bf0a80000000) (OK)
+   to int32: 2 (INEXACT )
+   to int64: 2 (INEXACT )
+  to uint32: 2 (INEXACT )
+  to uint64: 2 (INEXACT )
+from single: f32(0x1.921fb600000000000000p+1:0x40490fdb)
+  to double: f64(0x1.921fb600000000000000p+1:0x00400921fb60000000) (OK)
+   to int32: 3 (INEXACT )
+   to int64: 3 (INEXACT )
+  to uint32: 3 (INEXACT )
+  to uint64: 3 (INEXACT )
+from single: f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+  to double: f64(0x1.ffbe0000000000000000p+15:0x0040effbe000000000) (OK)
+   to int32: 65503 (OK)
+   to int64: 65503 (OK)
+  to uint32: 65503 (OK)
+  to uint64: 65503 (OK)
+from single: f32(0x1.ffc00000000000000000p+15:0x477fe000)
+  to double: f64(0x1.ffc00000000000000000p+15:0x0040effc0000000000) (OK)
+   to int32: 65504 (OK)
+   to int64: 65504 (OK)
+  to uint32: 65504 (OK)
+  to uint64: 65504 (OK)
+from single: f32(0x1.ffc20000000000000000p+15:0x477fe100)
+  to double: f64(0x1.ffc20000000000000000p+15:0x0040effc2000000000) (OK)
+   to int32: 65505 (OK)
+   to int64: 65505 (OK)
+  to uint32: 65505 (OK)
+  to uint64: 65505 (OK)
+from single: f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+  to double: f64(0x1.ffbf0000000000000000p+16:0x0040fffbf000000000) (OK)
+   to int32: 131007 (OK)
+   to int64: 131007 (OK)
+  to uint32: 131007 (OK)
+  to uint64: 131007 (OK)
+from single: f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+  to double: f64(0x1.ffc00000000000000000p+16:0x0040fffc0000000000) (OK)
+   to int32: 131008 (OK)
+   to int64: 131008 (OK)
+  to uint32: 131008 (OK)
+  to uint64: 131008 (OK)
+from single: f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+  to double: f64(0x1.ffc10000000000000000p+16:0x0040fffc1000000000) (OK)
+   to int32: 131009 (OK)
+   to int64: 131009 (OK)
+  to uint32: 131009 (OK)
+  to uint64: 131009 (OK)
+from single: f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+  to double: f64(0x1.c0bab600000000000000p+99:0x00462c0bab60000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+  to double: f64(0x1.fffffe00000000000000p+127:0x0047efffffe0000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(inf:0x7f800000)
+  to double: f64(inf:0x007ff0000000000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(nan:0x7fc00000)
+  to double: f64(nan:0x007ff8000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(nan:0x7fa00000)
+  to double: f64(nan:0x007ff4000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+### Rounding downwards
+from single: f32(-nan:0xffa00000)
+  to double: f64(-nan:0x00fff4000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-nan:0xffc00000)
+  to double: f64(-nan:0x00fff8000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-inf:0xff800000)
+  to double: f64(-inf:0x00fff0000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+  to double: f64(-0x1.fffffe00000000000000p+127:0x00c7efffffe0000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+  to double: f64(-0x1.1874b200000000000000p+103:0x00c661874b20000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+  to double: f64(-0x1.c0bab600000000000000p+99:0x00c62c0bab60000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+  to double: f64(-0x1.31f75000000000000000p-40:0x00bd731f7500000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+  to double: f64(-0x1.50544400000000000000p-66:0x00bbd5054440000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(-0x1.00000000000000000000p-126:0x80800000)
+  to double: f64(-0x1.00000000000000000000p-126:0x00b810000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x0.00000000000000000000p+0:0000000000)
+  to double: f64(0x0.00000000000000000000p+0:00000000000000000000) (OK)
+   to int32: 0 (OK)
+   to int64: 0 (OK)
+  to uint32: 0 (OK)
+  to uint64: 0 (OK)
+from single: f32(0x1.00000000000000000000p-126:0x00800000)
+  to double: f64(0x1.00000000000000000000p-126:0x003810000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000000000000000000p-25:0x33000000)
+  to double: f64(0x1.00000000000000000000p-25:0x003e60000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+  to double: f64(0x1.ffffe600000000000000p-25:0x003e6ffffe60000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+  to double: f64(0x1.ff801a00000000000000p-15:0x003f0ff801a0000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000c00000000000000p-14:0x38800006)
+  to double: f64(0x1.00000c00000000000000p-14:0x003f100000c0000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000000000000000000p+0:0x3f800000)
+  to double: f64(0x1.00000000000000000000p+0:0x003ff0000000000000) (OK)
+   to int32: 1 (OK)
+   to int64: 1 (OK)
+  to uint32: 1 (OK)
+  to uint64: 1 (OK)
+from single: f32(0x1.00400000000000000000p+0:0x3f802000)
+  to double: f64(0x1.00400000000000000000p+0:0x003ff0040000000000) (OK)
+   to int32: 1 (INEXACT )
+   to int64: 1 (INEXACT )
+  to uint32: 1 (INEXACT )
+  to uint64: 1 (INEXACT )
+from single: f32(0x1.00000000000000000000p+1:0x40000000)
+  to double: f64(0x1.00000000000000000000p+1:0x004000000000000000) (OK)
+   to int32: 2 (OK)
+   to int64: 2 (OK)
+  to uint32: 2 (OK)
+  to uint64: 2 (OK)
+from single: f32(0x1.5bf0a800000000000000p+1:0x402df854)
+  to double: f64(0x1.5bf0a800000000000000p+1:0x004005bf0a80000000) (OK)
+   to int32: 2 (INEXACT )
+   to int64: 2 (INEXACT )
+  to uint32: 2 (INEXACT )
+  to uint64: 2 (INEXACT )
+from single: f32(0x1.921fb600000000000000p+1:0x40490fdb)
+  to double: f64(0x1.921fb600000000000000p+1:0x00400921fb60000000) (OK)
+   to int32: 3 (INEXACT )
+   to int64: 3 (INEXACT )
+  to uint32: 3 (INEXACT )
+  to uint64: 3 (INEXACT )
+from single: f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+  to double: f64(0x1.ffbe0000000000000000p+15:0x0040effbe000000000) (OK)
+   to int32: 65503 (OK)
+   to int64: 65503 (OK)
+  to uint32: 65503 (OK)
+  to uint64: 65503 (OK)
+from single: f32(0x1.ffc00000000000000000p+15:0x477fe000)
+  to double: f64(0x1.ffc00000000000000000p+15:0x0040effc0000000000) (OK)
+   to int32: 65504 (OK)
+   to int64: 65504 (OK)
+  to uint32: 65504 (OK)
+  to uint64: 65504 (OK)
+from single: f32(0x1.ffc20000000000000000p+15:0x477fe100)
+  to double: f64(0x1.ffc20000000000000000p+15:0x0040effc2000000000) (OK)
+   to int32: 65505 (OK)
+   to int64: 65505 (OK)
+  to uint32: 65505 (OK)
+  to uint64: 65505 (OK)
+from single: f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+  to double: f64(0x1.ffbf0000000000000000p+16:0x0040fffbf000000000) (OK)
+   to int32: 131007 (OK)
+   to int64: 131007 (OK)
+  to uint32: 131007 (OK)
+  to uint64: 131007 (OK)
+from single: f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+  to double: f64(0x1.ffc00000000000000000p+16:0x0040fffc0000000000) (OK)
+   to int32: 131008 (OK)
+   to int64: 131008 (OK)
+  to uint32: 131008 (OK)
+  to uint64: 131008 (OK)
+from single: f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+  to double: f64(0x1.ffc10000000000000000p+16:0x0040fffc1000000000) (OK)
+   to int32: 131009 (OK)
+   to int64: 131009 (OK)
+  to uint32: 131009 (OK)
+  to uint64: 131009 (OK)
+from single: f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+  to double: f64(0x1.c0bab600000000000000p+99:0x00462c0bab60000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+  to double: f64(0x1.fffffe00000000000000p+127:0x0047efffffe0000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(inf:0x7f800000)
+  to double: f64(inf:0x007ff0000000000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(nan:0x7fc00000)
+  to double: f64(nan:0x007ff8000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(nan:0x7fa00000)
+  to double: f64(nan:0x007ff4000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+### Rounding to zero
+from single: f32(-nan:0xffa00000)
+  to double: f64(-nan:0x00fff4000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-nan:0xffc00000)
+  to double: f64(-nan:0x00fff8000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-inf:0xff800000)
+  to double: f64(-inf:0x00fff0000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+  to double: f64(-0x1.fffffe00000000000000p+127:0x00c7efffffe0000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+  to double: f64(-0x1.1874b200000000000000p+103:0x00c661874b20000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+  to double: f64(-0x1.c0bab600000000000000p+99:0x00c62c0bab60000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+  to double: f64(-0x1.31f75000000000000000p-40:0x00bd731f7500000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+  to double: f64(-0x1.50544400000000000000p-66:0x00bbd5054440000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(-0x1.00000000000000000000p-126:0x80800000)
+  to double: f64(-0x1.00000000000000000000p-126:0x00b810000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x0.00000000000000000000p+0:0000000000)
+  to double: f64(0x0.00000000000000000000p+0:00000000000000000000) (OK)
+   to int32: 0 (OK)
+   to int64: 0 (OK)
+  to uint32: 0 (OK)
+  to uint64: 0 (OK)
+from single: f32(0x1.00000000000000000000p-126:0x00800000)
+  to double: f64(0x1.00000000000000000000p-126:0x003810000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000000000000000000p-25:0x33000000)
+  to double: f64(0x1.00000000000000000000p-25:0x003e60000000000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+  to double: f64(0x1.ffffe600000000000000p-25:0x003e6ffffe60000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+  to double: f64(0x1.ff801a00000000000000p-15:0x003f0ff801a0000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000c00000000000000p-14:0x38800006)
+  to double: f64(0x1.00000c00000000000000p-14:0x003f100000c0000000) (OK)
+   to int32: 0 (INEXACT )
+   to int64: 0 (INEXACT )
+  to uint32: 0 (INEXACT )
+  to uint64: 0 (INEXACT )
+from single: f32(0x1.00000000000000000000p+0:0x3f800000)
+  to double: f64(0x1.00000000000000000000p+0:0x003ff0000000000000) (OK)
+   to int32: 1 (OK)
+   to int64: 1 (OK)
+  to uint32: 1 (OK)
+  to uint64: 1 (OK)
+from single: f32(0x1.00400000000000000000p+0:0x3f802000)
+  to double: f64(0x1.00400000000000000000p+0:0x003ff0040000000000) (OK)
+   to int32: 1 (INEXACT )
+   to int64: 1 (INEXACT )
+  to uint32: 1 (INEXACT )
+  to uint64: 1 (INEXACT )
+from single: f32(0x1.00000000000000000000p+1:0x40000000)
+  to double: f64(0x1.00000000000000000000p+1:0x004000000000000000) (OK)
+   to int32: 2 (OK)
+   to int64: 2 (OK)
+  to uint32: 2 (OK)
+  to uint64: 2 (OK)
+from single: f32(0x1.5bf0a800000000000000p+1:0x402df854)
+  to double: f64(0x1.5bf0a800000000000000p+1:0x004005bf0a80000000) (OK)
+   to int32: 2 (INEXACT )
+   to int64: 2 (INEXACT )
+  to uint32: 2 (INEXACT )
+  to uint64: 2 (INEXACT )
+from single: f32(0x1.921fb600000000000000p+1:0x40490fdb)
+  to double: f64(0x1.921fb600000000000000p+1:0x00400921fb60000000) (OK)
+   to int32: 3 (INEXACT )
+   to int64: 3 (INEXACT )
+  to uint32: 3 (INEXACT )
+  to uint64: 3 (INEXACT )
+from single: f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+  to double: f64(0x1.ffbe0000000000000000p+15:0x0040effbe000000000) (OK)
+   to int32: 65503 (OK)
+   to int64: 65503 (OK)
+  to uint32: 65503 (OK)
+  to uint64: 65503 (OK)
+from single: f32(0x1.ffc00000000000000000p+15:0x477fe000)
+  to double: f64(0x1.ffc00000000000000000p+15:0x0040effc0000000000) (OK)
+   to int32: 65504 (OK)
+   to int64: 65504 (OK)
+  to uint32: 65504 (OK)
+  to uint64: 65504 (OK)
+from single: f32(0x1.ffc20000000000000000p+15:0x477fe100)
+  to double: f64(0x1.ffc20000000000000000p+15:0x0040effc2000000000) (OK)
+   to int32: 65505 (OK)
+   to int64: 65505 (OK)
+  to uint32: 65505 (OK)
+  to uint64: 65505 (OK)
+from single: f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+  to double: f64(0x1.ffbf0000000000000000p+16:0x0040fffbf000000000) (OK)
+   to int32: 131007 (OK)
+   to int64: 131007 (OK)
+  to uint32: 131007 (OK)
+  to uint64: 131007 (OK)
+from single: f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+  to double: f64(0x1.ffc00000000000000000p+16:0x0040fffc0000000000) (OK)
+   to int32: 131008 (OK)
+   to int64: 131008 (OK)
+  to uint32: 131008 (OK)
+  to uint64: 131008 (OK)
+from single: f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+  to double: f64(0x1.ffc10000000000000000p+16:0x0040fffc1000000000) (OK)
+   to int32: 131009 (OK)
+   to int64: 131009 (OK)
+  to uint32: 131009 (OK)
+  to uint64: 131009 (OK)
+from single: f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+  to double: f64(0x1.c0bab600000000000000p+99:0x00462c0bab60000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+  to double: f64(0x1.fffffe00000000000000p+127:0x0047efffffe0000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(inf:0x7f800000)
+  to double: f64(inf:0x007ff0000000000000) (OK)
+   to int32: 2147483647 (INVALID)
+   to int64: 9223372036854775807 (INVALID)
+  to uint32: -1 (INVALID)
+  to uint64: -1 (INVALID)
+from single: f32(nan:0x7fc00000)
+  to double: f64(nan:0x007ff8000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
+from single: f32(nan:0x7fa00000)
+  to double: f64(nan:0x007ff4000000000000) (OK)
+   to int32: -2147483648 (INVALID)
+   to int64: -9223372036854775808 (INVALID)
+  to uint32: 0 (INVALID)
+  to uint64: 0 (INVALID)
diff --git a/tests/tcg/ppc64le/float_madds.ref b/tests/tcg/ppc64le/float_madds.ref
new file mode 100644
index 0000000000..e66917cb80
--- /dev/null
+++ b/tests/tcg/ppc64le/float_madds.ref
@@ -0,0 +1,768 @@
+### Rounding to nearest
+op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-inf:0xff800000)
+res: f32(-nan:0xffe00000) flags=INVALID (0/0)
+op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-nan:0xffa00000)
+res: f32(-nan:0xffc00000) flags=INVALID (0/1)
+op : f32(-inf:0xff800000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000)
+res: f32(-nan:0xffc00000) flags=INVALID (0/2)
+op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(-nan:0xffc00000) flags=OK (1/0)
+op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-nan:0xffc00000)
+res: f32(-nan:0xffc00000) flags=OK (1/1)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-nan:0xffc00000) + f32(-inf:0xff800000)
+res: f32(-nan:0xffc00000) flags=OK (1/2)
+op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(inf:0x7f800000) flags=OK (2/0)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-inf:0xff800000)
+res: f32(-inf:0xff800000) flags=OK (2/1)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(inf:0x7f800000) flags=OK (2/2)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (3/0)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (3/1)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (3/2)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (4/0)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(-0x1.1874b200000000000000p+103:0xf30c3a59) flags=INEXACT  (4/1)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) flags=INEXACT  (4/2)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(0x1.0c27fa00000000000000p+60:0x5d8613fd) flags=INEXACT  (5/0)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) flags=INEXACT  (5/1)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(0x1.26c46200000000000000p+34:0x50936231) flags=INEXACT  (5/2)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(0x1.91f94000000000000000p-106:0x0ac8fca0) flags=INEXACT  (6/0)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(-0x1.31f75000000000000000p-40:0xab98fba8) flags=INEXACT  (6/1)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=INEXACT  (6/2)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT  (7/0)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=OK (7/1)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (7/2)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (8/0)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (8/1)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(-0x0.00000000000000000000p+0:0x80000000) flags=UNDERFLOW INEXACT  (8/2)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00000000000000000000p-25:0x33000000) flags=OK (9/0)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT  (9/1)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (9/2)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.ffffe600000000000000p-25:0x337ffff3) flags=INEXACT  (10/0)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.ffffe600000000000000p-50:0x26fffff3) flags=INEXACT  (10/1)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00000000000000000000p-25:0x33000000) flags=INEXACT  (10/2)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT  (11/0)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.0007fe00000000000000p-25:0x330003ff) flags=INEXACT  (11/1)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.0001f200000000000000p-24:0x338000f9) flags=INEXACT  (11/2)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.00000c00000000000000p-14:0x38800006) flags=INEXACT  (12/0)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.0ffbf400000000000000p-24:0x3387fdfa) flags=INEXACT  (12/1)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ff801c00000000000000p-15:0x387fc00e) flags=INEXACT  (12/2)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.00000000000000000000p+0:0x3f800000) flags=INEXACT  (13/0)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT  (13/1)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT  (13/2)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT  (14/0)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT  (14/1)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.00040200000000000000p+0:0x3f800201) flags=INEXACT  (14/2)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.80200000000000000000p+1:0x40401000) flags=OK (15/0)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.80400000000000000000p+1:0x40402000) flags=OK (15/1)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.80200000000000000000p+1:0x40401000) flags=OK (15/2)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.2e185400000000000000p+2:0x40970c2a) flags=OK (16/0)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.9c00a800000000000000p+2:0x40ce0054) flags=OK (16/1)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.2e23d200000000000000p+2:0x409711e9) flags=INEXACT  (16/2)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.12804200000000000000p+3:0x41094021) flags=INEXACT  (17/0)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.51458000000000000000p+3:0x4128a2c0) flags=INEXACT  (17/1)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.200c0400000000000000p+3:0x41100602) flags=INEXACT  (17/2)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.ffcf1400000000000000p+15:0x477fe78a) flags=INEXACT  (18/0)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.91ed3c00000000000000p+17:0x4848f69e) flags=INEXACT  (18/1)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.5bc56000000000000000p+17:0x482de2b0) flags=INEXACT  (18/2)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.08edf000000000000000p+18:0x488476f8) flags=INEXACT  (19/0)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.ff7e0800000000000000p+31:0x4f7fbf04) flags=INEXACT  (19/1)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.08ee7a00000000000000p+18:0x4884773d) flags=INEXACT  (19/2)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff800800000000000000p+31:0x4f7fc004) flags=INEXACT  (20/0)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.ff840800000000000000p+31:0x4f7fc204) flags=INEXACT  (20/1)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.ff820800000000000000p+31:0x4f7fc104) flags=INEXACT  (20/2)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff860800000000000000p+31:0x4f7fc304) flags=INEXACT  (21/0)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.ff820800000000000000p+32:0x4fffc104) flags=INEXACT  (21/1)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff800800000000000000p+32:0x4fffc004) flags=INEXACT  (21/2)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.ff830800000000000000p+32:0x4fffc184) flags=INEXACT  (22/0)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff7f8800000000000000p+33:0x507fbfc4) flags=INEXACT  (22/1)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff840800000000000000p+32:0x4fffc204) flags=INEXACT  (22/2)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.ff800800000000000000p+33:0x507fc004) flags=INEXACT  (23/0)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff820800000000000000p+33:0x507fc104) flags=INEXACT  (23/1)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.ff810800000000000000p+33:0x507fc084) flags=INEXACT  (23/2)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(0x1.c0bab600000000000000p+99:0x71605d5b) flags=INEXACT  (24/0)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.c0838000000000000000p+116:0x79e041c0) flags=INEXACT  (24/1)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.c0829e00000000000000p+116:0x79e0414f) flags=INEXACT  (24/2)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (25/0)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (25/1)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (25/2)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000)
+res: f32(inf:0x7f800000) flags=OK (26/0)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(inf:0x7f800000) flags=OK (26/1)
+op : f32(inf:0x7f800000) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(inf:0x7f800000) flags=OK (26/2)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fc00000) flags=OK (27/0)
+op : f32(inf:0x7f800000) * f32(nan:0x7fc00000) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(nan:0x7fc00000) flags=OK (27/1)
+op : f32(nan:0x7fc00000) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000)
+res: f32(nan:0x7fc00000) flags=OK (27/2)
+op : f32(inf:0x7f800000) * f32(nan:0x7fc00000) + f32(nan:0x7fa00000)
+res: f32(nan:0x7fe00000) flags=INVALID (28/0)
+op : f32(nan:0x7fc00000) * f32(nan:0x7fa00000) + f32(inf:0x7f800000)
+res: f32(nan:0x7fc00000) flags=INVALID (28/1)
+op : f32(nan:0x7fa00000) * f32(inf:0x7f800000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (28/2)
+op : f32(nan:0x7fc00000) * f32(nan:0x7fa00000) + f32(-nan:0xffa00000)
+res: f32(nan:0x7fc00000) flags=INVALID (29/0)
+op : f32(nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (29/1)
+op : f32(-nan:0xffa00000) * f32(nan:0x7fc00000) + f32(nan:0x7fa00000)
+res: f32(-nan:0xffe00000) flags=INVALID (29/2)
+op : f32(nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (30/0)
+op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(nan:0x7fa00000)
+res: f32(-nan:0xffe00000) flags=INVALID (30/1)
+op : f32(-nan:0xffc00000) * f32(nan:0x7fa00000) + f32(-nan:0xffa00000)
+res: f32(-nan:0xffc00000) flags=INVALID (30/2)
+# LP184149
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-1:0x3f000000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=OK (31/0)
+op : f32(0x1.00000000000000000000p-149:0x00000001) * f32(0x1.00000000000000000000p-149:0x00000001) + f32(0x1.00000000000000000000p-149:0x00000001)
+res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT  (32/0)
+### Rounding upwards
+op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-inf:0xff800000)
+res: f32(-nan:0xffe00000) flags=INVALID (0/0)
+op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-nan:0xffa00000)
+res: f32(-nan:0xffc00000) flags=INVALID (0/1)
+op : f32(-inf:0xff800000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000)
+res: f32(-nan:0xffc00000) flags=INVALID (0/2)
+op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(-nan:0xffc00000) flags=OK (1/0)
+op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-nan:0xffc00000)
+res: f32(-nan:0xffc00000) flags=OK (1/1)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-nan:0xffc00000) + f32(-inf:0xff800000)
+res: f32(-nan:0xffc00000) flags=OK (1/2)
+op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(inf:0x7f800000) flags=OK (2/0)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-inf:0xff800000)
+res: f32(-inf:0xff800000) flags=OK (2/1)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(inf:0x7f800000) flags=OK (2/2)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (3/0)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (3/1)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (3/2)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (4/0)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(-0x1.1874b000000000000000p+103:0xf30c3a58) flags=INEXACT  (4/1)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(-0x1.c0bab400000000000000p+99:0xf1605d5a) flags=INEXACT  (4/2)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(0x1.0c27fa00000000000000p+60:0x5d8613fd) flags=INEXACT  (5/0)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(-0x1.c0bab400000000000000p+99:0xf1605d5a) flags=INEXACT  (5/1)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(0x1.26c46200000000000000p+34:0x50936231) flags=INEXACT  (5/2)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(0x1.91f94000000000000000p-106:0x0ac8fca0) flags=INEXACT  (6/0)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(-0x1.31f74e00000000000000p-40:0xab98fba7) flags=INEXACT  (6/1)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(-0x1.50544200000000000000p-66:0x9ea82a21) flags=INEXACT  (6/2)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT  (7/0)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=OK (7/1)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (7/2)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (8/0)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (8/1)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(-0x0.00000000000000000000p+0:0x80000000) flags=UNDERFLOW INEXACT  (8/2)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00000000000000000000p-25:0x33000000) flags=OK (9/0)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT  (9/1)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (9/2)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.ffffe800000000000000p-25:0x337ffff4) flags=INEXACT  (10/0)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.ffffe800000000000000p-50:0x26fffff4) flags=INEXACT  (10/1)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00000200000000000000p-25:0x33000001) flags=INEXACT  (10/2)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ff801c00000000000000p-15:0x387fc00e) flags=INEXACT  (11/0)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00080000000000000000p-25:0x33000400) flags=INEXACT  (11/1)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.0001f400000000000000p-24:0x338000fa) flags=INEXACT  (11/2)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.00000e00000000000000p-14:0x38800007) flags=INEXACT  (12/0)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.0ffbf600000000000000p-24:0x3387fdfb) flags=INEXACT  (12/1)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ff801c00000000000000p-15:0x387fc00e) flags=INEXACT  (12/2)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.00000200000000000000p+0:0x3f800001) flags=INEXACT  (13/0)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ffc01a00000000000000p-14:0x38ffe00d) flags=INEXACT  (13/1)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.ffc01a00000000000000p-14:0x38ffe00d) flags=INEXACT  (13/2)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.00440200000000000000p+0:0x3f802201) flags=INEXACT  (14/0)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.00440200000000000000p+0:0x3f802201) flags=INEXACT  (14/1)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.00040200000000000000p+0:0x3f800201) flags=INEXACT  (14/2)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.80200000000000000000p+1:0x40401000) flags=OK (15/0)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.80400000000000000000p+1:0x40402000) flags=OK (15/1)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.80200000000000000000p+1:0x40401000) flags=OK (15/2)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.2e185400000000000000p+2:0x40970c2a) flags=OK (16/0)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.9c00a800000000000000p+2:0x40ce0054) flags=OK (16/1)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.2e23d400000000000000p+2:0x409711ea) flags=INEXACT  (16/2)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.12804200000000000000p+3:0x41094021) flags=INEXACT  (17/0)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.51458200000000000000p+3:0x4128a2c1) flags=INEXACT  (17/1)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.200c0600000000000000p+3:0x41100603) flags=INEXACT  (17/2)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.ffcf1600000000000000p+15:0x477fe78b) flags=INEXACT  (18/0)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.91ed3c00000000000000p+17:0x4848f69e) flags=INEXACT  (18/1)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.5bc56200000000000000p+17:0x482de2b1) flags=INEXACT  (18/2)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.08edf000000000000000p+18:0x488476f8) flags=INEXACT  (19/0)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.ff7e0a00000000000000p+31:0x4f7fbf05) flags=INEXACT  (19/1)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.08ee7a00000000000000p+18:0x4884773d) flags=INEXACT  (19/2)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff800a00000000000000p+31:0x4f7fc005) flags=INEXACT  (20/0)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.ff840800000000000000p+31:0x4f7fc204) flags=INEXACT  (20/1)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.ff820800000000000000p+31:0x4f7fc104) flags=INEXACT  (20/2)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff860800000000000000p+31:0x4f7fc304) flags=INEXACT  (21/0)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.ff820800000000000000p+32:0x4fffc104) flags=INEXACT  (21/1)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff800a00000000000000p+32:0x4fffc005) flags=INEXACT  (21/2)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.ff830800000000000000p+32:0x4fffc184) flags=INEXACT  (22/0)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff7f8a00000000000000p+33:0x507fbfc5) flags=INEXACT  (22/1)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff840800000000000000p+32:0x4fffc204) flags=INEXACT  (22/2)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.ff800a00000000000000p+33:0x507fc005) flags=INEXACT  (23/0)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff820800000000000000p+33:0x507fc104) flags=INEXACT  (23/1)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.ff810800000000000000p+33:0x507fc084) flags=INEXACT  (23/2)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(0x1.c0bab800000000000000p+99:0x71605d5c) flags=INEXACT  (24/0)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.c0838000000000000000p+116:0x79e041c0) flags=INEXACT  (24/1)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.c082a000000000000000p+116:0x79e04150) flags=INEXACT  (24/2)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (25/0)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (25/1)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(inf:0x7f800000) flags=OVERFLOW INEXACT  (25/2)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000)
+res: f32(inf:0x7f800000) flags=OK (26/0)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(inf:0x7f800000) flags=OK (26/1)
+op : f32(inf:0x7f800000) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(inf:0x7f800000) flags=OK (26/2)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fc00000) flags=OK (27/0)
+op : f32(inf:0x7f800000) * f32(nan:0x7fc00000) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(nan:0x7fc00000) flags=OK (27/1)
+op : f32(nan:0x7fc00000) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000)
+res: f32(nan:0x7fc00000) flags=OK (27/2)
+op : f32(inf:0x7f800000) * f32(nan:0x7fc00000) + f32(nan:0x7fa00000)
+res: f32(nan:0x7fe00000) flags=INVALID (28/0)
+op : f32(nan:0x7fc00000) * f32(nan:0x7fa00000) + f32(inf:0x7f800000)
+res: f32(nan:0x7fc00000) flags=INVALID (28/1)
+op : f32(nan:0x7fa00000) * f32(inf:0x7f800000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (28/2)
+op : f32(nan:0x7fc00000) * f32(nan:0x7fa00000) + f32(-nan:0xffa00000)
+res: f32(nan:0x7fc00000) flags=INVALID (29/0)
+op : f32(nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (29/1)
+op : f32(-nan:0xffa00000) * f32(nan:0x7fc00000) + f32(nan:0x7fa00000)
+res: f32(-nan:0xffe00000) flags=INVALID (29/2)
+op : f32(nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (30/0)
+op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(nan:0x7fa00000)
+res: f32(-nan:0xffe00000) flags=INVALID (30/1)
+op : f32(-nan:0xffc00000) * f32(nan:0x7fa00000) + f32(-nan:0xffa00000)
+res: f32(-nan:0xffc00000) flags=INVALID (30/2)
+# LP184149
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-1:0x3f000000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=OK (31/0)
+op : f32(0x1.00000000000000000000p-149:0x00000001) * f32(0x1.00000000000000000000p-149:0x00000001) + f32(0x1.00000000000000000000p-149:0x00000001)
+res: f32(0x1.00000000000000000000p-148:0x00000002) flags=UNDERFLOW INEXACT  (32/0)
+### Rounding downwards
+op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-inf:0xff800000)
+res: f32(-nan:0xffe00000) flags=INVALID (0/0)
+op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-nan:0xffa00000)
+res: f32(-nan:0xffc00000) flags=INVALID (0/1)
+op : f32(-inf:0xff800000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000)
+res: f32(-nan:0xffc00000) flags=INVALID (0/2)
+op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(-nan:0xffc00000) flags=OK (1/0)
+op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-nan:0xffc00000)
+res: f32(-nan:0xffc00000) flags=OK (1/1)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-nan:0xffc00000) + f32(-inf:0xff800000)
+res: f32(-nan:0xffc00000) flags=OK (1/2)
+op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(inf:0x7f800000) flags=OK (2/0)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-inf:0xff800000)
+res: f32(-inf:0xff800000) flags=OK (2/1)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(inf:0x7f800000) flags=OK (2/2)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (3/0)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (3/1)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (3/2)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (4/0)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(-0x1.1874b200000000000000p+103:0xf30c3a59) flags=INEXACT  (4/1)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) flags=INEXACT  (4/2)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(0x1.0c27f800000000000000p+60:0x5d8613fc) flags=INEXACT  (5/0)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) flags=INEXACT  (5/1)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(0x1.26c46000000000000000p+34:0x50936230) flags=INEXACT  (5/2)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(0x1.91f93e00000000000000p-106:0x0ac8fc9f) flags=INEXACT  (6/0)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(-0x1.31f75000000000000000p-40:0xab98fba8) flags=INEXACT  (6/1)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=INEXACT  (6/2)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT  (7/0)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=OK (7/1)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (7/2)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (8/0)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (8/1)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(-0x1.00000000000000000000p-149:0x80000001) flags=UNDERFLOW INEXACT  (8/2)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00000000000000000000p-25:0x33000000) flags=OK (9/0)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT  (9/1)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (9/2)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.ffffe600000000000000p-25:0x337ffff3) flags=INEXACT  (10/0)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.ffffe600000000000000p-50:0x26fffff3) flags=INEXACT  (10/1)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00000000000000000000p-25:0x33000000) flags=INEXACT  (10/2)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT  (11/0)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.0007fe00000000000000p-25:0x330003ff) flags=INEXACT  (11/1)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.0001f200000000000000p-24:0x338000f9) flags=INEXACT  (11/2)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.00000c00000000000000p-14:0x38800006) flags=INEXACT  (12/0)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.0ffbf400000000000000p-24:0x3387fdfa) flags=INEXACT  (12/1)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT  (12/2)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.00000000000000000000p+0:0x3f800000) flags=INEXACT  (13/0)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT  (13/1)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT  (13/2)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT  (14/0)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT  (14/1)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.00040000000000000000p+0:0x3f800200) flags=INEXACT  (14/2)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.80200000000000000000p+1:0x40401000) flags=OK (15/0)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.80400000000000000000p+1:0x40402000) flags=OK (15/1)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.80200000000000000000p+1:0x40401000) flags=OK (15/2)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.2e185400000000000000p+2:0x40970c2a) flags=OK (16/0)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.9c00a800000000000000p+2:0x40ce0054) flags=OK (16/1)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.2e23d200000000000000p+2:0x409711e9) flags=INEXACT  (16/2)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.12804000000000000000p+3:0x41094020) flags=INEXACT  (17/0)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.51458000000000000000p+3:0x4128a2c0) flags=INEXACT  (17/1)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.200c0400000000000000p+3:0x41100602) flags=INEXACT  (17/2)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.ffcf1400000000000000p+15:0x477fe78a) flags=INEXACT  (18/0)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.91ed3a00000000000000p+17:0x4848f69d) flags=INEXACT  (18/1)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.5bc56000000000000000p+17:0x482de2b0) flags=INEXACT  (18/2)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.08edee00000000000000p+18:0x488476f7) flags=INEXACT  (19/0)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.ff7e0800000000000000p+31:0x4f7fbf04) flags=INEXACT  (19/1)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.08ee7800000000000000p+18:0x4884773c) flags=INEXACT  (19/2)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff800800000000000000p+31:0x4f7fc004) flags=INEXACT  (20/0)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.ff840600000000000000p+31:0x4f7fc203) flags=INEXACT  (20/1)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.ff820600000000000000p+31:0x4f7fc103) flags=INEXACT  (20/2)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff860600000000000000p+31:0x4f7fc303) flags=INEXACT  (21/0)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.ff820600000000000000p+32:0x4fffc103) flags=INEXACT  (21/1)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff800800000000000000p+32:0x4fffc004) flags=INEXACT  (21/2)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.ff830600000000000000p+32:0x4fffc183) flags=INEXACT  (22/0)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff7f8800000000000000p+33:0x507fbfc4) flags=INEXACT  (22/1)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff840600000000000000p+32:0x4fffc203) flags=INEXACT  (22/2)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.ff800800000000000000p+33:0x507fc004) flags=INEXACT  (23/0)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff820600000000000000p+33:0x507fc103) flags=INEXACT  (23/1)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.ff810600000000000000p+33:0x507fc083) flags=INEXACT  (23/2)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(0x1.c0bab600000000000000p+99:0x71605d5b) flags=INEXACT  (24/0)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.c0837e00000000000000p+116:0x79e041bf) flags=INEXACT  (24/1)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.c0829e00000000000000p+116:0x79e0414f) flags=INEXACT  (24/2)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (25/0)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (25/1)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (25/2)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000)
+res: f32(inf:0x7f800000) flags=OK (26/0)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(inf:0x7f800000) flags=OK (26/1)
+op : f32(inf:0x7f800000) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(inf:0x7f800000) flags=OK (26/2)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fc00000) flags=OK (27/0)
+op : f32(inf:0x7f800000) * f32(nan:0x7fc00000) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(nan:0x7fc00000) flags=OK (27/1)
+op : f32(nan:0x7fc00000) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000)
+res: f32(nan:0x7fc00000) flags=OK (27/2)
+op : f32(inf:0x7f800000) * f32(nan:0x7fc00000) + f32(nan:0x7fa00000)
+res: f32(nan:0x7fe00000) flags=INVALID (28/0)
+op : f32(nan:0x7fc00000) * f32(nan:0x7fa00000) + f32(inf:0x7f800000)
+res: f32(nan:0x7fc00000) flags=INVALID (28/1)
+op : f32(nan:0x7fa00000) * f32(inf:0x7f800000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (28/2)
+op : f32(nan:0x7fc00000) * f32(nan:0x7fa00000) + f32(-nan:0xffa00000)
+res: f32(nan:0x7fc00000) flags=INVALID (29/0)
+op : f32(nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (29/1)
+op : f32(-nan:0xffa00000) * f32(nan:0x7fc00000) + f32(nan:0x7fa00000)
+res: f32(-nan:0xffe00000) flags=INVALID (29/2)
+op : f32(nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (30/0)
+op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(nan:0x7fa00000)
+res: f32(-nan:0xffe00000) flags=INVALID (30/1)
+op : f32(-nan:0xffc00000) * f32(nan:0x7fa00000) + f32(-nan:0xffa00000)
+res: f32(-nan:0xffc00000) flags=INVALID (30/2)
+# LP184149
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-1:0x3f000000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=OK (31/0)
+op : f32(0x1.00000000000000000000p-149:0x00000001) * f32(0x1.00000000000000000000p-149:0x00000001) + f32(0x1.00000000000000000000p-149:0x00000001)
+res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT  (32/0)
+### Rounding to zero
+op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(-inf:0xff800000)
+res: f32(-nan:0xffe00000) flags=INVALID (0/0)
+op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-nan:0xffa00000)
+res: f32(-nan:0xffc00000) flags=INVALID (0/1)
+op : f32(-inf:0xff800000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000)
+res: f32(-nan:0xffc00000) flags=INVALID (0/2)
+op : f32(-nan:0xffc00000) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(-nan:0xffc00000) flags=OK (1/0)
+op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-nan:0xffc00000)
+res: f32(-nan:0xffc00000) flags=OK (1/1)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-nan:0xffc00000) + f32(-inf:0xff800000)
+res: f32(-nan:0xffc00000) flags=OK (1/2)
+op : f32(-inf:0xff800000) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(inf:0x7f800000) flags=OK (2/0)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-inf:0xff800000)
+res: f32(-inf:0xff800000) flags=OK (2/1)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-inf:0xff800000) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(inf:0x7f800000) flags=OK (2/2)
+op : f32(-0x1.fffffe00000000000000p+127:0xff7fffff) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (3/0)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.fffffe00000000000000p+127:0xff7fffff)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (3/1)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.fffffe00000000000000p+127:0xff7fffff) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (3/2)
+op : f32(-0x1.1874b200000000000000p+103:0xf30c3a59) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (4/0)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.1874b200000000000000p+103:0xf30c3a59)
+res: f32(-0x1.1874b000000000000000p+103:0xf30c3a58) flags=INEXACT  (4/1)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.1874b200000000000000p+103:0xf30c3a59) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(-0x1.c0bab400000000000000p+99:0xf1605d5a) flags=INEXACT  (4/2)
+op : f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(0x1.0c27f800000000000000p+60:0x5d8613fc) flags=INEXACT  (5/0)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.c0bab600000000000000p+99:0xf1605d5b)
+res: f32(-0x1.c0bab400000000000000p+99:0xf1605d5a) flags=INEXACT  (5/1)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.c0bab600000000000000p+99:0xf1605d5b) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(0x1.26c46000000000000000p+34:0x50936230) flags=INEXACT  (5/2)
+op : f32(-0x1.31f75000000000000000p-40:0xab98fba8) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(0x1.91f93e00000000000000p-106:0x0ac8fc9f) flags=INEXACT  (6/0)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(-0x1.31f75000000000000000p-40:0xab98fba8)
+res: f32(-0x1.31f74e00000000000000p-40:0xab98fba7) flags=INEXACT  (6/1)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(-0x1.31f75000000000000000p-40:0xab98fba8) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(-0x1.50544200000000000000p-66:0x9ea82a21) flags=INEXACT  (6/2)
+op : f32(-0x1.50544400000000000000p-66:0x9ea82a22) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT  (7/0)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(-0x1.50544400000000000000p-66:0x9ea82a22)
+res: f32(-0x1.50544400000000000000p-66:0x9ea82a22) flags=OK (7/1)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(-0x1.50544400000000000000p-66:0x9ea82a22) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (7/2)
+op : f32(-0x1.00000000000000000000p-126:0x80800000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (8/0)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(-0x1.00000000000000000000p-126:0x80800000)
+res: f32(-0x1.00000000000000000000p-126:0x80800000) flags=OK (8/1)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(-0x1.00000000000000000000p-126:0x80800000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(-0x0.00000000000000000000p+0:0x80000000) flags=UNDERFLOW INEXACT  (8/2)
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00000000000000000000p-25:0x33000000) flags=OK (9/0)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=UNDERFLOW INEXACT  (9/1)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x0.00000000000000000000p+0:0000000000) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.00000000000000000000p-126:0x00800000) flags=OK (9/2)
+op : f32(0x1.00000000000000000000p-126:0x00800000) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.ffffe600000000000000p-25:0x337ffff3) flags=INEXACT  (10/0)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.00000000000000000000p-126:0x00800000)
+res: f32(0x1.ffffe600000000000000p-50:0x26fffff3) flags=INEXACT  (10/1)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.00000000000000000000p-126:0x00800000) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.00000000000000000000p-25:0x33000000) flags=INEXACT  (10/2)
+op : f32(0x1.00000000000000000000p-25:0x33000000) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT  (11/0)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000000000000000000p-25:0x33000000)
+res: f32(0x1.0007fe00000000000000p-25:0x330003ff) flags=INEXACT  (11/1)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000000000000000000p-25:0x33000000) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.0001f200000000000000p-24:0x338000f9) flags=INEXACT  (11/2)
+op : f32(0x1.ffffe600000000000000p-25:0x337ffff3) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.00000c00000000000000p-14:0x38800006) flags=INEXACT  (12/0)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.ffffe600000000000000p-25:0x337ffff3)
+res: f32(0x1.0ffbf400000000000000p-24:0x3387fdfa) flags=INEXACT  (12/1)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.ffffe600000000000000p-25:0x337ffff3) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ff801a00000000000000p-15:0x387fc00d) flags=INEXACT  (12/2)
+op : f32(0x1.ff801a00000000000000p-15:0x387fc00d) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.00000000000000000000p+0:0x3f800000) flags=INEXACT  (13/0)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.ff801a00000000000000p-15:0x387fc00d)
+res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT  (13/1)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.ff801a00000000000000p-15:0x387fc00d) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.ffc01800000000000000p-14:0x38ffe00c) flags=INEXACT  (13/2)
+op : f32(0x1.00000c00000000000000p-14:0x38800006) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT  (14/0)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000c00000000000000p-14:0x38800006)
+res: f32(0x1.00440000000000000000p+0:0x3f802200) flags=INEXACT  (14/1)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000c00000000000000p-14:0x38800006) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.00040000000000000000p+0:0x3f800200) flags=INEXACT  (14/2)
+op : f32(0x1.00000000000000000000p+0:0x3f800000) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.80200000000000000000p+1:0x40401000) flags=OK (15/0)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.00000000000000000000p+0:0x3f800000)
+res: f32(0x1.80400000000000000000p+1:0x40402000) flags=OK (15/1)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.00000000000000000000p+0:0x3f800000) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.80200000000000000000p+1:0x40401000) flags=OK (15/2)
+op : f32(0x1.00400000000000000000p+0:0x3f802000) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.2e185400000000000000p+2:0x40970c2a) flags=OK (16/0)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.00400000000000000000p+0:0x3f802000)
+res: f32(0x1.9c00a800000000000000p+2:0x40ce0054) flags=OK (16/1)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.00400000000000000000p+0:0x3f802000) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.2e23d200000000000000p+2:0x409711e9) flags=INEXACT  (16/2)
+op : f32(0x1.00000000000000000000p+1:0x40000000) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.12804000000000000000p+3:0x41094020) flags=INEXACT  (17/0)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.00000000000000000000p+1:0x40000000)
+res: f32(0x1.51458000000000000000p+3:0x4128a2c0) flags=INEXACT  (17/1)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.00000000000000000000p+1:0x40000000) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.200c0400000000000000p+3:0x41100602) flags=INEXACT  (17/2)
+op : f32(0x1.5bf0a800000000000000p+1:0x402df854) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.ffcf1400000000000000p+15:0x477fe78a) flags=INEXACT  (18/0)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.5bf0a800000000000000p+1:0x402df854)
+res: f32(0x1.91ed3a00000000000000p+17:0x4848f69d) flags=INEXACT  (18/1)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.5bf0a800000000000000p+1:0x402df854) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.5bc56000000000000000p+17:0x482de2b0) flags=INEXACT  (18/2)
+op : f32(0x1.921fb600000000000000p+1:0x40490fdb) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.08edee00000000000000p+18:0x488476f7) flags=INEXACT  (19/0)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.921fb600000000000000p+1:0x40490fdb)
+res: f32(0x1.ff7e0800000000000000p+31:0x4f7fbf04) flags=INEXACT  (19/1)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.921fb600000000000000p+1:0x40490fdb) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.08ee7800000000000000p+18:0x4884773c) flags=INEXACT  (19/2)
+op : f32(0x1.ffbe0000000000000000p+15:0x477fdf00) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff800800000000000000p+31:0x4f7fc004) flags=INEXACT  (20/0)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbe0000000000000000p+15:0x477fdf00)
+res: f32(0x1.ff840600000000000000p+31:0x4f7fc203) flags=INEXACT  (20/1)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbe0000000000000000p+15:0x477fdf00) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.ff820600000000000000p+31:0x4f7fc103) flags=INEXACT  (20/2)
+op : f32(0x1.ffc00000000000000000p+15:0x477fe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff860600000000000000p+31:0x4f7fc303) flags=INEXACT  (21/0)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+15:0x477fe000)
+res: f32(0x1.ff820600000000000000p+32:0x4fffc103) flags=INEXACT  (21/1)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+15:0x477fe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff800800000000000000p+32:0x4fffc004) flags=INEXACT  (21/2)
+op : f32(0x1.ffc20000000000000000p+15:0x477fe100) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.ff830600000000000000p+32:0x4fffc183) flags=INEXACT  (22/0)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc20000000000000000p+15:0x477fe100)
+res: f32(0x1.ff7f8800000000000000p+33:0x507fbfc4) flags=INEXACT  (22/1)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc20000000000000000p+15:0x477fe100) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff840600000000000000p+32:0x4fffc203) flags=INEXACT  (22/2)
+op : f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.ff800800000000000000p+33:0x507fc004) flags=INEXACT  (23/0)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.ffbf0000000000000000p+16:0x47ffdf80)
+res: f32(0x1.ff820600000000000000p+33:0x507fc103) flags=INEXACT  (23/1)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.ffbf0000000000000000p+16:0x47ffdf80) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.ff810600000000000000p+33:0x507fc083) flags=INEXACT  (23/2)
+op : f32(0x1.ffc00000000000000000p+16:0x47ffe000) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(0x1.c0bab600000000000000p+99:0x71605d5b) flags=INEXACT  (24/0)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.ffc00000000000000000p+16:0x47ffe000)
+res: f32(0x1.c0837e00000000000000p+116:0x79e041bf) flags=INEXACT  (24/1)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.ffc00000000000000000p+16:0x47ffe000) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.c0829e00000000000000p+116:0x79e0414f) flags=INEXACT  (24/2)
+op : f32(0x1.ffc10000000000000000p+16:0x47ffe080) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (25/0)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(0x1.ffc10000000000000000p+16:0x47ffe080)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (25/1)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(0x1.ffc10000000000000000p+16:0x47ffe080) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(0x1.fffffe00000000000000p+127:0x7f7fffff) flags=OVERFLOW INEXACT  (25/2)
+op : f32(0x1.c0bab600000000000000p+99:0x71605d5b) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000)
+res: f32(inf:0x7f800000) flags=OK (26/0)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(0x1.c0bab600000000000000p+99:0x71605d5b)
+res: f32(inf:0x7f800000) flags=OK (26/1)
+op : f32(inf:0x7f800000) * f32(0x1.c0bab600000000000000p+99:0x71605d5b) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(inf:0x7f800000) flags=OK (26/2)
+op : f32(0x1.fffffe00000000000000p+127:0x7f7fffff) * f32(inf:0x7f800000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fc00000) flags=OK (27/0)
+op : f32(inf:0x7f800000) * f32(nan:0x7fc00000) + f32(0x1.fffffe00000000000000p+127:0x7f7fffff)
+res: f32(nan:0x7fc00000) flags=OK (27/1)
+op : f32(nan:0x7fc00000) * f32(0x1.fffffe00000000000000p+127:0x7f7fffff) + f32(inf:0x7f800000)
+res: f32(nan:0x7fc00000) flags=OK (27/2)
+op : f32(inf:0x7f800000) * f32(nan:0x7fc00000) + f32(nan:0x7fa00000)
+res: f32(nan:0x7fe00000) flags=INVALID (28/0)
+op : f32(nan:0x7fc00000) * f32(nan:0x7fa00000) + f32(inf:0x7f800000)
+res: f32(nan:0x7fc00000) flags=INVALID (28/1)
+op : f32(nan:0x7fa00000) * f32(inf:0x7f800000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (28/2)
+op : f32(nan:0x7fc00000) * f32(nan:0x7fa00000) + f32(-nan:0xffa00000)
+res: f32(nan:0x7fc00000) flags=INVALID (29/0)
+op : f32(nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(nan:0x7fc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (29/1)
+op : f32(-nan:0xffa00000) * f32(nan:0x7fc00000) + f32(nan:0x7fa00000)
+res: f32(-nan:0xffe00000) flags=INVALID (29/2)
+op : f32(nan:0x7fa00000) * f32(-nan:0xffa00000) + f32(-nan:0xffc00000)
+res: f32(nan:0x7fe00000) flags=INVALID (30/0)
+op : f32(-nan:0xffa00000) * f32(-nan:0xffc00000) + f32(nan:0x7fa00000)
+res: f32(-nan:0xffe00000) flags=INVALID (30/1)
+op : f32(-nan:0xffc00000) * f32(nan:0x7fa00000) + f32(-nan:0xffa00000)
+res: f32(-nan:0xffc00000) flags=INVALID (30/2)
+# LP184149
+op : f32(0x0.00000000000000000000p+0:0000000000) * f32(0x1.00000000000000000000p-1:0x3f000000) + f32(0x0.00000000000000000000p+0:0000000000)
+res: f32(0x0.00000000000000000000p+0:0000000000) flags=OK (31/0)
+op : f32(0x1.00000000000000000000p-149:0x00000001) * f32(0x1.00000000000000000000p-149:0x00000001) + f32(0x1.00000000000000000000p-149:0x00000001)
+res: f32(0x1.00000000000000000000p-149:0x00000001) flags=UNDERFLOW INEXACT  (32/0)
-- 
2.25.1



^ permalink raw reply related	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  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
  0 siblings, 1 reply; 51+ messages in thread
From: Cédric Le Goater @ 2021-11-21 17:47 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/19/21 17:05, Richard Henderson wrote:
> Generated on Power9, PowerNV 9006-22P.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>   tests/tcg/ppc64le/float_convs.ref | 748 +++++++++++++++++++++++++++++
>   tests/tcg/ppc64le/float_madds.ref | 768 ++++++++++++++++++++++++++++++
>   2 files changed, 1516 insertions(+)
>   create mode 100644 tests/tcg/ppc64le/float_convs.ref
>   create mode 100644 tests/tcg/ppc64le/float_madds.ref
> 
> diff --git a/tests/tcg/ppc64le/float_convs.ref b/tests/tcg/ppc64le/float_convs.ref
> new file mode 100644
> index 0000000000..6e6f636834
> --- /dev/null
> +++ b/tests/tcg/ppc64le/float_convs.ref
> @@ -0,0 +1,748 @@
> +### Rounding to nearest
> +from single: f32(-nan:0xffa00000)
> +  to double: f64(-nan:0x00fff4000000000000) (OK)
> +   to int32: -2147483648 (INVALID)
> +   to int64: -9223372036854775808 (INVALID)
> +  to uint32: 0 (INVALID)
> +  to uint64: 0 (INVALID)


I am getting an error with this test. See below.

C.




make[2]: Leaving directory '/home/legoater/work/qemu/qemu-ppc-7.0.git/build/tests/tcg/ppc64le-linux-user'
(cd tests/tcg/ppc64le-linux-user && make -f ../Makefile.target TARGET="ppc64le-linux-user" SRC_PATH="/home/legoater/work/qemu/qemu-ppc-7.0.git" SPEED=quick run)
make[2]: Entering directory '/home/legoater/work/qemu/qemu-ppc-7.0.git/build/tests/tcg/ppc64le-linux-user'
timeout --foreground 15  /home/legoater/work/qemu/qemu-ppc-7.0.git/build/qemu-ppc64le  float_convs > float_convs.out
diff -q float_convs.out /home/legoater/work/qemu/qemu-ppc-7.0.git/tests/tcg/ppc64le/float_convs.ref || (diff -u float_convs.out /home/legoater/work/qemu/qemu-ppc-7.0.git/tests/tcg/ppc64le/float_convs.ref | head -n 10 && false)
Files float_convs.out and /home/legoater/work/qemu/qemu-ppc-7.0.git/tests/tcg/ppc64le/float_convs.ref differ
--- float_convs.out	2021-11-21 12:39:33.911946974 -0500
+++ /home/legoater/work/qemu/qemu-ppc-7.0.git/tests/tcg/ppc64le/float_convs.ref	2021-11-21 09:43:12.946774006 -0500
@@ -1,6 +1,6 @@
  ### Rounding to nearest
  from single: f32(-nan:0xffa00000)
-  to double: f64(-nan:0x00fff4000000000000) (INVALID)
+  to double: f64(-nan:0x00fff4000000000000) (OK)
     to int32: -2147483648 (INVALID)
     to int64: -9223372036854775808 (INVALID)
    to uint32: 0 (INVALID)




^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  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
  0 siblings, 2 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-22  9:43 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/21/21 6:47 PM, Cédric Le Goater wrote:
> I am getting an error with this test. See below.
...
>   ### Rounding to nearest
>   from single: f32(-nan:0xffa00000)
> -  to double: f64(-nan:0x00fff4000000000000) (INVALID)
> +  to double: f64(-nan:0x00fff4000000000000) (OK)

Well that's disconcerting.

I can replicate this failure on an x86_64 host, but do not see the same error on a power9 
ppc64le host.


r~


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  2021-11-22  9:43     ` Richard Henderson
@ 2021-11-22  9:51       ` Cédric Le Goater
  2021-11-22 11:16       ` Richard Henderson
  1 sibling, 0 replies; 51+ messages in thread
From: Cédric Le Goater @ 2021-11-22  9:51 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/22/21 10:43, Richard Henderson wrote:
> On 11/21/21 6:47 PM, Cédric Le Goater wrote:
>> I am getting an error with this test. See below.
> ...
>>   ### Rounding to nearest
>>   from single: f32(-nan:0xffa00000)
>> -  to double: f64(-nan:0x00fff4000000000000) (INVALID)
>> +  to double: f64(-nan:0x00fff4000000000000) (OK)
> 
> Well that's disconcerting.
> 
> I can replicate this failure on an x86_64 host, but do not see the 
> same error on a power9 ppc64le host.

I do replicate on both x86_64 (rh9) and POWER9 (21.10).

The same ref file on 4 different P9 systems looks the same. make
check-tcg is behaving fine with it.

Updated here :

   https://gitlab.com/legoater/qemu/-/commit/3d5ab4afaa50c3771b9d3bc74bfd04d992dc3a07

CI in progress :

   https://gitlab.com/legoater/qemu/-/pipelines/413705207

C.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  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-29 14:45         ` Cédric Le Goater
  1 sibling, 2 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-22 11:16 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/22/21 10:43 AM, Richard Henderson wrote:
> On 11/21/21 6:47 PM, Cédric Le Goater wrote:
>> I am getting an error with this test. See below.
> ...
>>   ### Rounding to nearest
>>   from single: f32(-nan:0xffa00000)
>> -  to double: f64(-nan:0x00fff4000000000000) (INVALID)
>> +  to double: f64(-nan:0x00fff4000000000000) (OK)
> 
> Well that's disconcerting.
> 
> I can replicate this failure on an x86_64 host, but do not see the same error on a power9 
> ppc64le host.

Bah.  The test case is buggy.

It reads the fpscr for the flags *after* having gone through the printf for the result, at 
which point you are at the mercy of whatever other fp arithmetic libc chooses to do.

Fixed with

--- a/tests/tcg/multiarch/float_convs.c
+++ b/tests/tcg/multiarch/float_convs.c
@@ -51,8 +51,8 @@ static void convert_single_to_double(float input)

      output = input;

-    out_fmt = fmt_f64(output);
      flag_fmt = fmt_flags();
+    out_fmt = fmt_f64(output);
      printf("  to double: %s (%s)\n", out_fmt, flag_fmt);
      free(out_fmt);
      free(flag_fmt);

But this alone of course causes other "failures", because we've got some incorrect 
reference files.


r~


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  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-29 14:45         ` Cédric Le Goater
  1 sibling, 1 reply; 51+ messages in thread
From: Cédric Le Goater @ 2021-11-22 13:04 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/22/21 12:16, Richard Henderson wrote:
> On 11/22/21 10:43 AM, Richard Henderson wrote:
>> On 11/21/21 6:47 PM, Cédric Le Goater wrote:
>>> I am getting an error with this test. See below.
>> ...
>>>   ### Rounding to nearest
>>>   from single: f32(-nan:0xffa00000)
>>> -  to double: f64(-nan:0x00fff4000000000000) (INVALID)
>>> +  to double: f64(-nan:0x00fff4000000000000) (OK)
>>
>> Well that's disconcerting.
>>
>> I can replicate this failure on an x86_64 host, but do not see the same error on a power9 ppc64le host.
> 
> Bah.  The test case is buggy.
> 
> It reads the fpscr for the flags *after* having gone through the printf for the result, at which point you are at the mercy of whatever other fp arithmetic libc chooses to do.
> 
> Fixed with
> 
> --- a/tests/tcg/multiarch/float_convs.c
> +++ b/tests/tcg/multiarch/float_convs.c
> @@ -51,8 +51,8 @@ static void convert_single_to_double(float input)
> 
>       output = input;
> 
> -    out_fmt = fmt_f64(output);
>       flag_fmt = fmt_flags();
> +    out_fmt = fmt_f64(output);
>       printf("  to double: %s (%s)\n", out_fmt, flag_fmt);
>       free(out_fmt);
>       free(flag_fmt);
> 
> But this alone of course causes other "failures", because we've got some incorrect reference files.

Looks fine. Will you send this patch independently ?

The patchset doesn't seem to break anything.

Thanks,

C.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  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
  0 siblings, 1 reply; 51+ messages in thread
From: Richard Henderson @ 2021-11-22 13:14 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/22/21 2:04 PM, Cédric Le Goater wrote:
>> But this alone of course causes other "failures", because we've got some incorrect 
>> reference files.
> 
> Looks fine. Will you send this patch independently ?

Yes.

> The patchset doesn't seem to break anything.

You may not have docker cross-compilers enabled.
The hexagon reference files have incorrect contents.
I'll pursue an update with Taylor.


r~


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  2021-11-22 13:14           ` Richard Henderson
@ 2021-11-24  9:17             ` Cédric Le Goater
  2021-11-24  9:27               ` Richard Henderson
  0 siblings, 1 reply; 51+ messages in thread
From: Cédric Le Goater @ 2021-11-24  9:17 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/22/21 14:14, Richard Henderson wrote:
> On 11/22/21 2:04 PM, Cédric Le Goater wrote:
>>> But this alone of course causes other "failures", because we've got some incorrect reference files.
>>
>> Looks fine. Will you send this patch independently ?
> 
> Yes.
> 
>> The patchset doesn't seem to break anything.
> 
> You may not have docker cross-compilers enabled.
> The hexagon reference files have incorrect contents.
> I'll pursue an update with Taylor.


I do now. That was not an easy task. All seem fine with a x86/RH9
but I am having issues building the images on power9/ubuntu21.10.

centos8 fails with :
   #6 41.69 Error: Unable to find a match: libpmem-devel spice-server-devel

and some others with :

   #5 3.433  builddeps:qemu : Depends: gcc-s390x-linux-gnu but it is not installable
   #5 3.433                   Depends: gcc-alpha-linux-gnu but it is not installable
   #5 3.256 E: Unable to locate package gcc-hppa-linux-gnu

Is that expected ?


Also I am seeing this issue on RH9 when running gdb tests :

   TEST    basic gdbstub support
warning: Remote gdbserver does not support determining executable automatically.
RHEL <=6.8 and <=7.2 versions of gdbserver do not support such automatic executable detection.
The following versions of gdbserver support it:
- Upstream version of gdbserver (unsupported) 7.10 or later
- Red Hat Developer Toolset (DTS) version of gdbserver from DTS 4.0 or later (only on x86_64)
- RHEL-7.3 versions of gdbserver (on any architecture)

I will dig that one. May be it's from the gdb of RH.

Thanks,

C.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  2021-11-24  9:17             ` Cédric Le Goater
@ 2021-11-24  9:27               ` Richard Henderson
  0 siblings, 0 replies; 51+ messages in thread
From: Richard Henderson @ 2021-11-24  9:27 UTC (permalink / raw)
  To: Cédric Le Goater, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/24/21 10:17 AM, Cédric Le Goater wrote:
> I do now. That was not an easy task. All seem fine with a x86/RH9
> but I am having issues building the images on power9/ubuntu21.10.
> 
> centos8 fails with :
>    #6 41.69 Error: Unable to find a match: libpmem-devel spice-server-devel
> 
> and some others with :
> 
>    #5 3.433  builddeps:qemu : Depends: gcc-s390x-linux-gnu but it is not installable
>    #5 3.433                   Depends: gcc-alpha-linux-gnu but it is not installable
>    #5 3.256 E: Unable to locate package gcc-hppa-linux-gnu
> 
> Is that expected ?

Yes, most docker images are x86_64 only.  Alex knows more about trying to sort this out 
for aarch64, but mostly the cross-build packages are simply not available for other hosts.

> Also I am seeing this issue on RH9 when running gdb tests :
> 
>    TEST    basic gdbstub support
> warning: Remote gdbserver does not support determining executable automatically.
> RHEL <=6.8 and <=7.2 versions of gdbserver do not support such automatic executable 
> detection.
> The following versions of gdbserver support it:
> - Upstream version of gdbserver (unsupported) 7.10 or later
> - Red Hat Developer Toolset (DTS) version of gdbserver from DTS 4.0 or later (only on x86_64)
> - RHEL-7.3 versions of gdbserver (on any architecture)
> 
> I will dig that one. May be it's from the gdb of RH.

I've never seen this one.


r~


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 35/35] test/tcg/ppc64le: Add float reference files
  2021-11-22 11:16       ` Richard Henderson
  2021-11-22 13:04         ` Cédric Le Goater
@ 2021-11-29 14:45         ` Cédric Le Goater
  1 sibling, 0 replies; 51+ messages in thread
From: Cédric Le Goater @ 2021-11-29 14:45 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/22/21 12:16, Richard Henderson wrote:
> On 11/22/21 10:43 AM, Richard Henderson wrote:
>> On 11/21/21 6:47 PM, Cédric Le Goater wrote:
>>> I am getting an error with this test. See below.
>> ...
>>>   ### Rounding to nearest
>>>   from single: f32(-nan:0xffa00000)
>>> -  to double: f64(-nan:0x00fff4000000000000) (INVALID)
>>> +  to double: f64(-nan:0x00fff4000000000000) (OK)
>>
>> Well that's disconcerting.
>>
>> I can replicate this failure on an x86_64 host, but do not see the same error on a power9 ppc64le host.
> 
> Bah.  The test case is buggy.
> 
> It reads the fpscr for the flags *after* having gone through the printf for the result, at which point you are at the mercy of whatever other fp arithmetic libc chooses to do.
> 
> Fixed with
> 
> --- a/tests/tcg/multiarch/float_convs.c
> +++ b/tests/tcg/multiarch/float_convs.c
> @@ -51,8 +51,8 @@ static void convert_single_to_double(float input)
> 
>       output = input;
> 
> -    out_fmt = fmt_f64(output);
>       flag_fmt = fmt_flags();
> +    out_fmt = fmt_f64(output);
>       printf("  to double: %s (%s)\n", out_fmt, flag_fmt);
>       free(out_fmt);
>       free(flag_fmt);
> 
> But this alone of course causes other "failures", because we've got some incorrect reference files.

The only one I have seen so far is on hexagon:

   https://gitlab.com/legoater/qemu/-/jobs/1829273672

C.



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (34 preceding siblings ...)
  2021-11-19 16:05 ` [PATCH 35/35] test/tcg/ppc64le: Add float reference files Richard Henderson
@ 2021-12-03 10:36 ` Cédric Le Goater
  2021-12-03 16:10 ` Matheus K. Ferst
  2021-12-15 16:42 ` Cédric Le Goater
  37 siblings, 0 replies; 51+ messages in thread
From: Cédric Le Goater @ 2021-12-03 10:36 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/19/21 17:04, Richard Henderson wrote:
> This is a partial patch set showing the direction I believe
> the cleanups should go, as opposed to a complete conversion.
> 
> I add a bunch of float_flag_* bits that diagnose the reason
> for most float_flag_invalid, as guided by the requirements
> of the PowerPC VX* bits.  I have converted some helpers to
> use these new flags but not all.  A good signal for unconverted
> routines is the use of float*_is_signalling_nan, which should
> now be using float_flag_invalid_snan.
> 
> I added float64x32_* arithmetic routines, which take float64
> arguments and round the result to the range and precision of
> float32, while giving the result in float64 form.  This is
> exactly what PowerPC requires for its single-precision math.
> This fixes double-rounding problems that exist in the current
> code, and are visible in the float_madds test.
> 
> I add test reference files for float_madds and float_convs
> after fixing the bugs required to make the tests pass.
> 
> 
> r~
> 
> 
> Richard Henderson (35):
>    softfloat: Extend float_exception_flags to 16 bits
>    softfloat: Add flag specific to Inf - Inf
>    softfloat: Add flag specific to Inf * 0
>    softfloat: Add flags specific to Inf / Inf and 0 / 0
>    softfloat: Add flag specific to sqrt(-x)
>    softfloat: Add flag specific to convert non-nan to int
>    softfloat: Add flag specific to signaling nans
>    target/ppc: Update float_invalid_op_addsub for new flags
>    target/ppc: Update float_invalid_op_mul for new flags
>    target/ppc: Update float_invalid_op_div for new flags
>    target/ppc: Move float_check_status from FPU_FCTI to translate
>    target/ppc: Update float_invalid_cvt for new flags
>    target/ppc: Fix VXCVI return value
>    target/ppc: Remove inline from do_fri
>    target/ppc: Use FloatRoundMode in do_fri
>    target/ppc: Tidy inexact handling in do_fri
>    target/ppc: Clean up do_fri
>    target/ppc: Update fmadd for new flags
>    target/ppc: Split out do_fmadd
>    target/ppc: Do not call do_float_check_status from do_fmadd
>    target/ppc: Split out do_frsp
>    target/ppc: Update do_frsp for new flags
>    target/ppc: Use helper_todouble in do_frsp
>    target/ppc: Update sqrt for new flags
>    target/ppc: Update xsrqpi and xsrqpxp to new flags
>    target/ppc: Update fre to new flags
>    softfloat: Add float64r32 arithmetic routines
>    target/ppc: Add helpers for fmadds et al
>    target/ppc: Add helper for fsqrts
>    target/ppc: Add helpers for fadds, fsubs, fdivs
>    target/ppc: Add helper for fmuls
>    target/ppc: Add helper for frsqrtes
>    target/ppc: Update fres to new flags and float64r32
>    target/ppc: Use helper_todouble/tosingle in helper_xststdcsp
>    test/tcg/ppc64le: Add float reference files

I didn't see any regression, so I plan to queue the first 34 patches
for 7.0 and let you handle the last patch since there is a small fix
to address before.

Thanks,

C.


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (35 preceding siblings ...)
  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
  37 siblings, 0 replies; 51+ messages in thread
From: Matheus K. Ferst @ 2021-12-03 16:10 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, danielhb413, qemu-ppc, clg

On 19/11/2021 13:04, Richard Henderson wrote:
> This is a partial patch set showing the direction I believe
> the cleanups should go, as opposed to a complete conversion.
> 
> I add a bunch of float_flag_* bits that diagnose the reason
> for most float_flag_invalid, as guided by the requirements
> of the PowerPC VX* bits.  I have converted some helpers to
> use these new flags but not all.  A good signal for unconverted
> routines is the use of float*_is_signalling_nan, which should
> now be using float_flag_invalid_snan.
> 
> I added float64x32_* arithmetic routines, which take float64
> arguments and round the result to the range and precision of
> float32, while giving the result in float64 form.  This is
> exactly what PowerPC requires for its single-precision math.
> This fixes double-rounding problems that exist in the current
> code, and are visible in the float_madds test.
> 
> I add test reference files for float_madds and float_convs
> after fixing the bugs required to make the tests pass.

With this series and few other VSX instructions[1], QEMU now passes the 
GLibc math test suite.

Tested-by: Matheus Ferst <matheus.ferst@eldorado.org.br>

[1] https://github.com/PPC64/qemu/tree/ferst-tcg-xsmaddqp (WIP)

Thanks,
Matheus K. Ferst
Instituto de Pesquisas ELDORADO <http://www.eldorado.org.br/>
Analista de Software
Aviso Legal - Disclaimer <https://www.eldorado.org.br/disclaimer.html>


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 01/35] softfloat: Extend float_exception_flags to 16 bits
  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é
  0 siblings, 0 replies; 51+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-12-03 21:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, danielhb413, qemu-ppc, clg

On 11/19/21 17:04, Richard Henderson wrote:
> We will shortly have more than 8 bits of exceptions.
> Repack the existing flags into low bits and reformat to hex.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/fpu/softfloat-types.h | 16 ++++++++--------
>  include/fpu/softfloat.h       |  2 +-
>  2 files changed, 9 insertions(+), 9 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>



^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 14/35] target/ppc: Remove inline from do_fri
  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é
  0 siblings, 0 replies; 51+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-12-03 21:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, danielhb413, qemu-ppc, clg

On 11/19/21 17:04, Richard Henderson wrote:
> There's no reason the callers can't tail call to one function.
> Leave it up to the compiler either way.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/ppc/fpu_helper.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [PATCH 15/35] target/ppc: Use FloatRoundMode in do_fri
  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é
  0 siblings, 0 replies; 51+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-12-03 21:33 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: alex.bennee, danielhb413, qemu-ppc, clg

On 11/19/21 17:04, Richard Henderson wrote:
> This is the proper type for the enumeration.
> 
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/ppc/fpu_helper.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>


^ permalink raw reply	[flat|nested] 51+ messages in thread

* Re: [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups
  2021-11-19 16:04 [RFC PATCH for-7.0 00/35] target/ppc fpu fixes and cleanups Richard Henderson
                   ` (36 preceding siblings ...)
  2021-12-03 16:10 ` Matheus K. Ferst
@ 2021-12-15 16:42 ` Cédric Le Goater
  37 siblings, 0 replies; 51+ messages in thread
From: Cédric Le Goater @ 2021-12-15 16:42 UTC (permalink / raw)
  To: Richard Henderson, qemu-devel; +Cc: qemu-ppc, danielhb413, alex.bennee

On 11/19/21 17:04, Richard Henderson wrote:
> This is a partial patch set showing the direction I believe
> the cleanups should go, as opposed to a complete conversion.
> 
> I add a bunch of float_flag_* bits that diagnose the reason
> for most float_flag_invalid, as guided by the requirements
> of the PowerPC VX* bits.  I have converted some helpers to
> use these new flags but not all.  A good signal for unconverted
> routines is the use of float*_is_signalling_nan, which should
> now be using float_flag_invalid_snan.
> 
> I added float64x32_* arithmetic routines, which take float64
> arguments and round the result to the range and precision of
> float32, while giving the result in float64 form.  This is
> exactly what PowerPC requires for its single-precision math.
> This fixes double-rounding problems that exist in the current
> code, and are visible in the float_madds test.
> 
> I add test reference files for float_madds and float_convs
> after fixing the bugs required to make the tests pass.


Applied patches 1-34 to ppc-next.

Thanks,

C.


^ permalink raw reply	[flat|nested] 51+ messages in thread

end of thread, other threads:[~2021-12-15 16:45 UTC | newest]

Thread overview: 51+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [PATCH 27/35] softfloat: Add float64r32 arithmetic routines Richard Henderson
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

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.