[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 1/2] host-utils: Use __int128 for mul[us]64
From: |
Richard Henderson |
Subject: |
[Qemu-devel] [PATCH 1/2] host-utils: Use __int128 for mul[us]64 |
Date: |
Mon, 28 Jan 2013 10:52:33 -0800 |
Replace some x86_64 specific inline assembly with something that
all 64-bit hosts ought to optimize well. At worst this becomes a
call to the gcc __multi3 routine, which is no worse than our
implementation in util/host-utils.c.
With gcc 4.7, we get identical code generation for x86_64. We
now get native multiplication on ia64 and s390x hosts. With minor
improvements to gcc we can get it for ppc64 as well.
Signed-off-by: Richard Henderson <address@hidden>
---
configure | 20 ++++++++++++++++++++
include/qemu/host-utils.h | 17 ++++++++---------
util/host-utils.c | 4 ++--
3 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/configure b/configure
index b7635e4..ecf1cbc 100755
--- a/configure
+++ b/configure
@@ -3150,6 +3150,22 @@ if compile_prog "" "" ; then
cpuid_h=yes
fi
+########################################
+# check if __int128 is usable.
+
+int128=no
+cat > $TMPC << EOF
+int main (void) {
+ __int128 a = 0;
+ unsigned __int128 b = 1;
+ a = a + b;
+ a = a * b;
+ return 0;
+}
+EOF
+if compile_prog "" "" ; then
+ int128=yes
+fi
##########################################
# End of CC checks
@@ -3692,6 +3708,10 @@ if test "$cpuid_h" = "yes" ; then
echo "CONFIG_CPUID_H=y" >> $config_host_mak
fi
+if test "$int128" = "yes" ; then
+ echo "CONFIG_INT128=y" >> $config_host_mak
+fi
+
if test "$glusterfs" = "yes" ; then
echo "CONFIG_GLUSTERFS=y" >> $config_host_mak
fi
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 81c9a75..01f6610 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -27,22 +27,21 @@
#include "qemu/compiler.h" /* QEMU_GNUC_PREREQ */
-#if defined(__x86_64__)
-#define __HAVE_FAST_MULU64__
+#ifdef CONFIG_INT128
static inline void mulu64(uint64_t *plow, uint64_t *phigh,
uint64_t a, uint64_t b)
{
- __asm__ ("mul %0\n\t"
- : "=d" (*phigh), "=a" (*plow)
- : "a" (a), "0" (b));
+ unsigned __int128 r = (unsigned __int128)a * b;
+ *plow = r;
+ *phigh = r >> 64;
}
-#define __HAVE_FAST_MULS64__
+
static inline void muls64(uint64_t *plow, uint64_t *phigh,
int64_t a, int64_t b)
{
- __asm__ ("imul %0\n\t"
- : "=d" (*phigh), "=a" (*plow)
- : "a" (a), "0" (b));
+ __int128 r = (__int128)a * b;
+ *plow = r;
+ *phigh = r >> 64;
}
#else
void muls64(uint64_t *phigh, uint64_t *plow, int64_t a, int64_t b);
diff --git a/util/host-utils.c b/util/host-utils.c
index 5e3915a..2d06a2c 100644
--- a/util/host-utils.c
+++ b/util/host-utils.c
@@ -30,7 +30,7 @@
//#define DEBUG_MULDIV
/* Long integer helpers */
-#if !defined(__x86_64__)
+#ifndef CONFIG_INT128
static void add128 (uint64_t *plow, uint64_t *phigh, uint64_t a, uint64_t b)
{
*plow += a;
@@ -102,4 +102,4 @@ void muls64 (uint64_t *plow, uint64_t *phigh, int64_t a,
int64_t b)
a, b, *phigh, *plow);
#endif
}
-#endif /* !defined(__x86_64__) */
+#endif /* !CONFIG_INT128 */
--
1.7.11.7