Message ID | 1359568655-23982-1-git-send-email-pbonzini@redhat.com |
---|---|
State | New |
Headers | show |
Il 30/01/2013 18:57, Paolo Bonzini ha scritto: > @@ -30,34 +31,21 @@ > */ > static unsigned long bitops_ffsl(unsigned long word) > { > - int num = 0; > +#if QEMU_GNUC_PREREQ(3, 4) > + return __builtin_ffsl(word) + 1; Obviously wrong, sent before "git commit --amend". But it also reminds me that I noticed most uses of ffsl tend to subtract one, and GCC optimizes it a little better if it is written as ctz + 1 and inlined. Nacked-by: Paolo Bonzini <pbonzini@redhat.com> but v1 stands. Paolo > +#else > + if (!word) { > + return 0; > + } > > -#if LONG_MAX > 0x7FFFFFFF > - if ((word & 0xffffffff) == 0) { > - num += 32; > - word >>= 32; > - } > + if (sizeof(long) == 4) { > + return ctz32(word) + 1; > + } else if (sizeof(long) == 8) { > + return ctz64(word) + 1; > + } else { > + abort(); > + } > #endif > - if ((word & 0xffff) == 0) { > - num += 16; > - word >>= 16; > - } > - if ((word & 0xff) == 0) { > - num += 8; > - word >>= 8; > - } > - if ((word & 0xf) == 0) { > - num += 4; > - word >>= 4; > - } > - if ((word & 0x3) == 0) { > - num += 2; > - word >>= 2; > - } > - if ((word & 0x1) == 0) { > - num += 1; > - } > - return num; > } > > /** > diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h > index 73f5d1d..abad209 100644 > --- a/include/qemu/hbitmap.h > +++ b/include/qemu/hbitmap.h > @@ -170,7 +170,7 @@ static inline int64_t hbitmap_iter_next(HBitmapIter *hbi) > > /* The next call will resume work from the next bit. */ > hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1); > - item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ffsl(cur) - 1; > + item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + bitops_ffsl(cur) - 1; > > return item << hbi->granularity; > } > diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h > index 2a32be4..40457bd 100644 > --- a/include/qemu/host-utils.h > +++ b/include/qemu/host-utils.h > @@ -238,29 +238,4 @@ static inline int ctpop64(uint64_t val) > #endif > } > > -/* glibc does not provide an inline version of ffsl, so always define > - * ours. We need to give it a different name, however. > - */ > -#ifdef __GLIBC__ > -#define ffsl qemu_ffsl > -#endif > -static inline int ffsl(long val) > -{ > - if (!val) { > - return 0; > - } > - > -#if QEMU_GNUC_PREREQ(3, 4) > - return __builtin_ctzl(val) + 1; > -#else > - if (sizeof(long) == 4) { > - return ctz32(val) + 1; > - } else if (sizeof(long) == 8) { > - return ctz64(val) + 1; > - } else { > - abort(); > - } > -#endif > -} > - > #endif > diff --git a/util/hbitmap.c b/util/hbitmap.c > index 2aa487d..32c3d59 100644 > --- a/util/hbitmap.c > +++ b/util/hbitmap.c > @@ -126,7 +126,7 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi) > * The index of this word's least significant set bit provides > * the low-order bits. > */ > - pos = (pos << BITS_PER_LEVEL) + ffsl(cur) - 1; > + pos = (pos << BITS_PER_LEVEL) + bitops_ffsl(cur) - 1; > hbi->cur[i] = cur & (cur - 1); > > /* Set up next level for iteration. */ >
On 01/30/2013 10:57 AM, Paolo Bonzini wrote: > Fixes the build on Mac OS X, which has ffsl. > > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > --- > include/qemu/bitops.h | 40 ++++++++++++++-------------------------- > include/qemu/hbitmap.h | 2 +- > include/qemu/host-utils.h | 25 ------------------------- > util/hbitmap.c | 2 +- > 4 files changed, 16 insertions(+), 53 deletions(-) > > diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h > index 74e14e5..27b2d42 100644 > --- a/include/qemu/bitops.h > +++ b/include/qemu/bitops.h > @@ -13,6 +13,7 @@ > #define BITOPS_H > > #include "qemu-common.h" > +#include "host-utils.h" > > #define BITS_PER_BYTE CHAR_BIT > #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) > @@ -30,34 +31,21 @@ > */ > static unsigned long bitops_ffsl(unsigned long word) > { > - int num = 0; > +#if QEMU_GNUC_PREREQ(3, 4) > + return __builtin_ffsl(word) + 1; Nope. The +1 is wrong (it was only needed when using __builtin_ctzl()).
Am 30.01.2013 18:57, schrieb Paolo Bonzini: > Fixes the build on Mac OS X, which has ffsl. > > Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> > --- > include/qemu/bitops.h | 40 ++++++++++++++-------------------------- > include/qemu/hbitmap.h | 2 +- > include/qemu/host-utils.h | 25 ------------------------- > util/hbitmap.c | 2 +- > 4 files changed, 16 insertions(+), 53 deletions(-) For MinGW / MinGW-w64 builds: Tested-by: Stefan Weil <sw@weilnetz.de>
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h index 74e14e5..27b2d42 100644 --- a/include/qemu/bitops.h +++ b/include/qemu/bitops.h @@ -13,6 +13,7 @@ #define BITOPS_H #include "qemu-common.h" +#include "host-utils.h" #define BITS_PER_BYTE CHAR_BIT #define BITS_PER_LONG (sizeof (unsigned long) * BITS_PER_BYTE) @@ -30,34 +31,21 @@ */ static unsigned long bitops_ffsl(unsigned long word) { - int num = 0; +#if QEMU_GNUC_PREREQ(3, 4) + return __builtin_ffsl(word) + 1; +#else + if (!word) { + return 0; + } -#if LONG_MAX > 0x7FFFFFFF - if ((word & 0xffffffff) == 0) { - num += 32; - word >>= 32; - } + if (sizeof(long) == 4) { + return ctz32(word) + 1; + } else if (sizeof(long) == 8) { + return ctz64(word) + 1; + } else { + abort(); + } #endif - if ((word & 0xffff) == 0) { - num += 16; - word >>= 16; - } - if ((word & 0xff) == 0) { - num += 8; - word >>= 8; - } - if ((word & 0xf) == 0) { - num += 4; - word >>= 4; - } - if ((word & 0x3) == 0) { - num += 2; - word >>= 2; - } - if ((word & 0x1) == 0) { - num += 1; - } - return num; } /** diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h index 73f5d1d..abad209 100644 --- a/include/qemu/hbitmap.h +++ b/include/qemu/hbitmap.h @@ -170,7 +170,7 @@ static inline int64_t hbitmap_iter_next(HBitmapIter *hbi) /* The next call will resume work from the next bit. */ hbi->cur[HBITMAP_LEVELS - 1] = cur & (cur - 1); - item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + ffsl(cur) - 1; + item = ((uint64_t)hbi->pos << BITS_PER_LEVEL) + bitops_ffsl(cur) - 1; return item << hbi->granularity; } diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h index 2a32be4..40457bd 100644 --- a/include/qemu/host-utils.h +++ b/include/qemu/host-utils.h @@ -238,29 +238,4 @@ static inline int ctpop64(uint64_t val) #endif } -/* glibc does not provide an inline version of ffsl, so always define - * ours. We need to give it a different name, however. - */ -#ifdef __GLIBC__ -#define ffsl qemu_ffsl -#endif -static inline int ffsl(long val) -{ - if (!val) { - return 0; - } - -#if QEMU_GNUC_PREREQ(3, 4) - return __builtin_ctzl(val) + 1; -#else - if (sizeof(long) == 4) { - return ctz32(val) + 1; - } else if (sizeof(long) == 8) { - return ctz64(val) + 1; - } else { - abort(); - } -#endif -} - #endif diff --git a/util/hbitmap.c b/util/hbitmap.c index 2aa487d..32c3d59 100644 --- a/util/hbitmap.c +++ b/util/hbitmap.c @@ -126,7 +126,7 @@ unsigned long hbitmap_iter_skip_words(HBitmapIter *hbi) * The index of this word's least significant set bit provides * the low-order bits. */ - pos = (pos << BITS_PER_LEVEL) + ffsl(cur) - 1; + pos = (pos << BITS_PER_LEVEL) + bitops_ffsl(cur) - 1; hbi->cur[i] = cur & (cur - 1); /* Set up next level for iteration. */
Fixes the build on Mac OS X, which has ffsl. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> --- include/qemu/bitops.h | 40 ++++++++++++++-------------------------- include/qemu/hbitmap.h | 2 +- include/qemu/host-utils.h | 25 ------------------------- util/hbitmap.c | 2 +- 4 files changed, 16 insertions(+), 53 deletions(-)