[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 18/20] target/mips: fpu: Refactor conversion from ieee to mips exc
From: |
Aleksandar Markovic |
Subject: |
[PULL 18/20] target/mips: fpu: Refactor conversion from ieee to mips exception flags |
Date: |
Tue, 9 Jun 2020 18:28:36 +0200 |
The original coversion function is used for regular and MSA floating
point instructions handling. Since there are some nuanced differences
between regular and MSA floating point exception handling, provide two
instances of the conversion function, rather than just a single common
one. Inline both instances of this function instances for the sake of
performance. Improve variable naming in surrounding code for clarity.
Reviewed-by: Aleksandar Rikalo <aleksandar.rikalo@syrmia.com>
Signed-off-by: Aleksandar Markovic <aleksandar.qemu.devel@gmail.com>
Message-Id: <20200518200920.17344-17-aleksandar.qemu.devel@gmail.com>
---
target/mips/internal.h | 1 -
target/mips/fpu_helper.c | 55 ++++++++++++++++++----------------
target/mips/msa_helper.c | 77 ++++++++++++++++++++++++++++++++----------------
3 files changed, 82 insertions(+), 51 deletions(-)
diff --git a/target/mips/internal.h b/target/mips/internal.h
index 1bf274b..684356e 100644
--- a/target/mips/internal.h
+++ b/target/mips/internal.h
@@ -224,7 +224,6 @@ uint32_t float_class_s(uint32_t arg, float_status *fst);
uint64_t float_class_d(uint64_t arg, float_status *fst);
extern unsigned int ieee_rm[];
-int ieee_ex_to_mips(int xcpt);
void update_pagemask(CPUMIPSState *env, target_ulong arg1, int32_t *pagemask);
static inline void restore_rounding_mode(CPUMIPSState *env)
diff --git a/target/mips/fpu_helper.c b/target/mips/fpu_helper.c
index dbb8ca5..7a3a61c 100644
--- a/target/mips/fpu_helper.c
+++ b/target/mips/fpu_helper.c
@@ -189,43 +189,48 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1,
uint32_t fs, uint32_t rt)
}
}
-int ieee_ex_to_mips(int xcpt)
+static inline int ieee_to_mips_xcpt(int ieee_xcpt)
{
- int ret = 0;
- if (xcpt) {
- if (xcpt & float_flag_invalid) {
- ret |= FP_INVALID;
- }
- if (xcpt & float_flag_overflow) {
- ret |= FP_OVERFLOW;
- }
- if (xcpt & float_flag_underflow) {
- ret |= FP_UNDERFLOW;
- }
- if (xcpt & float_flag_divbyzero) {
- ret |= FP_DIV0;
- }
- if (xcpt & float_flag_inexact) {
- ret |= FP_INEXACT;
- }
+ int mips_xcpt = 0;
+
+ if (ieee_xcpt & float_flag_invalid) {
+ mips_xcpt |= FP_INVALID;
+ }
+ if (ieee_xcpt & float_flag_overflow) {
+ mips_xcpt |= FP_OVERFLOW;
}
- return ret;
+ if (ieee_xcpt & float_flag_underflow) {
+ mips_xcpt |= FP_UNDERFLOW;
+ }
+ if (ieee_xcpt & float_flag_divbyzero) {
+ mips_xcpt |= FP_DIV0;
+ }
+ if (ieee_xcpt & float_flag_inexact) {
+ mips_xcpt |= FP_INEXACT;
+ }
+
+ return mips_xcpt;
}
static inline void update_fcr31(CPUMIPSState *env, uintptr_t pc)
{
- int tmp = ieee_ex_to_mips(get_float_exception_flags(
- &env->active_fpu.fp_status));
+ int ieee_exception_flags = get_float_exception_flags(
+ &env->active_fpu.fp_status);
+ int mips_exception_flags = 0;
+
+ if (ieee_exception_flags) {
+ mips_exception_flags = ieee_to_mips_xcpt(ieee_exception_flags);
+ }
- SET_FP_CAUSE(env->active_fpu.fcr31, tmp);
+ SET_FP_CAUSE(env->active_fpu.fcr31, mips_exception_flags);
- if (tmp) {
+ if (mips_exception_flags) {
set_float_exception_flags(0, &env->active_fpu.fp_status);
- if (GET_FP_ENABLE(env->active_fpu.fcr31) & tmp) {
+ if (GET_FP_ENABLE(env->active_fpu.fcr31) & mips_exception_flags) {
do_raise_exception(env, EXCP_FPE, pc);
} else {
- UPDATE_FP_FLAGS(env->active_fpu.fcr31, tmp);
+ UPDATE_FP_FLAGS(env->active_fpu.fcr31, mips_exception_flags);
}
}
}
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 3c7012c..c3b2719 100644
--- a/target/mips/msa_helper.c
+++ b/target/mips/msa_helper.c
@@ -5419,54 +5419,81 @@ static inline void check_msacsr_cause(CPUMIPSState
*env, uintptr_t retaddr)
#define CLEAR_IS_INEXACT 2
#define RECIPROCAL_INEXACT 4
-static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
+
+static inline int ieee_to_mips_xcpt_msa(int ieee_xcpt)
{
- int ieee_ex;
+ int mips_xcpt = 0;
- int c;
+ if (ieee_xcpt & float_flag_invalid) {
+ mips_xcpt |= FP_INVALID;
+ }
+ if (ieee_xcpt & float_flag_overflow) {
+ mips_xcpt |= FP_OVERFLOW;
+ }
+ if (ieee_xcpt & float_flag_underflow) {
+ mips_xcpt |= FP_UNDERFLOW;
+ }
+ if (ieee_xcpt & float_flag_divbyzero) {
+ mips_xcpt |= FP_DIV0;
+ }
+ if (ieee_xcpt & float_flag_inexact) {
+ mips_xcpt |= FP_INEXACT;
+ }
+
+ return mips_xcpt;
+}
+
+static inline int update_msacsr(CPUMIPSState *env, int action, int denormal)
+{
+ int ieee_exception_flags;
+ int mips_exception_flags = 0;
int cause;
int enable;
- ieee_ex = get_float_exception_flags(&env->active_tc.msa_fp_status);
+ ieee_exception_flags = get_float_exception_flags(
+ &env->active_tc.msa_fp_status);
/* QEMU softfloat does not signal all underflow cases */
if (denormal) {
- ieee_ex |= float_flag_underflow;
+ ieee_exception_flags |= float_flag_underflow;
+ }
+ if (ieee_exception_flags) {
+ mips_exception_flags = ieee_to_mips_xcpt_msa(ieee_exception_flags);
}
-
- c = ieee_ex_to_mips(ieee_ex);
enable = GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED;
/* Set Inexact (I) when flushing inputs to zero */
- if ((ieee_ex & float_flag_input_denormal) &&
+ if ((ieee_exception_flags & float_flag_input_denormal) &&
(env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
if (action & CLEAR_IS_INEXACT) {
- c &= ~FP_INEXACT;
+ mips_exception_flags &= ~FP_INEXACT;
} else {
- c |= FP_INEXACT;
+ mips_exception_flags |= FP_INEXACT;
}
}
/* Set Inexact (I) and Underflow (U) when flushing outputs to zero */
- if ((ieee_ex & float_flag_output_denormal) &&
+ if ((ieee_exception_flags & float_flag_output_denormal) &&
(env->active_tc.msacsr & MSACSR_FS_MASK) != 0) {
- c |= FP_INEXACT;
+ mips_exception_flags |= FP_INEXACT;
if (action & CLEAR_FS_UNDERFLOW) {
- c &= ~FP_UNDERFLOW;
+ mips_exception_flags &= ~FP_UNDERFLOW;
} else {
- c |= FP_UNDERFLOW;
+ mips_exception_flags |= FP_UNDERFLOW;
}
}
/* Set Inexact (I) when Overflow (O) is not enabled */
- if ((c & FP_OVERFLOW) != 0 && (enable & FP_OVERFLOW) == 0) {
- c |= FP_INEXACT;
+ if ((mips_exception_flags & FP_OVERFLOW) != 0 &&
+ (enable & FP_OVERFLOW) == 0) {
+ mips_exception_flags |= FP_INEXACT;
}
/* Clear Exact Underflow when Underflow (U) is not enabled */
- if ((c & FP_UNDERFLOW) != 0 && (enable & FP_UNDERFLOW) == 0 &&
- (c & FP_INEXACT) == 0) {
- c &= ~FP_UNDERFLOW;
+ if ((mips_exception_flags & FP_UNDERFLOW) != 0 &&
+ (enable & FP_UNDERFLOW) == 0 &&
+ (mips_exception_flags & FP_INEXACT) == 0) {
+ mips_exception_flags &= ~FP_UNDERFLOW;
}
/*
@@ -5474,11 +5501,11 @@ static inline int update_msacsr(CPUMIPSState *env, int
action, int denormal)
* divide by zero
*/
if ((action & RECIPROCAL_INEXACT) &&
- (c & (FP_INVALID | FP_DIV0)) == 0) {
- c = FP_INEXACT;
+ (mips_exception_flags & (FP_INVALID | FP_DIV0)) == 0) {
+ mips_exception_flags = FP_INEXACT;
}
- cause = c & enable; /* all current enabled exceptions */
+ cause = mips_exception_flags & enable; /* all current enabled exceptions */
if (cause == 0) {
/*
@@ -5486,7 +5513,7 @@ static inline int update_msacsr(CPUMIPSState *env, int
action, int denormal)
* with all current exceptions
*/
SET_FP_CAUSE(env->active_tc.msacsr,
- (GET_FP_CAUSE(env->active_tc.msacsr) | c));
+ (GET_FP_CAUSE(env->active_tc.msacsr) | mips_exception_flags));
} else {
/* Current exceptions are enabled */
if ((env->active_tc.msacsr & MSACSR_NX_MASK) == 0) {
@@ -5495,11 +5522,11 @@ static inline int update_msacsr(CPUMIPSState *env, int
action, int denormal)
* with all enabled exceptions
*/
SET_FP_CAUSE(env->active_tc.msacsr,
- (GET_FP_CAUSE(env->active_tc.msacsr) | c));
+ (GET_FP_CAUSE(env->active_tc.msacsr) | mips_exception_flags));
}
}
- return c;
+ return mips_exception_flags;
}
static inline int get_enabled_exceptions(const CPUMIPSState *env, int c)
--
2.7.4
- [PULL 06/20] target/mips: fpu: Demacro DIV.<D|S|PS>, (continued)
- [PULL 06/20] target/mips: fpu: Demacro DIV.<D|S|PS>, Aleksandar Markovic, 2020/06/09
- [PULL 02/20] mailmap: Change email address of Stefan Brankovic, Aleksandar Markovic, 2020/06/09
- [PULL 08/20] target/mips: fpu: Demacro MADD.<D|S|PS>, Aleksandar Markovic, 2020/06/09
- [PULL 09/20] target/mips: fpu: Demacro MSUB.<D|S|PS>, Aleksandar Markovic, 2020/06/09
- [PULL 10/20] target/mips: fpu: Demacro NMADD.<D|S|PS>, Aleksandar Markovic, 2020/06/09
- [PULL 11/20] target/mips: fpu: Demacro NMSUB.<D|S|PS>, Aleksandar Markovic, 2020/06/09
- [PULL 07/20] target/mips: fpu: Remove now unused macro FLOAT_BINOP, Aleksandar Markovic, 2020/06/09
- [PULL 05/20] target/mips: fpu: Demacro MUL.<D|S|PS>, Aleksandar Markovic, 2020/06/09
- [PULL 12/20] target/mips: fpu: Remove now unused UNFUSED_FMA and FLOAT_FMA macros, Aleksandar Markovic, 2020/06/09
- [PULL 13/20] target/mips: fpu: Demacro CLASS.<D|S>, Aleksandar Markovic, 2020/06/09
- [PULL 18/20] target/mips: fpu: Refactor conversion from ieee to mips exception flags,
Aleksandar Markovic <=
- [PULL 17/20] target/mips: fpu: Name better paired-single variables, Aleksandar Markovic, 2020/06/09
- [PULL 15/20] target/mips: fpu: Demacro RINT.<D|S>, Aleksandar Markovic, 2020/06/09
- [PULL 16/20] target/mips: fpu: Remove now unused FLOAT_RINT macro, Aleksandar Markovic, 2020/06/09
- [PULL 14/20] target/mips: fpu: Remove now unused FLOAT_CLASS macro, Aleksandar Markovic, 2020/06/09
- [PULL 19/20] target/mips: Add Loongson-3 CPU definition, Aleksandar Markovic, 2020/06/09
- [PULL 20/20] target/mips: Enable hardware page table walker and CMGCR features for P5600, Aleksandar Markovic, 2020/06/09
- Re: [PULL 00/20] MIPS queue for June 9th, 2020, Peter Maydell, 2020/06/11