diff options
author | Bharata B Rao <bharata@linux.vnet.ibm.com> | 2017-02-06 16:00:00 +0530 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2017-02-22 11:28:27 +1100 |
commit | d4ccd87e6894569f5535eed94e45bf1bbba0478c (patch) | |
tree | d14614f465c0fd845f7c9522ef0e2b06d6429102 /target | |
parent | 2770deede0ad4a7f1e9e41a75b96e4eeb9a8305d (diff) |
target-ppc: Add xsmaxjdp and xsminjdp instructions
xsmaxjdp: VSX Scalar Maximum Type-J Double-Precision
xsminjdp: VSX Scalar Minimum Type-J Double-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')
-rw-r--r-- | target/ppc/fpu_helper.c | 55 | ||||
-rw-r--r-- | target/ppc/helper.h | 2 | ||||
-rw-r--r-- | target/ppc/translate/vsx-impl.inc.c | 2 | ||||
-rw-r--r-- | target/ppc/translate/vsx-ops.inc.c | 2 |
4 files changed, 61 insertions, 0 deletions
diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index 9d2688e675..1b6cd3bd10 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -2717,6 +2717,61 @@ void helper_##name(CPUPPCState *env, uint32_t opcode) \ VSX_MAX_MINC(xsmaxcdp, 1); VSX_MAX_MINC(xsmincdp, 0); +#define VSX_MAX_MINJ(name, max) \ +void helper_##name(CPUPPCState *env, uint32_t opcode) \ +{ \ + ppc_vsr_t xt, xa, xb; \ + bool vxsnan_flag = false, vex_flag = false; \ + \ + getVSR(rA(opcode) + 32, &xa, env); \ + getVSR(rB(opcode) + 32, &xb, env); \ + getVSR(rD(opcode) + 32, &xt, env); \ + \ + if (unlikely(float64_is_any_nan(xa.VsrD(0)))) { \ + if (float64_is_signaling_nan(xa.VsrD(0), &env->fp_status)) { \ + vxsnan_flag = true; \ + } \ + xt.VsrD(0) = xa.VsrD(0); \ + } else if (unlikely(float64_is_any_nan(xb.VsrD(0)))) { \ + if (float64_is_signaling_nan(xb.VsrD(0), &env->fp_status)) { \ + vxsnan_flag = true; \ + } \ + xt.VsrD(0) = xb.VsrD(0); \ + } else if (float64_is_zero(xa.VsrD(0)) && float64_is_zero(xb.VsrD(0))) { \ + if (max) { \ + if (!float64_is_neg(xa.VsrD(0)) || !float64_is_neg(xb.VsrD(0))) { \ + xt.VsrD(0) = 0ULL; \ + } else { \ + xt.VsrD(0) = 0x8000000000000000ULL; \ + } \ + } else { \ + if (float64_is_neg(xa.VsrD(0)) || float64_is_neg(xb.VsrD(0))) { \ + xt.VsrD(0) = 0x8000000000000000ULL; \ + } else { \ + xt.VsrD(0) = 0ULL; \ + } \ + } \ + } else if ((max && \ + !float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) || \ + (!max && \ + float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status))) { \ + xt.VsrD(0) = xa.VsrD(0); \ + } else { \ + xt.VsrD(0) = xb.VsrD(0); \ + } \ + \ + vex_flag = fpscr_ve & vxsnan_flag; \ + if (vxsnan_flag) { \ + float_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ + } \ + if (!vex_flag) { \ + putVSR(rD(opcode) + 32, &xt, env); \ + } \ +} \ + +VSX_MAX_MINJ(xsmaxjdp, 1); +VSX_MAX_MINJ(xsminjdp, 0); + /* VSX_CMP - VSX floating point compare * op - instruction mnemonic * nels - number of elements (1, 2 or 4) diff --git a/target/ppc/helper.h b/target/ppc/helper.h index fe3267e14b..cc81709e42 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -433,6 +433,8 @@ DEF_HELPER_2(xsmaxdp, void, env, i32) DEF_HELPER_2(xsmindp, void, env, i32) DEF_HELPER_2(xsmaxcdp, void, env, i32) DEF_HELPER_2(xsmincdp, void, env, i32) +DEF_HELPER_2(xsmaxjdp, void, env, i32) +DEF_HELPER_2(xsminjdp, void, env, i32) DEF_HELPER_2(xscvdphp, void, env, i32) DEF_HELPER_2(xscvdpqp, void, env, i32) DEF_HELPER_2(xscvdpsp, void, env, i32) diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 3251dca8e7..8de8cd0db8 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -810,6 +810,8 @@ GEN_VSX_HELPER_2(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsmindp, 0x00, 0x15, 0, PPC2_VSX) GEN_VSX_HELPER_2(xsmaxcdp, 0x00, 0x10, 0, PPC2_ISA300) GEN_VSX_HELPER_2(xsmincdp, 0x00, 0x11, 0, PPC2_ISA300) +GEN_VSX_HELPER_2(xsmaxjdp, 0x00, 0x12, 0, PPC2_ISA300) +GEN_VSX_HELPER_2(xsminjdp, 0x00, 0x12, 0, PPC2_ISA300) GEN_VSX_HELPER_2(xscvdphp, 0x16, 0x15, 0x11, PPC2_ISA300) GEN_VSX_HELPER_2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX) GEN_VSX_HELPER_2(xscvdpqp, 0x04, 0x1A, 0x16, PPC2_ISA300) diff --git a/target/ppc/translate/vsx-ops.inc.c b/target/ppc/translate/vsx-ops.inc.c index 16a135fd87..c1b71ad862 100644 --- a/target/ppc/translate/vsx-ops.inc.c +++ b/target/ppc/translate/vsx-ops.inc.c @@ -202,6 +202,8 @@ GEN_XX3FORM(xsmaxdp, 0x00, 0x14, PPC2_VSX), GEN_XX3FORM(xsmindp, 0x00, 0x15, PPC2_VSX), GEN_XX3FORM(xsmaxcdp, 0x00, 0x10, PPC2_ISA300), GEN_XX3FORM(xsmincdp, 0x00, 0x11, PPC2_ISA300), +GEN_XX3FORM(xsmaxjdp, 0x00, 0x12, PPC2_ISA300), +GEN_XX3FORM(xsminjdp, 0x00, 0x13, PPC2_ISA300), GEN_XX2FORM_EO(xscvdphp, 0x16, 0x15, 0x11, PPC2_ISA300), GEN_XX2FORM(xscvdpsp, 0x12, 0x10, PPC2_VSX), GEN_XX2FORM(xscvdpspn, 0x16, 0x10, PPC2_VSX207), |