qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: John Arbuckle <programmingkidx@gmail.com>
To: david@gibson.dropbear.id.au, richard.henderson@linaro.org,
	qemu-devel@nongnu.org, qemu-ppc@nongnu.org
Cc: John Arbuckle <programmingkidx@gmail.com>
Subject: [Qemu-devel] [RFC] fix setting FPSCR[FR] bit
Date: Thu,  5 Jul 2018 11:13:34 -0400	[thread overview]
Message-ID: <20180705151334.12271-1-programmingkidx@gmail.com> (raw)

https://www.pdfdrive.net/powerpc-microprocessor-family-the-programming-environments-for-32-e3087633.html
Page 63 in table 2-4 is where the description of this bit can be found.

It is described as:

Floating-point fraction rounded. The last arithmetic or rounding and conversion instruction that rounded the intermediate result incremented the fraction. This bit is NOT sticky.

What I think this means is when the softfloat.c:round_canonical() function adds the inc variable to the frac variable, the floating point fraction rounded bit should be set. It also means that every time a floating point operation takes place, this bit needs to be updated since it isn't a sticky bit. My testing has produced mixed results with this patch. Some of my floating point tests are fixed by this patch, and others are broken by this patch. I'm not clear if this is the right way to implement setting the FPSCR[FR] bit. Feedback would be great.

Signed-off-by: John Arbuckle <programmingkidx@gmail.com>
---
 fpu/softfloat.c               | 6 +++++-
 include/fpu/softfloat-types.h | 1 +
 target/ppc/fpu_helper.c       | 8 ++++++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 8cd2400081..b2b2c61cff 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -382,11 +382,12 @@ 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, old_frac;
     int exp, flags = 0;
     bool overflow_norm;
 
     frac = p.frac;
+    old_frac = frac; /* Used to determine if the fraction was rounded */
     exp = p.exp;
 
     switch (p.cls) {
@@ -503,6 +504,9 @@ static FloatParts round_canonical(FloatParts p, float_status *s,
         g_assert_not_reached();
     }
 
+    if (frac != old_frac) {
+        flags |= float_flag_round;
+    }
     float_raise(flags, s);
     p.exp = exp;
     p.frac = frac;
diff --git a/include/fpu/softfloat-types.h b/include/fpu/softfloat-types.h
index 2aae6a89b1..1d124e659c 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_round     =  2,
     float_flag_divbyzero =  4,
     float_flag_overflow  =  8,
     float_flag_underflow = 16,
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c
index cb82e6e842..ba57ea7cfe 100644
--- a/target/ppc/fpu_helper.c
+++ b/target/ppc/fpu_helper.c
@@ -581,6 +581,7 @@ static void do_float_check_status(CPUPPCState *env, uintptr_t raddr)
     CPUState *cs = CPU(ppc_env_get_cpu(env));
     int status = get_float_exception_flags(&env->fp_status);
     bool inexact_happened = false;
+    bool round_happened = false;
 
     if (status & float_flag_overflow) {
         float_overflow_excp(env);
@@ -589,6 +590,8 @@ static void do_float_check_status(CPUPPCState *env, uintptr_t raddr)
     } else if (status & float_flag_inexact) {
         float_inexact_excp(env);
         inexact_happened = true;
+    } else if (status & float_flag_round) {
+        round_happened = true;
     }
 
     /* if the inexact flag was not set */
@@ -596,6 +599,11 @@ static void do_float_check_status(CPUPPCState *env, uintptr_t raddr)
         env->fpscr &= ~(1 << FPSCR_FI); /* clear the FPSCR[FI] bit */
     }
 
+    /* if the floating-point fraction rounded bit was not set */
+    if (round_happened == false) {
+        env->fpscr &= ~(1 << FPSCR_FR); /* clear the FPSCR[FR] bit */
+    }
+
     if (cs->exception_index == POWERPC_EXCP_PROGRAM &&
         (env->error_code & POWERPC_EXCP_FP)) {
         /* Differred floating-point exception after target FPR update */
-- 
2.14.3 (Apple Git-98)

                 reply	other threads:[~2018-07-05 15:13 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=20180705151334.12271-1-programmingkidx@gmail.com \
    --to=programmingkidx@gmail.com \
    --cc=david@gibson.dropbear.id.au \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    --cc=richard.henderson@linaro.org \
    /path/to/YOUR_REPLY

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

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).