Patchwork [36/47] host-utils: add ffsl and flsl

login
register
mail settings
Submitter Paolo Bonzini
Date July 24, 2012, 11:04 a.m.
Message ID <1343127865-16608-37-git-send-email-pbonzini@redhat.com>
Download mbox | patch
Permalink /patch/172834/
State New
Headers show

Comments

Paolo Bonzini - July 24, 2012, 11:04 a.m.
We can provide fast versions based on the other functions defined
by host-utils.h.  Some care is required on glibc, which provides
ffsl already.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 host-utils.h |   45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
Eric Blake - July 27, 2012, 4:05 p.m.
On 07/24/2012 05:04 AM, Paolo Bonzini wrote:
> We can provide fast versions based on the other functions defined
> by host-utils.h.  Some care is required on glibc, which provides
> ffsl already.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  host-utils.h |   45 +++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)

> +#ifdef __GLIBC__
> +#define ffsl qemu_ffsl
> +#endif
> +static inline int ffsl(long val)

ffsl() makes sense in comparison to the standardized ffs() (why POSIX
doesn't specify one is beyond me).

> +
> +static inline int flsl(long val)

But what good is flsl (I'm assuming you mean find-last-set, or the
most-significant set bit), especially since there is no standardized
fls() and no fls() in host-utils.h?
Paolo Bonzini - July 30, 2012, 1:30 p.m.
Il 27/07/2012 18:05, Eric Blake ha scritto:
>> > +static inline int flsl(long val)
> But what good is flsl (I'm assuming you mean find-last-set, or the
> most-significant set bit), especially since there is no standardized
> fls() and no fls() in host-utils.h?

No idea why I thought that fls existed.

Paolo

Patch

diff --git a/host-utils.h b/host-utils.h
index 821db93..4250eb0 100644
--- a/host-utils.h
+++ b/host-utils.h
@@ -24,6 +24,7 @@ 
  */
 
 #include "compiler.h"   /* QEMU_GNUC_PREREQ */
+#include <string.h>     /* ffsl */
 
 #if defined(__x86_64__)
 #define __HAVE_FAST_MULU64__
@@ -234,3 +235,47 @@  static inline int ctpop64(uint64_t val)
     return val;
 #endif
 }
+
+/* glibc does not provide an inline version of ffsl, so always define
+ * ours.
+ */
+#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
+}
+
+static inline int flsl(long val)
+{
+    if (!val) {
+        return 0;
+    }
+
+#if QEMU_GNUC_PREREQ(3, 4)
+    return __builtin_clzl(val) + 1;
+#else
+    if (sizeof(long) == 4) {
+        return clz32(val) + 1;
+    } else if (sizeof(long) == 8) {
+        return clz64(val) + 1;
+    } else {
+        abort();
+    }
+#endif
+}