diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2007-01-03 20:08:53 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2007-01-03 20:08:53 +0000 |
commit | 048efdfbd59b00fe184c1cda7e9cf4af9b447156 (patch) | |
tree | 7bc74aaf55f37931c5ffe78a7f3cf32fa420d694 /glib/gutils.h | |
parent | bf1b1d2711075d75aab68844ba15a5493686eec3 (diff) | |
download | glib-048efdfbd59b00fe184c1cda7e9cf4af9b447156.tar.gz |
Fix bug in g_bit_nth_lsf (#371631) and use __builtin_clzl for
2007-01-03 Behdad Esfahbod <behdad@gnome.org>
* glib/gutils.h: Fix bug in g_bit_nth_lsf (#371631) and use
__builtin_clzl for g_bit_storage if available (#371670).
* tests/Makefile.am:
* tests/bit-test.c: New test, to test g_bit_* operations against
naive and builtin implementations.
svn path=/trunk/; revision=5200
Diffstat (limited to 'glib/gutils.h')
-rw-r--r-- | glib/gutils.h | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/glib/gutils.h b/glib/gutils.h index 6a0ca4784..06845b0be 100644 --- a/glib/gutils.h +++ b/glib/gutils.h @@ -250,10 +250,10 @@ gchar* g_find_program_in_path (const gchar *program); /* Bit tests */ G_INLINE_FUNC gint g_bit_nth_lsf (gulong mask, - gint nth_bit); + gint nth_bit) G_GNUC_CONST; G_INLINE_FUNC gint g_bit_nth_msf (gulong mask, - gint nth_bit); -G_INLINE_FUNC guint g_bit_storage (gulong number); + gint nth_bit) G_GNUC_CONST; +G_INLINE_FUNC guint g_bit_storage (gulong number) G_GNUC_CONST; /* Trash Stacks * elements need to be >= sizeof (gpointer) @@ -277,33 +277,36 @@ G_INLINE_FUNC gint g_bit_nth_lsf (gulong mask, gint nth_bit) { - do + if (G_UNLIKELY (nth_bit < -1)) + nth_bit = -1; + while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1)) { nth_bit++; if (mask & (1UL << nth_bit)) return nth_bit; } - while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1)); return -1; } G_INLINE_FUNC gint g_bit_nth_msf (gulong mask, gint nth_bit) { - if (nth_bit < 0) + if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8)) nth_bit = GLIB_SIZEOF_LONG * 8; - do + while (nth_bit > 0) { nth_bit--; if (mask & (1UL << nth_bit)) return nth_bit; } - while (nth_bit > 0); return -1; } G_INLINE_FUNC guint g_bit_storage (gulong number) { +#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) + return number ? GLIB_SIZEOF_LONG * 8 - __builtin_clzl(number) : 1; +#else register guint n_bits = 0; do @@ -313,6 +316,7 @@ g_bit_storage (gulong number) } while (number); return n_bits; +#endif } G_INLINE_FUNC void g_trash_stack_push (GTrashStack **stack_p, |