aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2009-02-09 16:49:10 +0000
committeraurel32 <aurel32@c046a42c-6fe2-441c-8c8c-71466251a162>2009-02-09 16:49:10 +0000
commit819ca12127ee43c722f9946c8493a0aa2a1de6a0 (patch)
treee3c3a2da32269b08fb9f56e432e3e6d2cef733cf
parent35cf7c7e183775b3a850730804c8d64f56b9c02e (diff)
target-ppc: Add vcmp{eq, ge, gt, b}fp{, .} instructions
Signed-off-by: Nathan Froyd <froydnj@codesourcery.com> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6571 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--target-ppc/helper.h8
-rw-r--r--target-ppc/op_helper.c68
-rw-r--r--target-ppc/translate.c4
3 files changed, 80 insertions, 0 deletions
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index af6c8396c0..089955b1ce 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -132,6 +132,10 @@ DEF_HELPER_3(vcmpgtuw, void, avr, avr, avr)
DEF_HELPER_3(vcmpgtsb, void, avr, avr, avr)
DEF_HELPER_3(vcmpgtsh, void, avr, avr, avr)
DEF_HELPER_3(vcmpgtsw, void, avr, avr, avr)
+DEF_HELPER_3(vcmpeqfp, void, avr, avr, avr)
+DEF_HELPER_3(vcmpgefp, void, avr, avr, avr)
+DEF_HELPER_3(vcmpgtfp, void, avr, avr, avr)
+DEF_HELPER_3(vcmpbfp, void, avr, avr, avr)
DEF_HELPER_3(vcmpequb_dot, void, avr, avr, avr)
DEF_HELPER_3(vcmpequh_dot, void, avr, avr, avr)
DEF_HELPER_3(vcmpequw_dot, void, avr, avr, avr)
@@ -141,6 +145,10 @@ DEF_HELPER_3(vcmpgtuw_dot, void, avr, avr, avr)
DEF_HELPER_3(vcmpgtsb_dot, void, avr, avr, avr)
DEF_HELPER_3(vcmpgtsh_dot, void, avr, avr, avr)
DEF_HELPER_3(vcmpgtsw_dot, void, avr, avr, avr)
+DEF_HELPER_3(vcmpeqfp_dot, void, avr, avr, avr)
+DEF_HELPER_3(vcmpgefp_dot, void, avr, avr, avr)
+DEF_HELPER_3(vcmpgtfp_dot, void, avr, avr, avr)
+DEF_HELPER_3(vcmpbfp_dot, void, avr, avr, avr)
DEF_HELPER_3(vmrglb, void, avr, avr, avr)
DEF_HELPER_3(vmrglh, void, avr, avr, avr)
DEF_HELPER_3(vmrglw, void, avr, avr, avr)
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index f59cd15cf6..d40caf0e8e 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -2220,6 +2220,74 @@ VCMP(gtsw, >, s32)
#undef VCMP_DO
#undef VCMP
+#define VCMPFP_DO(suffix, compare, order, record) \
+ void helper_vcmp##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \
+ { \
+ uint32_t ones = (uint32_t)-1; \
+ uint32_t all = ones; \
+ uint32_t none = 0; \
+ int i; \
+ for (i = 0; i < ARRAY_SIZE(r->f); i++) { \
+ uint32_t result; \
+ int rel = float32_compare_quiet(a->f[i], b->f[i], &env->vec_status); \
+ if (rel == float_relation_unordered) { \
+ result = 0; \
+ } else if (rel compare order) { \
+ result = ones; \
+ } else { \
+ result = 0; \
+ } \
+ r->u32[i] = result; \
+ all &= result; \
+ none |= result; \
+ } \
+ if (record) { \
+ env->crf[6] = ((all != 0) << 3) | ((none == 0) << 1); \
+ } \
+ }
+#define VCMPFP(suffix, compare, order) \
+ VCMPFP_DO(suffix, compare, order, 0) \
+ VCMPFP_DO(suffix##_dot, compare, order, 1)
+VCMPFP(eqfp, ==, float_relation_equal)
+VCMPFP(gefp, !=, float_relation_less)
+VCMPFP(gtfp, ==, float_relation_greater)
+#undef VCMPFP_DO
+#undef VCMPFP
+
+static always_inline void vcmpbfp_internal (ppc_avr_t *r, ppc_avr_t *a,
+ ppc_avr_t *b, int record)
+{
+ int i;
+ int all_in = 0;
+ for (i = 0; i < ARRAY_SIZE(r->f); i++) {
+ int le_rel = float32_compare_quiet(a->f[i], b->f[i], &env->vec_status);
+ if (le_rel == float_relation_unordered) {
+ r->u32[i] = 0xc0000000;
+ /* ALL_IN does not need to be updated here. */
+ } else {
+ float32 bneg = float32_chs(b->f[i]);
+ int ge_rel = float32_compare_quiet(a->f[i], bneg, &env->vec_status);
+ int le = le_rel != float_relation_greater;
+ int ge = ge_rel != float_relation_less;
+ r->u32[i] = ((!le) << 31) | ((!ge) << 30);
+ all_in |= (!le | !ge);
+ }
+ }
+ if (record) {
+ env->crf[6] = (all_in == 0) << 1;
+ }
+}
+
+void helper_vcmpbfp (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+ vcmpbfp_internal(r, a, b, 0);
+}
+
+void helper_vcmpbfp_dot (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
+{
+ vcmpbfp_internal(r, a, b, 1);
+}
+
void helper_vmaddfp (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c)
{
int i;
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 88426af946..a722f65c09 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6430,6 +6430,10 @@ GEN_VXRFORM(vcmpgtsw, 3, 14)
GEN_VXRFORM(vcmpgtub, 3, 8)
GEN_VXRFORM(vcmpgtuh, 3, 9)
GEN_VXRFORM(vcmpgtuw, 3, 10)
+GEN_VXRFORM(vcmpeqfp, 3, 3)
+GEN_VXRFORM(vcmpgefp, 3, 7)
+GEN_VXRFORM(vcmpgtfp, 3, 11)
+GEN_VXRFORM(vcmpbfp, 3, 15)
#define GEN_VXFORM_SIMM(name, opc2, opc3) \
GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC) \