1 #include <limits.h>
2 #include <assert.h>
3 
4 #if __INT_MAX__ > 2147483647L
5 # if __INT_MAX__ >= 9223372036854775807L
6 #  define BITSIZEOF_INT 64
7 # else
8 #  define BITSIZEOF_INT 32
9 # endif
10 #else
11 # if __INT_MAX__ >= 2147483647L
12 #  define BITSIZEOF_INT 32
13 # else
14 #  define BITSIZEOF_INT 16
15 # endif
16 #endif
17 
18 #if __LONG_MAX__ > 2147483647L
19 # if __LONG_MAX__ >= 9223372036854775807L
20 #  define BITSIZEOF_LONG 64
21 # else
22 #  define BITSIZEOF_LONG 32
23 # endif
24 #else
25 # define BITSIZEOF_LONG 32
26 #endif
27 
28 #if __LONG_LONG_MAX__ > 2147483647L
29 # if __LONG_LONG_MAX__ >= 9223372036854775807L
30 #  define BITSIZEOF_LONG_LONG 64
31 # else
32 #  define BITSIZEOF_LONG_LONG 32
33 # endif
34 #else
35 # define BITSIZEOF_LONG_LONG 32
36 #endif
37 
38 #define MAKE_FUNS(suffix, type)						\
39 int my_ffs##suffix(type x) {						\
40     int i;								\
41     if (x == 0)								\
42 	 return 0; 							\
43     for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
44 	if (x & ((type) 1  << i))					\
45 	    break;							\
46     return i + 1;							\
47 }									\
48 									\
49 int my_ctz##suffix(type x) {						\
50     int i;								\
51     for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
52 	if (x & ((type) 1  << i))					\
53 	    break;							\
54     return i;								\
55 }									\
56 									\
57 int my_clz##suffix(type x) {						\
58     int i;								\
59     for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
60 	if (x & ((type) 1 << ((CHAR_BIT * sizeof (type)) - i - 1)))	\
61 	    break;							\
62     return i;								\
63 }									\
64 									\
65 int my_clrsb##suffix(type x) {						\
66     int i;								\
67     int leading = (x >> CHAR_BIT * sizeof (type) - 1) & 1;		\
68     for (i = 1; i < CHAR_BIT * sizeof (type); i++)			\
69 	if (((x >> ((CHAR_BIT * sizeof (type)) - i - 1)) & 1)		\
70 	    != leading)							\
71 	    break;							\
72     return i - 1;							\
73 }									\
74 									\
75 int my_popcount##suffix(type x) {					\
76     int i;								\
77     int count = 0;							\
78     for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
79 	if (x & ((type) 1 << i))					\
80 	    count++;							\
81     return count;							\
82 }									\
83 									\
84 int my_parity##suffix(type x) {						\
85     int i;								\
86     int count = 0;							\
87     for (i = 0; i < CHAR_BIT * sizeof (type); i++)			\
88 	if (x & ((type) 1 << i))					\
89 	    count++;							\
90     return count & 1;							\
91 }
92 
93 MAKE_FUNS (, unsigned);
94 MAKE_FUNS (l, unsigned long);
95 MAKE_FUNS (ll, unsigned long long);
96 
97 extern void abort (void);
98 extern void exit (int);
99 
100 #define NUMS16					\
101   {						\
102     0x0000U,					\
103     0x0001U,					\
104     0x8000U,					\
105     0x0002U,					\
106     0x4000U,					\
107     0x0100U,					\
108     0x0080U,					\
109     0xa5a5U,					\
110     0x5a5aU,					\
111     0xcafeU,					\
112     0xffffU					\
113   }
114 
115 #define NUMS32					\
116   {						\
117     0x00000000UL,				\
118     0x00000001UL,				\
119     0x80000000UL,				\
120     0x00000002UL,				\
121     0x40000000UL,				\
122     0x00010000UL,				\
123     0x00008000UL,				\
124     0xa5a5a5a5UL,				\
125     0x5a5a5a5aUL,				\
126     0xcafe0000UL,				\
127     0x00cafe00UL,				\
128     0x0000cafeUL,				\
129     0xffffffffUL				\
130   }
131 
132 #define NUMS64					\
133   {						\
134     0x0000000000000000ULL,			\
135     0x0000000000000001ULL,			\
136     0x8000000000000000ULL,			\
137     0x0000000000000002ULL,			\
138     0x4000000000000000ULL,			\
139     0x0000000100000000ULL,			\
140     0x0000000080000000ULL,			\
141     0xa5a5a5a5a5a5a5a5ULL,			\
142     0x5a5a5a5a5a5a5a5aULL,			\
143     0xcafecafe00000000ULL,			\
144     0x0000cafecafe0000ULL,			\
145     0x00000000cafecafeULL,			\
146     0xffffffffffffffffULL			\
147   }
148 
149 unsigned int ints[] =
150 #if BITSIZEOF_INT == 64
151 NUMS64;
152 #elif BITSIZEOF_INT == 32
153 NUMS32;
154 #else
155 NUMS16;
156 #endif
157 
158 unsigned long longs[] =
159 #if BITSIZEOF_LONG == 64
160 NUMS64;
161 #else
162 NUMS32;
163 #endif
164 
165 unsigned long long longlongs[] =
166 #if BITSIZEOF_LONG_LONG == 64
167 NUMS64;
168 #else
169 NUMS32;
170 #endif
171 
172 #define N(table) (sizeof (table) / sizeof (table[0]))
173 
174 int
main(void)175 main (void)
176 {
177   int i;
178 
179   for (i = 0; i < N(ints); i++)
180     {
181       if (__builtin_ffs (ints[i]) != my_ffs (ints[i]))
182 	abort ();
183       if (ints[i] != 0
184 	  && __builtin_clz (ints[i]) != my_clz (ints[i]))
185 	abort ();
186       if (ints[i] != 0
187 	  && __builtin_ctz (ints[i]) != my_ctz (ints[i]))
188 	abort ();
189       if (__builtin_clrsb (ints[i]) != my_clrsb (ints[i]))
190 	abort ();
191       if (__builtin_popcount (ints[i]) != my_popcount (ints[i]))
192 	abort ();
193       if (__builtin_parity (ints[i]) != my_parity (ints[i]))
194 	abort ();
195     }
196 
197   for (i = 0; i < N(longs); i++)
198     {
199       if (__builtin_ffsl (longs[i]) != my_ffsl (longs[i]))
200 	abort ();
201       if (longs[i] != 0
202 	  && __builtin_clzl (longs[i]) != my_clzl (longs[i]))
203 	abort ();
204       if (longs[i] != 0
205 	  && __builtin_ctzl (longs[i]) != my_ctzl (longs[i]))
206 	abort ();
207       if (__builtin_clrsbl (longs[i]) != my_clrsbl (longs[i]))
208 	abort ();
209       if (__builtin_popcountl (longs[i]) != my_popcountl (longs[i]))
210 	abort ();
211       if (__builtin_parityl (longs[i]) != my_parityl (longs[i]))
212 	abort ();
213     }
214 
215   for (i = 0; i < N(longlongs); i++)
216     {
217       if (__builtin_ffsll (longlongs[i]) != my_ffsll (longlongs[i]))
218 	abort ();
219       if (longlongs[i] != 0
220 	  && __builtin_clzll (longlongs[i]) != my_clzll (longlongs[i]))
221 	abort ();
222       if (longlongs[i] != 0
223 	  && __builtin_ctzll (longlongs[i]) != my_ctzll (longlongs[i]))
224 	abort ();
225       if (__builtin_clrsbll (longlongs[i]) != my_clrsbll (longlongs[i]))
226 	abort ();
227       if (__builtin_popcountll (longlongs[i]) != my_popcountll (longlongs[i]))
228 	abort ();
229       if (__builtin_parityll (longlongs[i]) != my_parityll (longlongs[i]))
230 	abort ();
231     }
232 
233   /* Test constant folding.  */
234 
235 #define TEST(x, suffix)							\
236   if (__builtin_ffs##suffix (x) != my_ffs##suffix (x))			\
237     abort ();								\
238   if (x != 0 && __builtin_clz##suffix (x) != my_clz##suffix (x))	\
239     abort ();								\
240   if (x != 0 && __builtin_ctz##suffix (x) != my_ctz##suffix (x))	\
241     abort ();								\
242   if (__builtin_clrsb##suffix (x) != my_clrsb##suffix (x))		\
243     abort ();								\
244   if (__builtin_popcount##suffix (x) != my_popcount##suffix (x))	\
245     abort ();								\
246   if (__builtin_parity##suffix (x) != my_parity##suffix (x))		\
247     abort ();
248 
249 #if BITSIZEOF_INT == 32
250   TEST(0x00000000UL,);
251   TEST(0x00000001UL,);
252   TEST(0x80000000UL,);
253   TEST(0x40000000UL,);
254   TEST(0x00010000UL,);
255   TEST(0x00008000UL,);
256   TEST(0xa5a5a5a5UL,);
257   TEST(0x5a5a5a5aUL,);
258   TEST(0xcafe0000UL,);
259   TEST(0x00cafe00UL,);
260   TEST(0x0000cafeUL,);
261   TEST(0xffffffffUL,);
262 #endif
263 
264 #if BITSIZEOF_LONG_LONG == 64
265   TEST(0x0000000000000000ULL, ll);
266   TEST(0x0000000000000001ULL, ll);
267   TEST(0x8000000000000000ULL, ll);
268   TEST(0x0000000000000002ULL, ll);
269   TEST(0x4000000000000000ULL, ll);
270   TEST(0x0000000100000000ULL, ll);
271   TEST(0x0000000080000000ULL, ll);
272   TEST(0xa5a5a5a5a5a5a5a5ULL, ll);
273   TEST(0x5a5a5a5a5a5a5a5aULL, ll);
274   TEST(0xcafecafe00000000ULL, ll);
275   TEST(0x0000cafecafe0000ULL, ll);
276   TEST(0x00000000cafecafeULL, ll);
277   TEST(0xffffffffffffffffULL, ll);
278 #endif
279 
280   exit (0);
281 }
282