qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 1/2] host-utils: Use __int128 for mul[us]64


From: Blue Swirl
Subject: Re: [Qemu-devel] [PATCH 1/2] host-utils: Use __int128 for mul[us]64
Date: Mon, 28 Jan 2013 20:29:25 +0000

On Mon, Jan 28, 2013 at 6:52 PM, Richard Henderson <address@hidden> wrote:
> 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.

In OpenBIOS we use __int128_t and __uint128_t, which are closer in
form to standard types. Could you use those instead of __int128 and
unsigned  __int128?

>
> 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;

__uint128_t?

> +    *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
>
>



reply via email to

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