blob: 7907a753341cc0e0502f359a30a27e1472ebf326 [file] [log] [blame]
#include <limits.h>
#include <assert.h>
#if __INT_MAX__ > 2147483647L
# if __INT_MAX__ >= 9223372036854775807L
# define BITSIZEOF_INT 64
# else
# define BITSIZEOF_INT 32
# endif
#else
# if __INT_MAX__ >= 2147483647L
# define BITSIZEOF_INT 32
# else
# define BITSIZEOF_INT 16
# endif
#endif
#if __LONG_MAX__ > 2147483647L
# if __LONG_MAX__ >= 9223372036854775807L
# define BITSIZEOF_LONG 64
# else
# define BITSIZEOF_LONG 32
# endif
#else
# define BITSIZEOF_LONG 32
#endif
#if __LONG_LONG_MAX__ > 2147483647L
# if __LONG_LONG_MAX__ >= 9223372036854775807L
# define BITSIZEOF_LONG_LONG 64
# else
# define BITSIZEOF_LONG_LONG 32
# endif
#else
# define BITSIZEOF_LONG_LONG 32
#endif
#define MAKE_FUNS(suffix, type) \
int my_ffs##suffix(type x) { \
int i; \
if (x == 0) \
return 0; \
for (i = 0; i < CHAR_BIT * sizeof (type); i++) \
if (x & ((type) 1 << i)) \
break; \
return i + 1; \
} \
\
int my_ctz##suffix(type x) { \
int i; \
for (i = 0; i < CHAR_BIT * sizeof (type); i++) \
if (x & ((type) 1 << i)) \
break; \
return i; \
} \
\
int my_clz##suffix(type x) { \
int i; \
for (i = 0; i < CHAR_BIT * sizeof (type); i++) \
if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1))) \
break; \
return i; \
} \
\
int my_clrsb##suffix(type x) { \
int i; \
int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1; \
for (i = 1; i < CHAR_BIT * sizeof (type); i++) \
if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1) \
!= leading) \
break; \
return i - 1; \
} \
\
int my_popcount##suffix(type x) { \
int i; \
int count = 0; \
for (i = 0; i < CHAR_BIT * sizeof (type); i++) \
if (x & ((type) 1 << i)) \
count++; \
return count; \
} \
\
int my_parity##suffix(type x) { \
int i; \
int count = 0; \
for (i = 0; i < CHAR_BIT * sizeof (type); i++) \
if (x & ((type) 1 << i)) \
count++; \
return count & 1; \
}
MAKE_FUNS (, unsigned);
MAKE_FUNS (l, unsigned long);
MAKE_FUNS (ll, unsigned long long);
extern void abort (void);
extern void exit (int);
#define NUMS16 \
{ \
0x0000U, \
0x0001U, \
0x8000U, \
0x0002U, \
0x4000U, \
0x0100U, \
0x0080U, \
0xa5a5U, \
0x5a5aU, \
0xcafeU, \
0xffffU \
}
#define NUMS32 \
{ \
0x00000000UL, \
0x00000001UL, \
0x80000000UL, \
0x00000002UL, \
0x40000000UL, \
0x00010000UL, \
0x00008000UL, \
0xa5a5a5a5UL, \
0x5a5a5a5aUL, \
0xcafe0000UL, \
0x00cafe00UL, \
0x0000cafeUL, \
0xffffffffUL \
}
#define NUMS64 \
{ \
0x0000000000000000ULL, \
0x0000000000000001ULL, \
0x8000000000000000ULL, \
0x0000000000000002ULL, \
0x4000000000000000ULL, \
0x0000000100000000ULL, \
0x0000000080000000ULL, \
0xa5a5a5a5a5a5a5a5ULL, \
0x5a5a5a5a5a5a5a5aULL, \
0xcafecafe00000000ULL, \
0x0000cafecafe0000ULL, \
0x00000000cafecafeULL, \
0xffffffffffffffffULL \
}
unsigned int ints[] =
#if BITSIZEOF_INT == 64
NUMS64;
#elif BITSIZEOF_INT == 32
NUMS32;
#else
NUMS16;
#endif
unsigned long longs[] =
#if BITSIZEOF_LONG == 64
NUMS64;
#else
NUMS32;
#endif
unsigned long long longlongs[] =
#if BITSIZEOF_LONG_LONG == 64
NUMS64;
#else
NUMS32;
#endif
#define N(table) (sizeof (table) / sizeof (table[0]))
int
main (void)
{
int i;
for (i = 0; i < N(ints); i++)
{
if (__builtin_ffs (ints[i]) != my_ffs (ints[i]))
abort ();
if (ints[i] != 0
&& __builtin_clz (ints[i]) != my_clz (ints[i]))
abort ();
if (ints[i] != 0
&& __builtin_ctz (ints[i]) != my_ctz (ints[i]))
abort ();
if (__builtin_clrsb (ints[i]) != my_clrsb (ints[i]))
abort ();
if (__builtin_popcount (ints[i]) != my_popcount (ints[i]))
abort ();
if (__builtin_parity (ints[i]) != my_parity (ints[i]))
abort ();
}
for (i = 0; i < N(longs); i++)
{
if (__builtin_ffsl (longs[i]) != my_ffsl (longs[i]))
abort ();
if (longs[i] != 0
&& __builtin_clzl (longs[i]) != my_clzl (longs[i]))
abort ();
if (longs[i] != 0
&& __builtin_ctzl (longs[i]) != my_ctzl (longs[i]))
abort ();
if (__builtin_clrsbl (longs[i]) != my_clrsbl (longs[i]))
abort ();
if (__builtin_popcountl (longs[i]) != my_popcountl (longs[i]))
abort ();
if (__builtin_parityl (longs[i]) != my_parityl (longs[i]))
abort ();
}
for (i = 0; i < N(longlongs); i++)
{
if (__builtin_ffsll (longlongs[i]) != my_ffsll (longlongs[i]))
abort ();
if (longlongs[i] != 0
&& __builtin_clzll (longlongs[i]) != my_clzll (longlongs[i]))
abort ();
if (longlongs[i] != 0
&& __builtin_ctzll (longlongs[i]) != my_ctzll (longlongs[i]))
abort ();
if (__builtin_clrsbll (longlongs[i]) != my_clrsbll (longlongs[i]))
abort ();
if (__builtin_popcountll (longlongs[i]) != my_popcountll (longlongs[i]))
abort ();
if (__builtin_parityll (longlongs[i]) != my_parityll (longlongs[i]))
abort ();
}
/* Test constant folding. */
#define TEST(x, suffix) \
if (__builtin_ffs##suffix (x) != my_ffs##suffix (x)) \
abort (); \
if (x != 0 && __builtin_clz##suffix (x) != my_clz##suffix (x)) \
abort (); \
if (x != 0 && __builtin_ctz##suffix (x) != my_ctz##suffix (x)) \
abort (); \
if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x)) \
abort (); \
if (__builtin_popcount##suffix (x) != my_popcount##suffix (x)) \
abort (); \
if (__builtin_parity##suffix (x) != my_parity##suffix (x)) \
abort ();
#if BITSIZEOF_INT == 32
TEST(0x00000000UL,);
TEST(0x00000001UL,);
TEST(0x80000000UL,);
TEST(0x40000000UL,);
TEST(0x00010000UL,);
TEST(0x00008000UL,);
TEST(0xa5a5a5a5UL,);
TEST(0x5a5a5a5aUL,);
TEST(0xcafe0000UL,);
TEST(0x00cafe00UL,);
TEST(0x0000cafeUL,);
TEST(0xffffffffUL,);
#endif
#if BITSIZEOF_LONG_LONG == 64
TEST(0x0000000000000000ULL, ll);
TEST(0x0000000000000001ULL, ll);
TEST(0x8000000000000000ULL, ll);
TEST(0x0000000000000002ULL, ll);
TEST(0x4000000000000000ULL, ll);
TEST(0x0000000100000000ULL, ll);
TEST(0x0000000080000000ULL, ll);
TEST(0xa5a5a5a5a5a5a5a5ULL, ll);
TEST(0x5a5a5a5a5a5a5a5aULL, ll);
TEST(0xcafecafe00000000ULL, ll);
TEST(0x0000cafecafe0000ULL, ll);
TEST(0x00000000cafecafeULL, ll);
TEST(0xffffffffffffffffULL, ll);
#endif
exit (0);
}