From patchwork Fri Feb 20 13:07:45 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Leon Alrae X-Patchwork-Id: 441959 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id BD83F140082 for ; Sat, 21 Feb 2015 00:08:47 +1100 (AEDT) Received: from localhost ([::1]:60379 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YOnK1-0006PI-RY for incoming@patchwork.ozlabs.org; Fri, 20 Feb 2015 08:08:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58433) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YOnJO-0005Oo-Rr for qemu-devel@nongnu.org; Fri, 20 Feb 2015 08:08:08 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YOnJN-0005w2-7L for qemu-devel@nongnu.org; Fri, 20 Feb 2015 08:08:06 -0500 Received: from mailapp01.imgtec.com ([195.59.15.196]:13594) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YOnJM-0005vh-BT for qemu-devel@nongnu.org; Fri, 20 Feb 2015 08:08:05 -0500 Received: from KLMAIL01.kl.imgtec.org (unknown [192.168.5.35]) by Websense Email Security Gateway with ESMTPS id 5A98DF66F5833; Fri, 20 Feb 2015 13:08:00 +0000 (GMT) Received: from lalrae-linux.kl.imgtec.org (192.168.14.163) by KLMAIL01.kl.imgtec.org (192.168.5.35) with Microsoft SMTP Server (TLS) id 14.3.195.1; Fri, 20 Feb 2015 13:08:02 +0000 From: Leon Alrae To: Date: Fri, 20 Feb 2015 13:07:45 +0000 Message-ID: <1424437665-16939-3-git-send-email-leon.alrae@imgtec.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1424437665-16939-1-git-send-email-leon.alrae@imgtec.com> References: <1424437665-16939-1-git-send-email-leon.alrae@imgtec.com> MIME-Version: 1.0 X-Originating-IP: [192.168.14.163] X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.59.15.196 Cc: quintela@redhat.com, rth7680@gmail.com, macro@linux-mips.org, amit.shah@redhat.com, afaerber@suse.de, aurelien@aurel32.net Subject: [Qemu-devel] [PATCH v2 2/2] target-mips: add missing MSACSR and restore fp_status and hflags X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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: Leon Alrae Reviewed-by: Richard Henderson --- The introduced restore_fp_status() function is used only in the machine.c at the moment, but there are many more places where this could be applied instead of calling restore_rounding_mode() and restore_flush_mode() separately. However I don't see this cleanup fitting into this patchset -- I'm leaving it focused on vmstate rather than on a global cleanup which can come later. --- target-mips/cpu.h | 17 +++++++++++++++++ target-mips/machine.c | 34 ++++++++++++++++++++++++++-------- target-mips/msa_helper.c | 12 +----------- target-mips/translate_init.c | 10 ++-------- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/target-mips/cpu.h b/target-mips/cpu.h index 59a2373..283a546 100644 --- a/target-mips/cpu.h +++ b/target-mips/cpu.h @@ -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) { diff --git a/target-mips/machine.c b/target-mips/machine.c index 7fc4839..7d1fa32 100644 --- a/target-mips/machine.c +++ b/target-mips/machine.c @@ -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), diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c index c2160a6..26ffdc7 100644 --- a/target-mips/msa_helper.c +++ b/target-mips/msa_helper.c @@ -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)) { diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index 9e8433a..85a65e7 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -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); }