aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorBharata B Rao <bharata@linux.vnet.ibm.com>2017-02-06 16:00:00 +0530
committerDavid Gibson <david@gibson.dropbear.id.au>2017-02-22 11:28:27 +1100
commitd4ccd87e6894569f5535eed94e45bf1bbba0478c (patch)
treed14614f465c0fd845f7c9522ef0e2b06d6429102 /target
parent2770deede0ad4a7f1e9e41a75b96e4eeb9a8305d (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.c55
-rw-r--r--target/ppc/helper.h2
-rw-r--r--target/ppc/translate/vsx-impl.inc.c2
-rw-r--r--target/ppc/translate/vsx-ops.inc.c2
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),