Blame tests/bit-test.c

Packit ae235b
#include <glib.h>
Packit ae235b
Packit ae235b
#if defined(__GNUC__) && (__GNUC__ >= 4)
Packit ae235b
# define TEST_BUILTINS 1
Packit ae235b
#else
Packit ae235b
# define TEST_BUILTINS 0
Packit ae235b
#endif
Packit ae235b
Packit ae235b
#if TEST_BUILTINS
Packit ae235b
static gint
Packit ae235b
builtin_bit_nth_lsf1 (gulong mask, gint nth_bit)
Packit ae235b
{
Packit ae235b
  if (nth_bit >= 0)
Packit ae235b
    {
Packit ae235b
      if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1))
Packit ae235b
	mask &= -(1UL<<(nth_bit+1));
Packit ae235b
      else
Packit ae235b
	mask = 0;
Packit ae235b
    }
Packit ae235b
  return __builtin_ffsl(mask) - 1;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gint
Packit ae235b
builtin_bit_nth_lsf2 (gulong mask, gint nth_bit)
Packit ae235b
{
Packit ae235b
  if (nth_bit >= 0)
Packit ae235b
    {
Packit ae235b
      if (G_LIKELY (nth_bit < GLIB_SIZEOF_LONG * 8 - 1))
Packit ae235b
	mask &= -(1UL<<(nth_bit+1));
Packit ae235b
      else
Packit ae235b
	mask = 0;
Packit ae235b
    }
Packit ae235b
  return mask ? __builtin_ctzl(mask) : -1;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gint
Packit ae235b
builtin_bit_nth_msf (gulong mask, gint nth_bit)
Packit ae235b
{
Packit ae235b
  if (nth_bit >= 0 && nth_bit < GLIB_SIZEOF_LONG * 8)
Packit ae235b
    mask &= (1UL<
Packit ae235b
  return mask ? GLIB_SIZEOF_LONG * 8 - 1 - __builtin_clzl(mask) : -1;
Packit ae235b
}
Packit ae235b
Packit ae235b
Packit ae235b
static guint
Packit ae235b
builtin_bit_storage (gulong number)
Packit ae235b
{
Packit ae235b
  return number ? GLIB_SIZEOF_LONG * 8 - __builtin_clzl(number) : 1;
Packit ae235b
}
Packit ae235b
#endif
Packit ae235b
Packit ae235b
Packit ae235b
static gint
Packit ae235b
naive_bit_nth_lsf (gulong mask, gint   nth_bit)
Packit ae235b
{
Packit ae235b
  if (G_UNLIKELY (nth_bit < -1))
Packit ae235b
    nth_bit = -1;
Packit ae235b
  while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1))
Packit ae235b
    {
Packit ae235b
      nth_bit++;
Packit ae235b
      if (mask & (1UL << nth_bit))
Packit ae235b
	return nth_bit;
Packit ae235b
    }
Packit ae235b
  return -1;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gint
Packit ae235b
naive_bit_nth_msf (gulong mask, gint   nth_bit)
Packit ae235b
{
Packit ae235b
  if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8))
Packit ae235b
    nth_bit = GLIB_SIZEOF_LONG * 8;
Packit ae235b
  while (nth_bit > 0)
Packit ae235b
    {
Packit ae235b
      nth_bit--;
Packit ae235b
      if (mask & (1UL << nth_bit))
Packit ae235b
	return nth_bit;
Packit ae235b
    }
Packit ae235b
  return -1;
Packit ae235b
}
Packit ae235b
Packit ae235b
static guint
Packit ae235b
naive_bit_storage (gulong number)
Packit ae235b
{
Packit ae235b
  guint n_bits = 0;
Packit ae235b
  
Packit ae235b
  do
Packit ae235b
    {
Packit ae235b
      n_bits++;
Packit ae235b
      number >>= 1;
Packit ae235b
    }
Packit ae235b
  while (number);
Packit ae235b
  return n_bits;
Packit ae235b
}
Packit ae235b
Packit ae235b
Packit ae235b
Packit ae235b
#define TEST(f1, f2, i) \
Packit ae235b
	if (f1 (i) != f2 (i)) { \
Packit ae235b
		g_error (G_STRINGIFY (f1) " (%lu) = %d; " \
Packit ae235b
			 G_STRINGIFY (f2) " (%lu) = %d; ", \
Packit ae235b
			 i, f1 (i), \
Packit ae235b
			 i, f2 (i)); \
Packit ae235b
		return 1; \
Packit ae235b
	}
Packit ae235b
#define TEST2(f1, f2, i, n) \
Packit ae235b
	if (f1 (i, n) != f2 (i, n)) { \
Packit ae235b
		g_error (G_STRINGIFY (f1) " (%lu, %d) = %d; " \
Packit ae235b
			 G_STRINGIFY (f2) " (%lu, %d) = %d; ", \
Packit ae235b
			 i, n, f1 (i, n), \
Packit ae235b
			 i, n, f2 (i, n)); \
Packit ae235b
		return 1; \
Packit ae235b
	}
Packit ae235b
Packit ae235b
int
Packit ae235b
main (void)
Packit ae235b
{
Packit ae235b
  gulong i;
Packit ae235b
  gint nth_bit;
Packit ae235b
Packit ae235b
  /* we loop like this: 0, -1, 1, -2, 2, -3, 3, ... */
Packit ae235b
  for (i = 0; (glong)i < 1500 ; i = -(i+((glong)i>=0))) {
Packit ae235b
Packit ae235b
#if TEST_BUILTINS
Packit ae235b
    TEST (naive_bit_storage, builtin_bit_storage, i);
Packit ae235b
#endif
Packit ae235b
    TEST (naive_bit_storage, g_bit_storage, i);
Packit ae235b
Packit ae235b
    for (nth_bit = -3; nth_bit <= 2 + GLIB_SIZEOF_LONG * 8; nth_bit++) {
Packit ae235b
Packit ae235b
#if TEST_BUILTINS
Packit ae235b
      TEST2 (naive_bit_nth_lsf, builtin_bit_nth_lsf1, i, nth_bit);
Packit ae235b
      TEST2 (naive_bit_nth_lsf, builtin_bit_nth_lsf2, i, nth_bit);
Packit ae235b
#endif
Packit ae235b
      TEST2 (naive_bit_nth_lsf, g_bit_nth_lsf, i, nth_bit);
Packit ae235b
Packit ae235b
#if TEST_BUILTINS
Packit ae235b
      TEST2 (naive_bit_nth_msf, builtin_bit_nth_msf, i, nth_bit);
Packit ae235b
#endif
Packit ae235b
      TEST2 (naive_bit_nth_msf, g_bit_nth_msf, i, nth_bit);
Packit ae235b
Packit ae235b
    }
Packit ae235b
  }
Packit ae235b
Packit ae235b
  return 0;
Packit ae235b
}