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 <programmingk...@gmail.com> --- 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)