提交 64451111 编写于 作者: L Leon Alrae

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.
Signed-off-by: NLeon Alrae <leon.alrae@imgtec.com>
Reviewed-by: NRichard Henderson <rth@twiddle.net>
上级 04cd7962
......@@ -786,6 +786,23 @@ 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)
{
......
......@@ -2,19 +2,39 @@
#include "cpu.h"
static int cpu_post_load(void *opaque, int version_id)
{
MIPSCPU *cpu = opaque;
CPUMIPSState *env = &cpu->env;
restore_fp_status(env);
restore_msa_fp_status(env);
compute_hflags(env);
return 0;
}
/* FPU state */
static int get_fpr(QEMUFile *f, void *pv, size_t size)
{
int i;
fpr_t *v = pv;
qemu_get_be64s(f, &v->d);
/* Restore entire MSA vector register */
for (i = 0; i < MSA_WRLEN/64; i++) {
qemu_get_sbe64s(f, &v->wr.d[i]);
}
return 0;
}
static void put_fpr(QEMUFile *f, void *pv, size_t size)
{
int i;
fpr_t *v = pv;
qemu_put_be64s(f, &v->d);
/* Save entire MSA vector register */
for (i = 0; i < MSA_WRLEN/64; i++) {
qemu_put_sbe64s(f, &v->wr.d[i]);
}
}
const VMStateInfo vmstate_info_fpr = {
......@@ -31,9 +51,6 @@ const VMStateInfo vmstate_info_fpr = {
static VMStateField vmstate_fpu_fields[] = {
VMSTATE_FPR_ARRAY(fpr, CPUMIPSFPUContext, 32),
VMSTATE_INT8(fp_status.float_detect_tininess, CPUMIPSFPUContext),
VMSTATE_INT8(fp_status.float_rounding_mode, CPUMIPSFPUContext),
VMSTATE_INT8(fp_status.float_exception_flags, CPUMIPSFPUContext),
VMSTATE_UINT32(fcr0, CPUMIPSFPUContext),
VMSTATE_UINT32(fcr31, CPUMIPSFPUContext),
VMSTATE_END_OF_LIST()
......@@ -70,6 +87,7 @@ static VMStateField vmstate_tc_fields[] = {
VMSTATE_UINTTL(CP0_TCScheFBack, TCState),
VMSTATE_INT32(CP0_Debug_tcstatus, TCState),
VMSTATE_UINTTL(CP0_UserLocal, TCState),
VMSTATE_INT32(msacsr, TCState),
VMSTATE_END_OF_LIST()
};
......@@ -183,8 +201,9 @@ const VMStateDescription vmstate_tlb = {
const VMStateDescription vmstate_mips_cpu = {
.name = "cpu",
.version_id = 5,
.minimum_version_id = 5,
.version_id = 6,
.minimum_version_id = 6,
.post_load = cpu_post_load,
.fields = (VMStateField[]) {
/* Active TC */
VMSTATE_STRUCT(env.active_tc, MIPSCPU, 1, vmstate_tc, TCState),
......@@ -205,7 +224,6 @@ const VMStateDescription vmstate_mips_cpu = {
VMSTATE_UINT32(env.current_tc, MIPSCPU),
VMSTATE_UINT32(env.current_fpu, MIPSCPU),
VMSTATE_INT32(env.error_code, MIPSCPU),
VMSTATE_UINT32(env.hflags, MIPSCPU),
VMSTATE_UINTTL(env.btarget, MIPSCPU),
VMSTATE_UINTTL(env.bcond, MIPSCPU),
......
......@@ -1348,17 +1348,7 @@ void helper_msa_ctcmsa(CPUMIPSState *env, target_ulong elm, uint32_t cd)
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)) {
......
......@@ -835,6 +835,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);
......@@ -842,14 +844,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);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册