qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 04/18] target-ppc: Add ISA2.06 divde[o] Instructions


From: Tom Musta
Subject: [Qemu-devel] [PATCH 04/18] target-ppc: Add ISA2.06 divde[o] Instructions
Date: Mon, 9 Dec 2013 09:47:01 -0600

This patch adds the Divide Doubleword Extended instructions.
The implementation builds on the unsigned helper provided in
the previous patch.

Signed-off-by: Tom Musta <address@hidden>
---
 target-ppc/helper.h     |    1 +
 target-ppc/int_helper.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
 target-ppc/translate.c  |    4 ++++
 3 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 3eff4df..4359009 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -32,6 +32,7 @@ DEF_HELPER_5(lscbx, tl, env, tl, i32, i32, i32)
 #if defined(TARGET_PPC64)
 DEF_HELPER_3(mulldo, i64, env, i64, i64)
 DEF_HELPER_4(divdeu, i64, env, i64, i64, i32)
+DEF_HELPER_4(divde, i64, env, i64, i64, i32)
 #endif
 
 DEF_HELPER_FLAGS_1(cntlzw, TCG_CALL_NO_RWG_SE, tl, tl)
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 94a54d2..bd41d4b 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -85,6 +85,50 @@ uint64_t helper_divdeu(CPUPPCState *env, uint64_t ra, 
uint64_t rb, uint32_t oe)
     return rt;
 }
 
+uint64_t helper_divde(CPUPPCState *env, uint64_t rau, uint64_t rbu, uint32_t 
oe)
+{
+    int64_t rt = 0;
+    int64_t ra = (int64_t)rau;
+    int64_t rb = (int64_t)rbu;
+    int overflow = 0;
+
+    int sgna = (ra < 0) ? 1 : 0;
+    int sgnb = (rb < 0) ? 1 : 0;
+
+    if (sgna) {
+        ra = 0 - ra;
+    }
+
+    if (sgnb) {
+        rb = 0 - rb;
+    }
+
+    _divide_u64_extended(ra, rb, (uint64_t *)&rt, &overflow);
+
+    if (sgna ^ sgnb) {
+        rt = 0 - rt;
+    }
+
+    if (oe) {
+
+        if (overflow == 0) {
+            int sgnt = (rt < 0) ? 1 : 0;
+            if (sgnt ^ (sgna ^ sgnb)) {
+                overflow = 1;
+                rt = 0; /* undefined */
+            }
+        }
+
+        if (unlikely(overflow)) {
+            env->so = env->ov = 1;
+        } else {
+            env->ov = 0;
+        }
+    }
+
+    return rt;
+}
+
 #endif
 
 
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 7a51c6d..b274a15 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -1048,6 +1048,8 @@ static void gen_##name(DisasContext *ctx)                 
                    \
 
 GEN_DIVDE(divdeu, divdeu, 0);
 GEN_DIVDE(divdeuo, divdeu, 1);
+GEN_DIVDE(divde, divde, 0);
+GEN_DIVDE(divdeo, divde, 1);
 
 #endif
 
@@ -9613,6 +9615,8 @@ GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1),
 
 GEN_HANDLER_E(divdeu, 0x1F, 0x09, 0x0C, 0x00000000, PPC_NONE, PPC2_ISA206),
 GEN_HANDLER_E(divdeuo, 0x1F, 0x09, 0x1C, 0x00000000, PPC_NONE, PPC2_ISA206),
+GEN_HANDLER_E(divde, 0x1F, 0x09, 0x0D, 0x00000000, PPC_NONE, PPC2_ISA206),
+GEN_HANDLER_E(divdeo, 0x1F, 0x09, 0x1D, 0x00000000, PPC_NONE, PPC2_ISA206),
 
 #undef GEN_INT_ARITH_MUL_HELPER
 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]