From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:58699) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1WLhoN-00016P-EY for qemu-devel@nongnu.org; Thu, 06 Mar 2014 18:35:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1WLhnx-0003Lo-Ko for qemu-devel@nongnu.org; Thu, 06 Mar 2014 18:34:47 -0500 From: Alexander Graf Date: Fri, 7 Mar 2014 00:33:11 +0100 Message-Id: <1394148857-19607-65-git-send-email-agraf@suse.de> In-Reply-To: <1394148857-19607-1-git-send-email-agraf@suse.de> References: <1394148857-19607-1-git-send-email-agraf@suse.de> Subject: [Qemu-devel] [PULL 064/130] target-ppc: Fix and enable fri[mnpz] List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Peter Maydell , Tom Musta , blauwirbel@gmail.com, qemu-ppc@nongnu.org, aliguori@amazon.com, aurelien@aurel32.net From: Tom Musta The fri* series of instructions was introduced prior to ISA 2.06 and is supported on Power7 and Power8 hardware. However, the instruction is still considered illegal in the P7 and P8 QEMU emulation models. This patch enables these instructions for the P7 and P8 machines. Also, the existing helper is modified to correctly handle some of the boundary cases (NaNs and the inexact flag). Signed-off-by: Tom Musta Reviewed-by: Richard Henderson Signed-off-by: Alexander Graf --- target-ppc/fpu_helper.c | 18 +++++++++++------- target-ppc/translate_init.c | 3 +++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index eb56082..87ff60f 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -669,24 +669,28 @@ static inline uint64_t do_fri(CPUPPCState *env, uint64_t arg, if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN round */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN | - POWERPC_EXCP_FP_VXCVI, 1); - } else if (unlikely(float64_is_quiet_nan(farg.d) || - float64_is_infinity(farg.d))) { - /* qNan / infinity round */ - farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 1); + fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 1); + farg.ll = arg | 0x0008000000000000ul; } else { + int inexact = get_float_exception_flags(&env->fp_status) & + float_flag_inexact; set_float_rounding_mode(rounding_mode, &env->fp_status); farg.ll = float64_round_to_int(farg.d, &env->fp_status); /* Restore rounding mode from FPSCR */ fpscr_set_rounding_mode(env); + + /* fri* does not set FPSCR[XX] */ + if (!inexact) { + env->fp_status.float_exception_flags &= ~float_flag_inexact; + } } + helper_float_check_status(env); return farg.ll; } uint64_t helper_frin(CPUPPCState *env, uint64_t arg) { - return do_fri(env, arg, float_round_nearest_even); + return do_fri(env, arg, float_round_ties_away); } uint64_t helper_friz(CPUPPCState *env, uint64_t arg) diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 6dd0f84..21c56e6 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -7062,6 +7062,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_FLOAT_EXT | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | @@ -7102,6 +7103,7 @@ POWERPC_FAMILY(POWER7P)(ObjectClass *oc, void *data) PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_FLOAT_EXT | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | @@ -7142,6 +7144,7 @@ POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data) PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_STFIWX | + PPC_FLOAT_EXT | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | -- 1.8.1.4