diff options
author | Richard Henderson <rth@twiddle.net> | 2013-02-16 12:46:59 -0800 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2013-02-17 14:28:57 +0000 |
commit | f540166b7dfdf4ec2057ac322d8cbfd0691e1d65 (patch) | |
tree | 9ed4b3eed2a58ad4c14ec8e728fedf70bbb4d905 | |
parent | be96bd3fbffde908a392c830c856063e122791c1 (diff) | |
download | qemu-f540166b7dfdf4ec2057ac322d8cbfd0691e1d65.zip qemu-f540166b7dfdf4ec2057ac322d8cbfd0691e1d65.tar.gz qemu-f540166b7dfdf4ec2057ac322d8cbfd0691e1d65.tar.bz2 |
host-utils: Use __int128_t for mul[us]64
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 <rth@twiddle.net>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
-rwxr-xr-x | configure | 20 | ||||
-rw-r--r-- | include/qemu/host-utils.h | 17 | ||||
-rw-r--r-- | util/host-utils.c | 4 |
3 files changed, 30 insertions, 11 deletions
@@ -3150,6 +3150,22 @@ if compile_prog "" "" ; then cpuid_h=yes fi +######################################## +# check if __[u]int128_t is usable. + +int128=no +cat > $TMPC << EOF +__int128_t a; +__uint128_t b; +int main (void) { + a = a + b; + b = 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 f0dd850..0f688c1 100644 --- a/include/qemu/host-utils.h +++ b/include/qemu/host-utils.h @@ -28,22 +28,21 @@ #include "qemu/compiler.h" /* QEMU_GNUC_PREREQ */ #include <limits.h> -#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)); + __uint128_t r = (__uint128_t)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_t r = (__int128_t)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 */ |