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:
parent
efa7319619
commit
855f7a657e
|
@ -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); \
|
||||||
|
|
Loading…
Reference in a new issue