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 <bharata@linux.vnet.ibm.com>
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Bharata B Rao 2016-11-23 17:07:12 +05:30 committed by David Gibson
parent efa7319619
commit 855f7a657e

View file

@ -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); \