aboutsummaryrefslogtreecommitdiff
path: root/target/mips/msa_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/mips/msa_helper.c')
-rw-r--r--target/mips/msa_helper.c77
1 files changed, 52 insertions, 25 deletions
diff --git a/target/mips/msa_helper.c b/target/mips/msa_helper.c
index 3c7012c0b8..c3b271934a 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)