[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)
- [Qemu-ppc] [PATCH] fix setting the FPSCR[FR] bit,
John Arbuckle <=