diff mbox series

[1/2] Implement Floating Point flag Fraction Rounded

Message ID 20190525022008.24788-2-programmingkidx@gmail.com
State New
Headers show
Series Implement PowerPC FPSCR flag Fraction Rounded | expand

Commit Message

Programmingkid May 25, 2019, 2:20 a.m. UTC
Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
---
 fpu/softfloat.c               | 15 ++++++++++++---
 include/fpu/softfloat-types.h |  1 +
 2 files changed, 13 insertions(+), 3 deletions(-)

Comments

Richard Henderson June 11, 2019, 9 p.m. UTC | #1
On 5/24/19 7:20 PM, John Arbuckle wrote:
> Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
> ---
>  fpu/softfloat.c               | 15 ++++++++++++---
>  include/fpu/softfloat-types.h |  1 +
>  2 files changed, 13 insertions(+), 3 deletions(-)

There are additional places that need changing within this file, even if we
consider only float32 and float64 and ignore floatx80 and float128.

That said, merely renaming this patch to

  "softfloat: Implement float_flag_rounded in round_canonical

  Add a new flag to indicate that, when inexact, the result has
  been rounded.  That is, when the LSB of the rounded result
  differs from the same bit of the infinite precision result."

is enough to get

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>

For your usage within PowerPC, you will additionally need to modify round_to_int.


r~
diff mbox series

Patch

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 2ba36ec370..ac34f6a2de 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -702,7 +702,7 @@  static FloatParts round_canonical(FloatParts p, float_status *s,
     const uint64_t roundeven_mask = parm->roundeven_mask;
     const int exp_max = parm->exp_max;
     const int frac_shift = parm->frac_shift;
-    uint64_t frac, inc;
+    uint64_t frac, inc, rounded;
     int exp, flags = 0;
     bool overflow_norm;
 
@@ -744,7 +744,12 @@  static FloatParts round_canonical(FloatParts p, float_status *s,
         if (likely(exp > 0)) {
             if (frac & round_mask) {
                 flags |= float_flag_inexact;
-                frac += inc;
+                rounded = frac + inc;
+                if ((rounded ^ frac) & frac_lsb) {
+                    flags |= float_flag_rounded;
+                }
+                frac = rounded;
+
                 if (frac & DECOMPOSED_OVERFLOW_BIT) {
                     frac >>= 1;
                     exp++;
@@ -793,7 +798,11 @@  static FloatParts round_canonical(FloatParts p, float_status *s,
                     break;
                 }
                 flags |= float_flag_inexact;
-                frac += inc;
+                rounded = frac + inc;
+                if ((rounded ^ frac) & frac_lsb) {
+                    flags |= float_flag_rounded;
+                }
+                frac = rounded;
             }
 
             exp = (frac & DECOMPOSED_IMPLICIT_BIT ? 1 : 0);
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 2aae6a89b1..bee576e0fd 100644
--- a/include/fpu/softfloat-types.h
+++ b/include/fpu/softfloat-types.h
@@ -147,6 +147,7 @@  enum {
 
 enum {
     float_flag_invalid   =  1,
+    float_flag_rounded   =  2,
     float_flag_divbyzero =  4,
     float_flag_overflow  =  8,
     float_flag_underflow = 16,