@@ -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)
@@ -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);
}
}
}
@@ -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)