diff options
author | Bharata B Rao <bharata@linux.vnet.ibm.com> | 2016-11-23 17:07:12 +0530 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2017-01-31 10:10:12 +1100 |
commit | 855f7a657e6061c241b5aa52c2a22cc94be4a63b (patch) | |
tree | 65e7216f11528bd0882ba670399a03c75c38a73e | |
parent | efa7319619e92809c12b5f12f7f5bcdb044e7e21 (diff) |
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>
-rw-r--r-- | target/ppc/fpu_helper.c | 40 |
1 files 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); \ |