diff options
author | Bharata B Rao <bharata@linux.vnet.ibm.com> | 2016-11-23 17:07:13 +0530 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2017-01-31 10:10:12 +1100 |
commit | 3a20d11d451e9573af19ff312d61ee4da61cbbf0 (patch) | |
tree | 6e12fabee6a64acd366da4cc6316189078f23da1 /target/ppc/fpu_helper.c | |
parent | 855f7a657e6061c241b5aa52c2a22cc94be4a63b (diff) |
target-ppc: Add xscmpexp[dp,qp] instructions
xscmpexpdp: VSX Scalar Compare Exponents Double-Precision
xscmpexpqp: VSX Scalar Compare Exponents Quad-Precision
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>
Diffstat (limited to 'target/ppc/fpu_helper.c')
-rw-r--r-- | target/ppc/fpu_helper.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index fdd3216d72..8bffafb57e 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2405,6 +2405,70 @@ VSX_SCALAR_CMP_DP(xscmpgedp, le, 1, 1) VSX_SCALAR_CMP_DP(xscmpgtdp, lt, 1, 1) VSX_SCALAR_CMP_DP(xscmpnedp, eq, 0, 0) +void helper_xscmpexpdp(CPUPPCState *env, uint32_t opcode) +{ + ppc_vsr_t xa, xb; + int64_t exp_a, exp_b; + uint32_t cc; + + getVSR(xA(opcode), &xa, env); + getVSR(xB(opcode), &xb, env); + + exp_a = extract64(xa.VsrD(0), 52, 11); + exp_b = extract64(xb.VsrD(0), 52, 11); + + if (unlikely(float64_is_any_nan(xa.VsrD(0)) || + float64_is_any_nan(xb.VsrD(0)))) { + cc = CRF_SO; + } else { + if (exp_a < exp_b) { + cc = CRF_LT; + } else if (exp_a > exp_b) { + cc = CRF_GT; + } else { + cc = CRF_EQ; + } + } + + env->fpscr &= ~(0x0F << FPSCR_FPRF); + env->fpscr |= cc << FPSCR_FPRF; + env->crf[BF(opcode)] = cc; + + helper_float_check_status(env); +} + +void helper_xscmpexpqp(CPUPPCState *env, uint32_t opcode) +{ + ppc_vsr_t xa, xb; + int64_t exp_a, exp_b; + uint32_t cc; + + getVSR(rA(opcode) + 32, &xa, env); + getVSR(rB(opcode) + 32, &xb, env); + + exp_a = extract64(xa.VsrD(0), 48, 15); + exp_b = extract64(xb.VsrD(0), 48, 15); + + if (unlikely(float128_is_any_nan(make_float128(xa.VsrD(0), xa.VsrD(1))) || + float128_is_any_nan(make_float128(xb.VsrD(0), xb.VsrD(1))))) { + cc = CRF_SO; + } else { + if (exp_a < exp_b) { + cc = CRF_LT; + } else if (exp_a > exp_b) { + cc = CRF_GT; + } else { + cc = CRF_EQ; + } + } + + env->fpscr &= ~(0x0F << FPSCR_FPRF); + env->fpscr |= cc << FPSCR_FPRF; + env->crf[BF(opcode)] = cc; + + helper_float_check_status(env); +} + #define VSX_SCALAR_CMP(op, ordered) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ { \ |