qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [PATCH] fix setting the FPSCR[FR] bit


From: John Arbuckle
Subject: [Qemu-ppc] [PATCH] fix setting the FPSCR[FR] bit
Date: Mon, 17 Sep 2018 17:18:58 -0400

https://www.nxp.com/files-static/product/doc/MPCFPE32B.pdf
Page 2-8 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, rounding, or conversion 
instruction incremented the fraction. This bit is NOT sticky.

This patch actually implements the setting and unsetting of this bit.

Signed-off-by: John Arbuckle <address@hidden>
---
 fpu/softfloat.c               | 12 ++++++++++--
 include/fpu/softfloat-types.h |  1 +
 target/ppc/fpu_helper.c       | 12 ++++++++++++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 59ca356d0e..c5378ae9e8 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -751,9 +751,17 @@ float64 __attribute__((flatten)) float64_add(float64 a, 
float64 b,
 {
     FloatParts pa = float64_unpack_canonical(a, status);
     FloatParts pb = float64_unpack_canonical(b, status);
-    FloatParts pr = addsub_floats(pa, pb, false, status);
+    FloatParts intermediate_parts = addsub_floats(pa, pb, false, status);
 
-    return float64_round_pack_canonical(pr, status);
+    float64 rounded_result = float64_round_pack_canonical(intermediate_parts,
+                                                          status);
+    FloatParts rounded_parts = float64_unpack_canonical(rounded_result, 
status);
+
+    if (rounded_parts.frac != intermediate_parts.frac) {
+        float_raise(float_flag_round, status);
+    }
+
+    return rounded_result;
 }
 
 float16 __attribute__((flatten)) float16_sub(float16 a, float16 b,
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 b9bb1b856e..eed4f1a650 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);
@@ -591,11 +592,22 @@ static void do_float_check_status(CPUPPCState *env, 
uintptr_t raddr)
         inexact_happened = true;
     }
 
+    /* if the round flag was set */
+    if (status & float_flag_round) {
+        round_happened = true;
+        env->fpscr |= 1 << FPSCR_FR;
+    }
+
     /* if the inexact flag was not set */
     if (inexact_happened == false) {
         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 via email to

[Prev in Thread] Current Thread [Next in Thread]