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; \ ppc_vsr_t xa, xb; \
uint32_t cc = 0; \ uint32_t cc = 0; \
bool vxsnan_flag = false, vxvc_flag = false; \
\ \
helper_reset_fpstatus(env); \
getVSR(xA(opcode), &xa, env); \ getVSR(xA(opcode), &xa, env); \
getVSR(xB(opcode), &xb, env); \ getVSR(xB(opcode), &xb, env); \
\ \
if (unlikely(float64_is_any_nan(xa.VsrD(0)) || \ if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \
float64_is_any_nan(xb.VsrD(0)))) { \ float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \
if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status) || \ vxsnan_flag = true; \
float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \ cc = CRF_SO; \
float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ 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) { \ 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 { \ } else { \
if (float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \ cc |= CRF_EQ; \
cc = 8; \
} else if (!float64_le(xa.VsrD(0), xb.VsrD(0), \
&env->fp_status)) { \
cc = 4; \
} else { \
cc = 2; \
} \
} \ } \
\ \
env->fpscr &= ~(0x0F << FPSCR_FPRF); \ env->fpscr &= ~(0x0F << FPSCR_FPRF); \