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
This commit is contained in:
Behdad Esfahbod
2007-01-03 20:08:53 +00:00
committed by Behdad Esfahbod
parent bf1b1d2711
commit 048efdfbd5
4 changed files with 168 additions and 8 deletions

View File

@@ -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,