From 855f7a657e6061c241b5aa52c2a22cc94be4a63b Mon Sep 17 00:00:00 2001 From: Bharata B Rao Date: Wed, 23 Nov 2016 17:07:12 +0530 Subject: [PATCH] target-ppc: Fix xscmpodp and xscmpudp instructions - xscmpodp & xscmpudp are missing flags reset. - In xscmpodp, VXCC should be set only if VE is 0 for signalling NaN case and VXCC should be set by explicitly checking for quiet NaN case. - Comparison is being done only if the operands are not NaNs. However as per ISA, it should be done even when operands are NaNs. Signed-off-by: Bharata B Rao Signed-off-by: Nikunj A Dadhania Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index d3741b4828..fdd3216d72 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2410,29 +2410,39 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \ { \ ppc_vsr_t xa, xb; \ uint32_t cc = 0; \ + bool vxsnan_flag = false, vxvc_flag = false; \ \ + helper_reset_fpstatus(env); \ getVSR(xA(opcode), &xa, env); \ getVSR(xB(opcode), &xb, env); \ \ - if (unlikely(float64_is_any_nan(xa.VsrD(0)) || \ - float64_is_any_nan(xb.VsrD(0)))) { \ - if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \ - float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \ - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \ + float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \ + vxsnan_flag = true; \ + cc = CRF_SO; \ + if (fpscr_ve == 0 && ordered) { \ + vxvc_flag = true; \ } \ + } else if (float64_is_quiet_nan(xa.VsrD(0), &env->fp_status) || \ + float64_is_quiet_nan(xb.VsrD(0), &env->fp_status)) { \ + cc = CRF_SO; \ if (ordered) { \ - float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \ + vxvc_flag = true; \ } \ - cc = 1; \ + } \ + if (vxsnan_flag) { \ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + } \ + if (vxvc_flag) { \ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \ + } \ + \ + if (float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \ + cc |= CRF_LT; \ + } else if (!float64_le(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \ + cc |= CRF_GT; \ } else { \ - if (float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \ - cc = 8; \ - } else if (!float64_le(xa.VsrD(0), xb.VsrD(0), \ - &env->fp_status)) { \ - cc = 4; \ - } else { \ - cc = 2; \ - } \ + cc |= CRF_EQ; \ } \ \ env->fpscr &= ~(0x0F << FPSCR_FPRF); \