From e475e68c94c890194a9a776dcfbc94c4de53eb64 Mon Sep 17 00:00:00 2001 From: Leon Alrae Date: Mon, 12 Feb 2018 16:11:50 -0500 Subject: [PATCH] target-mips: add missing MSACSR and restore fp_status and hflags Save MSACSR state. Also remove fp_status, msa_fp_status, hflags and restore them in post_load() from the architectural registers. Float exception flags are not present in vmstate. Information they carry is used only by softfloat caller who translates them into MIPS FCSR.Cause, FCSR.Flags and then they are cleared. Therefore there is no need for saving them in vmstate. Backports commit 644511117e7ca9f26d633a59c202a297113a796c from qemu --- qemu/target-mips/cpu.h | 16 ++++++++++++++++ qemu/target-mips/msa_helper.c | 13 +------------ qemu/target-mips/translate_init.c | 10 ++-------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/qemu/target-mips/cpu.h b/qemu/target-mips/cpu.h index 791019a5..2146ca9a 100644 --- a/qemu/target-mips/cpu.h +++ b/qemu/target-mips/cpu.h @@ -783,6 +783,22 @@ static inline void restore_flush_mode(CPUMIPSState *env) &env->active_fpu.fp_status); } +static inline void restore_fp_status(CPUMIPSState *env) +{ + restore_rounding_mode(env); + restore_flush_mode(env); +} + +static inline void restore_msa_fp_status(CPUMIPSState *env) +{ + float_status *status = &env->active_tc.msa_fp_status; + int rounding_mode = (env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM; + bool flush_to_zero = (env->active_tc.msacsr & MSACSR_FS_MASK) != 0; + + set_float_rounding_mode(ieee_rm[rounding_mode], status); + set_flush_to_zero(flush_to_zero, status); + set_flush_inputs_to_zero(flush_to_zero, status); +} static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc, target_ulong *cs_base, int *flags) diff --git a/qemu/target-mips/msa_helper.c b/qemu/target-mips/msa_helper.c index af1c7e34..1af89082 100644 --- a/qemu/target-mips/msa_helper.c +++ b/qemu/target-mips/msa_helper.c @@ -1347,18 +1347,7 @@ void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd) case 0: break; case 1: - env->active_tc.msacsr = (int32_t)elm & MSACSR_MASK; - /* set float_status rounding mode */ - set_float_rounding_mode( - ieee_rm[(env->active_tc.msacsr & MSACSR_RM_MASK) >> MSACSR_RM], - &env->active_tc.msa_fp_status); - /* set float_status flush modes */ - set_flush_to_zero( - (env->active_tc.msacsr & MSACSR_FS_MASK) != 0 ? 1 : 0, - &env->active_tc.msa_fp_status); - set_flush_inputs_to_zero( - (env->active_tc.msacsr & MSACSR_FS_MASK) != 0 ? 1 : 0, - &env->active_tc.msa_fp_status); + restore_msa_fp_status(env); /* check exception */ if ((GET_FP_ENABLE(env->active_tc.msacsr) | FP_UNIMPLEMENTED) & GET_FP_CAUSE(env->active_tc.msacsr)) { diff --git a/qemu/target-mips/translate_init.c b/qemu/target-mips/translate_init.c index 31d25458..94d3fc36 100644 --- a/qemu/target-mips/translate_init.c +++ b/qemu/target-mips/translate_init.c @@ -1054,6 +1054,8 @@ static void msa_reset(CPUMIPSState *env) - round to nearest / ties to even (RM bits are 0) */ env->active_tc.msacsr = 0; + restore_msa_fp_status(env); + /* tininess detected after rounding.*/ set_float_detect_tininess(float_tininess_after_rounding, &env->active_tc.msa_fp_status); @@ -1061,14 +1063,6 @@ static void msa_reset(CPUMIPSState *env) /* clear float_status exception flags */ set_float_exception_flags(0, &env->active_tc.msa_fp_status); - /* set float_status rounding mode */ - set_float_rounding_mode(float_round_nearest_even, - &env->active_tc.msa_fp_status); - - /* set float_status flush modes */ - set_flush_to_zero(0, &env->active_tc.msa_fp_status); - set_flush_inputs_to_zero(0, &env->active_tc.msa_fp_status); - /* clear float_status nan mode */ set_default_nan_mode(0, &env->active_tc.msa_fp_status); }