summary refs log tree commit diff stats
path: root/util/host-utils.c
diff options
context:
space:
mode:
authorTom Musta <tommusta@gmail.com>2014-01-07 10:05:52 -0600
committerAlexander Graf <agraf@suse.de>2014-03-05 03:06:39 +0100
commite44259b6d4f4de69a868510a198b2696f24118a1 (patch)
tree08d61c8be5c091ca24b46a85ce20023fc4b442bc /util/host-utils.c
parent98d1eb2748e84f9e3118d1bd2495f0cc917ac18d (diff)
downloadfocaccia-qemu-e44259b6d4f4de69a868510a198b2696f24118a1.tar.gz
focaccia-qemu-e44259b6d4f4de69a868510a198b2696f24118a1.zip
target-ppc: Add ISA2.06 divde[o] Instructions
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 <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'util/host-utils.c')
-rw-r--r--util/host-utils.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/util/host-utils.c b/util/host-utils.c
index 37c1706de6..ee57ef55f6 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -124,4 +124,41 @@ int divu128(uint64_t *plow, uint64_t *phigh, uint64_t divisor)
         return 0;
     }
 }
+
+int divs128(int64_t *plow, int64_t *phigh, int64_t divisor)
+{
+    int sgn_dvdnd = *phigh < 0;
+    int sgn_divsr = divisor < 0;
+    int overflow = 0;
+
+    if (sgn_dvdnd) {
+        *plow = ~(*plow);
+        *phigh = ~(*phigh);
+        if (*plow == (int64_t)-1) {
+            *plow = 0;
+            (*phigh)++;
+         } else {
+            (*plow)++;
+         }
+    }
+
+    if (sgn_divsr) {
+        divisor = 0 - divisor;
+    }
+
+    overflow = divu128((uint64_t *)plow, (uint64_t *)phigh, (uint64_t)divisor);
+
+    if (sgn_dvdnd  ^ sgn_divsr) {
+        *plow = 0 - *plow;
+    }
+
+    if (!overflow) {
+        if ((*plow < 0) ^ (sgn_dvdnd ^ sgn_divsr)) {
+            overflow = 1;
+        }
+    }
+
+    return overflow;
+}
+
 #endif /* !CONFIG_INT128 */