xref: /illumos-gate/usr/src/test/libc-tests/tests/stdbit.c (revision 4b9db4f6425b1a08fca4390f446072c4a6aae8d5)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2024 Oxide Computer Company
14  */
15 
16 /*
17  * Test various aspects of the libc stdbit(3HEAD) interfaces. This does not test
18  * the generic interfaces so that way this can be built and run by compilers
19  * that don't support C23 and we also want to explicitly test the various type
20  * specific values.
21  *
22  * This test is built 32-bit and 64-bit. The width of a long varies between an
23  * ILP32 and LP64 environment and therefore will end up getting back different
24  * values. Hence the ifdefs.
25  */
26 
27 #include <stdbit.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <err.h>
31 #include <sys/debug.h>
32 #include <sys/sysmacros.h>
33 
34 typedef enum {
35 	STDBIT_TEST_U8	 = 1 << 0,
36 	STDBIT_TEST_U16	 = 1 << 1,
37 	STDBIT_TEST_U32	 = 1 << 2,
38 	STDBIT_TEST_U64	 = 1 << 3
39 } stdbit_test_type_t;
40 
41 #define	STDBIT_TEST_64P	(STDBIT_TEST_U64)
42 #define	STDBIT_TEST_32P	(STDBIT_TEST_U32  | STDBIT_TEST_64P)
43 #define	STDBIT_TEST_16P	(STDBIT_TEST_U16 | STDBIT_TEST_32P)
44 #define	STDBIT_TEST_ALL	(STDBIT_TEST_U8 | STDBIT_TEST_16P)
45 
46 typedef struct {
47 	const char *so_name;
48 	unsigned int (*so_uc)(unsigned char);
49 	unsigned int (*so_us)(unsigned short);
50 	unsigned int (*so_ui)(unsigned int);
51 	unsigned int (*so_ul)(unsigned long);
52 	unsigned int (*so_ull)(unsigned long long);
53 	int32_t so_delta[3];
54 } stdbit_ops_t;
55 
56 typedef struct {
57 	stdbit_test_type_t st_types;
58 	uint64_t st_val;
59 	uint64_t st_res;
60 } stdbit_test_t;
61 
62 /*
63  * Count Leading Zeros tests. As the integer increases in size, there are a
64  * bunch of leading zeros added, hence the delta values in this entry.
65  */
66 static const stdbit_ops_t stdbit_clz_ops = {
67 	.so_name = "Count Leading Zeros",
68 	.so_uc = stdc_leading_zeros_uc,
69 	.so_us = stdc_leading_zeros_us,
70 	.so_ui = stdc_leading_zeros_ui,
71 	.so_ul = stdc_leading_zeros_ul,
72 	.so_ull = stdc_leading_zeros_ull,
73 	.so_delta = { 8, 16, 32 }
74 };
75 
76 static const stdbit_test_t stdbit_clz_tests[] = { {
77 	.st_types = STDBIT_TEST_ALL,
78 	.st_val = 0,
79 	.st_res = 8
80 }, {
81 	.st_types = STDBIT_TEST_ALL,
82 	.st_val = UINT8_MAX,
83 	.st_res = 0
84 }, {
85 	.st_types = STDBIT_TEST_ALL,
86 	.st_val = 0x42,
87 	.st_res = 1
88 }, {
89 	.st_types = STDBIT_TEST_ALL,
90 	.st_val = 1,
91 	.st_res = 7
92 }, {
93 	.st_types = STDBIT_TEST_16P,
94 	.st_val = UINT16_MAX,
95 	.st_res = 0
96 }, {
97 	.st_types = STDBIT_TEST_16P,
98 	.st_val = 0x7777,
99 	.st_res = 1
100 }, {
101 	.st_types = STDBIT_TEST_16P,
102 	.st_val = 0x800,
103 	.st_res = 4
104 }, {
105 	.st_types = STDBIT_TEST_16P,
106 	.st_val = 0x080,
107 	.st_res = 8
108 }, {
109 	.st_types = STDBIT_TEST_16P,
110 	.st_val = 0x008,
111 	.st_res = 12
112 }, {
113 	.st_types = STDBIT_TEST_32P,
114 	.st_val = UINT32_MAX,
115 	.st_res = 0
116 }, {
117 	.st_types = STDBIT_TEST_32P,
118 	.st_val = 0x23000000,
119 	.st_res = 2
120 }, {
121 	.st_types = STDBIT_TEST_32P,
122 	.st_val = 0x23000032,
123 	.st_res = 2
124 }, {
125 	.st_types = STDBIT_TEST_64P,
126 	.st_val = 0x400000000,
127 	.st_res = 29
128 }, {
129 	.st_types = STDBIT_TEST_64P,
130 	.st_val = UINT64_MAX,
131 	.st_res = 0
132 } };
133 
134 /*
135  * Unlike count leading zeros, when we take a value and hand it to a larger
136  * function, it will always go to a value of zero. As a result, we don't test
137  * many of this suite across everything.
138  */
139 static const stdbit_ops_t stdbit_clo_ops = {
140 	.so_name = "Count Leading Ones",
141 	.so_uc = stdc_leading_ones_uc,
142 	.so_us = stdc_leading_ones_us,
143 	.so_ui = stdc_leading_ones_ui,
144 	.so_ul = stdc_leading_ones_ul,
145 	.so_ull = stdc_leading_ones_ull,
146 };
147 
148 
149 static const stdbit_test_t stdbit_clo_tests[] = { {
150 	.st_types = STDBIT_TEST_U8,
151 	.st_val = UINT8_MAX,
152 	.st_res = 8
153 }, {
154 	.st_types = STDBIT_TEST_ALL,
155 	.st_val = 0,
156 	.st_res = 0
157 }, {
158 	.st_types = STDBIT_TEST_ALL,
159 	.st_val = 0x42,
160 	.st_res = 0
161 }, {
162 	.st_types = STDBIT_TEST_U8,
163 	.st_val = 0xe0,
164 	.st_res = 3
165 }, {
166 	.st_types = STDBIT_TEST_U8,
167 	.st_val = 0xfc,
168 	.st_res = 6
169 }, {
170 	.st_types = STDBIT_TEST_16P,
171 	.st_val = UINT8_MAX,
172 	.st_res = 0
173 }, {
174 	.st_types = STDBIT_TEST_16P,
175 	.st_val = 0x142,
176 	.st_res = 0
177 }, {
178 	.st_types = STDBIT_TEST_U16,
179 	.st_val = UINT16_MAX,
180 	.st_res = 16
181 }, {
182 	.st_types = STDBIT_TEST_U16,
183 	.st_val = 0xc0ff,
184 	.st_res = 2
185 }, {
186 	.st_types = STDBIT_TEST_U16,
187 	.st_val = 0xf88f,
188 	.st_res = 5
189 }, {
190 	.st_types = STDBIT_TEST_U32,
191 	.st_val = 0x12345678,
192 	.st_res = 0
193 }, {
194 	.st_types = STDBIT_TEST_U32,
195 	.st_val = UINT32_MAX,
196 	.st_res = 32
197 }, {
198 	.st_types = STDBIT_TEST_U32,
199 	.st_val = 0x87654321,
200 	.st_res = 1
201 }, {
202 	.st_types = STDBIT_TEST_U32,
203 	.st_val = 0xff7ff7ff,
204 	.st_res = 8
205 }, {
206 	.st_types = STDBIT_TEST_U32,
207 	.st_val = 0xfffffeee,
208 	.st_res = 23
209 }, {
210 	.st_types = STDBIT_TEST_U64,
211 	.st_val = UINT64_MAX,
212 	.st_res = 64
213 }, {
214 	.st_types = STDBIT_TEST_U64,
215 	.st_val = 0x8000000000000000,
216 	.st_res = 1
217 }, {
218 	.st_types = STDBIT_TEST_U64,
219 	.st_val = 0xffffffff80000000,
220 	.st_res = 33
221 }, {
222 	.st_types = STDBIT_TEST_U64,
223 	.st_val = 0xffffffffffff9999,
224 	.st_res = 49
225 } };
226 
227 /*
228  * The results for zero is the only special case that occurs with this
229  * particular case.
230  */
231 static const stdbit_ops_t stdbit_ctz_ops = {
232 	.so_name = "Count Trailing Zeros",
233 	.so_uc = stdc_trailing_zeros_uc,
234 	.so_us = stdc_trailing_zeros_us,
235 	.so_ui = stdc_trailing_zeros_ui,
236 	.so_ul = stdc_trailing_zeros_ul,
237 	.so_ull = stdc_trailing_zeros_ull,
238 };
239 
240 static const stdbit_test_t stdbit_ctz_tests[] = { {
241 	.st_types = STDBIT_TEST_U8,
242 	.st_val = 0,
243 	.st_res = 8
244 }, {
245 	.st_types = STDBIT_TEST_U16,
246 	.st_val = 0,
247 	.st_res = 16
248 }, {
249 	.st_types = STDBIT_TEST_U32,
250 	.st_val = 0,
251 	.st_res = 32
252 }, {
253 	.st_types = STDBIT_TEST_U64,
254 	.st_val = 0,
255 	.st_res = 64
256 }, {
257 	.st_types = STDBIT_TEST_ALL,
258 	.st_val = UINT8_MAX,
259 	.st_res = 0
260 }, {
261 	.st_types = STDBIT_TEST_ALL,
262 	.st_val = 0x1,
263 	.st_res = 0
264 }, {
265 	.st_types = STDBIT_TEST_ALL,
266 	.st_val = 0x4,
267 	.st_res = 2
268 }, {
269 	.st_types = STDBIT_TEST_ALL,
270 	.st_val = 0x80,
271 	.st_res = 7
272 }, {
273 	.st_types = STDBIT_TEST_16P,
274 	.st_val = 0xff60,
275 	.st_res = 5
276 }, {
277 	.st_types = STDBIT_TEST_16P,
278 	.st_val = 0x8ad0,
279 	.st_res = 4
280 }, {
281 	.st_types = STDBIT_TEST_16P,
282 	.st_val = 0x2300,
283 	.st_res = 8
284 }, {
285 	.st_types = STDBIT_TEST_32P,
286 	.st_val = 0x42000000,
287 	.st_res = 25
288 }, {
289 	.st_types = STDBIT_TEST_32P,
290 	.st_val = 0x99887700,
291 	.st_res = 8
292 }, {
293 	.st_types = STDBIT_TEST_32P,
294 	.st_val = UINT32_MAX,
295 	.st_res = 0
296 }, {
297 	.st_types = STDBIT_TEST_64P,
298 	.st_val = 0xaa00000000000000,
299 	.st_res = 57
300 }, {
301 	.st_types = STDBIT_TEST_64P,
302 	.st_val = 0xbadcaf0000000000,
303 	.st_res = 40
304 }, {
305 	.st_types = STDBIT_TEST_64P,
306 	.st_val = UINT64_MAX,
307 	.st_res = 0
308 } };
309 
310 /*
311  * Count Trailing Ones Tests
312  */
313 static const stdbit_ops_t stdbit_cto_ops = {
314 	.so_name = "Count Trailing Ones",
315 	.so_uc = stdc_trailing_ones_uc,
316 	.so_us = stdc_trailing_ones_us,
317 	.so_ui = stdc_trailing_ones_ui,
318 	.so_ul = stdc_trailing_ones_ul,
319 	.so_ull = stdc_trailing_ones_ull,
320 };
321 
322 static const stdbit_test_t stdbit_cto_tests[] = { {
323 	.st_types = STDBIT_TEST_ALL,
324 	.st_val = UINT8_MAX,
325 	.st_res = 8
326 }, {
327 	.st_types = STDBIT_TEST_ALL,
328 	.st_val = 0,
329 	.st_res = 0
330 }, {
331 	.st_types = STDBIT_TEST_ALL,
332 	.st_val = 3,
333 	.st_res = 2
334 }, {
335 	.st_types = STDBIT_TEST_ALL,
336 	.st_val = 0x7e,
337 	.st_res = 0
338 }, {
339 	.st_types = STDBIT_TEST_ALL,
340 	.st_val = 0x7f,
341 	.st_res = 7
342 }, {
343 	.st_types = STDBIT_TEST_16P,
344 	.st_val = UINT16_MAX,
345 	.st_res = 16
346 }, {
347 	.st_types = STDBIT_TEST_16P,
348 	.st_val = 0x8765,
349 	.st_res = 1
350 }, {
351 	.st_types = STDBIT_TEST_16P,
352 	.st_val = 0xcdef,
353 	.st_res = 4
354 }, {
355 	.st_types = STDBIT_TEST_16P,
356 	.st_val = 0x9fff,
357 	.st_res = 13
358 }, {
359 	.st_types = STDBIT_TEST_32P,
360 	.st_val = UINT32_MAX,
361 	.st_res = 32
362 }, {
363 	.st_types = STDBIT_TEST_32P,
364 	.st_val = 0x85ab91ff,
365 	.st_res = 9
366 }, {
367 	.st_types = STDBIT_TEST_32P,
368 	.st_val = 0x7fffffff,
369 	.st_res = 31
370 }, {
371 	.st_types = STDBIT_TEST_64P,
372 	.st_val = UINT64_MAX,
373 	.st_res = 64
374 }, {
375 	.st_types = STDBIT_TEST_64P,
376 	.st_val = 0x1bffffffffffffff,
377 	.st_res = 58
378 }, {
379 	.st_types = STDBIT_TEST_64P,
380 	.st_val = 0x9abe83cff6ff7ff8,
381 	.st_res = 0
382 } };
383 
384 /*
385  * See the manual. The C23 definition for "most-significant" bit is
386  * counter-intuitive. Basically bit 0 is considered the most significant bit. So
387  * for a uint8_t bit 0 is considered index 7 and bit 7 is index 0. The results
388  * always have 1 added to them.
389  */
390 static const stdbit_ops_t stdbit_flz_ops = {
391 	.so_name = "First Leading Zero",
392 	.so_uc = stdc_first_leading_zero_uc,
393 	.so_us = stdc_first_leading_zero_us,
394 	.so_ui = stdc_first_leading_zero_ui,
395 	.so_ul = stdc_first_leading_zero_ul,
396 	.so_ull = stdc_first_leading_zero_ull,
397 };
398 
399 static const stdbit_test_t stdbit_flz_tests[] = { {
400 	.st_types = STDBIT_TEST_ALL,
401 	.st_val = 0,
402 	.st_res = 1
403 }, {
404 	.st_types = STDBIT_TEST_ALL,
405 	.st_val = 0x3,
406 	.st_res = 1
407 }, {
408 	.st_types = STDBIT_TEST_U8,
409 	.st_val = 0xf0,
410 	.st_res = 5
411 }, {
412 	.st_types = STDBIT_TEST_U8,
413 	.st_val = 0xef,
414 	.st_res = 4
415 }, {
416 	.st_types = STDBIT_TEST_U8,
417 	.st_val = 0xc4,
418 	.st_res = 3
419 }, {
420 	.st_types = STDBIT_TEST_U8,
421 	.st_val = UINT8_MAX,
422 	.st_res = 0
423 }, {
424 	.st_types = STDBIT_TEST_16P,
425 	.st_val = UINT8_MAX,
426 	.st_res = 1
427 }, {
428 	.st_types = STDBIT_TEST_U16,
429 	.st_val = UINT16_MAX,
430 	.st_res = 0
431 }, {
432 	.st_types = STDBIT_TEST_U16,
433 	.st_val = 0xfabc,
434 	.st_res = 6
435 }, {
436 	.st_types = STDBIT_TEST_U16,
437 	.st_val = 0xcbaf,
438 	.st_res = 3
439 }, {
440 	.st_types = STDBIT_TEST_32P,
441 	.st_val = UINT16_MAX,
442 	.st_res = 1
443 }, {
444 	.st_types = STDBIT_TEST_U32,
445 	.st_val = UINT32_MAX,
446 	.st_res = 0
447 }, {
448 	.st_types = STDBIT_TEST_U32,
449 	.st_val = 0xff7ff623,
450 	.st_res = 9
451 }, {
452 	.st_types = STDBIT_TEST_U32,
453 	.st_val = 0xfffff623,
454 	.st_res = 21
455 }, {
456 .	st_types = STDBIT_TEST_U32,
457 	.st_val = 0xffffff95,
458 	.st_res = 26
459 }, {
460 	.st_types = STDBIT_TEST_64P,
461 	.st_val = UINT32_MAX,
462 	.st_res = 1
463 }, {
464 	.st_types = STDBIT_TEST_U64,
465 	.st_val = UINT64_MAX,
466 	.st_res = 0
467 }, {
468 	.st_types = STDBIT_TEST_U64,
469 	.st_val = 0xfffffffffffffffe,
470 	.st_res = 64
471 }, {
472 	.st_types = STDBIT_TEST_U64,
473 	.st_val = 0xffff2b9542fffffe,
474 	.st_res = 17
475 } };
476 
477 /*
478  * See the note on the flz tests for the oddities with calculating this. Due to
479  * the nature of how these are counted, the larger the number gets, the more the
480  * first 1 increases in its "most-significant" value. However, we have to
481  * special case 0 in our logic because it will stay consistent across all the
482  * values.
483  */
484 static const stdbit_ops_t stdbit_flo_ops = {
485 	.so_name = "First Leading One",
486 	.so_uc = stdc_first_leading_one_uc,
487 	.so_us = stdc_first_leading_one_us,
488 	.so_ui = stdc_first_leading_one_ui,
489 	.so_ul = stdc_first_leading_one_ul,
490 	.so_ull = stdc_first_leading_one_ull,
491 	.so_delta = { 8, 16, 32 }
492 };
493 
494 static const stdbit_test_t stdbit_flo_tests[] = { {
495 	.st_types = STDBIT_TEST_U8,
496 	.st_val = 0,
497 	.st_res = 0
498 }, {
499 	.st_types = STDBIT_TEST_U16,
500 	.st_val = 0,
501 	.st_res = 0
502 }, {
503 	.st_types = STDBIT_TEST_U32,
504 	.st_val = 0,
505 	.st_res = 0
506 }, {
507 	.st_types = STDBIT_TEST_U64,
508 	.st_val = 0,
509 	.st_res = 0
510 }, {
511 	.st_types = STDBIT_TEST_ALL,
512 	.st_val = 0x1,
513 	.st_res = 8
514 }, {
515 	.st_types = STDBIT_TEST_ALL,
516 	.st_val = 0xf,
517 	.st_res = 5
518 }, {
519 	.st_types = STDBIT_TEST_ALL,
520 	.st_val = 0xfe,
521 	.st_res = 1
522 }, {
523 	.st_types = STDBIT_TEST_ALL,
524 	.st_val = 0x7f,
525 	.st_res = 2
526 }, {
527 	.st_types = STDBIT_TEST_ALL,
528 	.st_val = UINT8_MAX,
529 	.st_res = 1
530 }, {
531 	.st_types = STDBIT_TEST_16P,
532 	.st_val = UINT16_MAX,
533 	.st_res = 1
534 }, {
535 	.st_types = STDBIT_TEST_16P,
536 	.st_val = 0xfeed,
537 	.st_res = 1
538 }, {
539 	.st_types = STDBIT_TEST_16P,
540 	.st_val = 0x1aff,
541 	.st_res = 4
542 }, {
543 	.st_types = STDBIT_TEST_16P,
544 	.st_val = 0x02b0,
545 	.st_res = 7
546 }, {
547 	.st_types = STDBIT_TEST_32P,
548 	.st_val = UINT32_MAX,
549 	.st_res = 1
550 }, {
551 	.st_types = STDBIT_TEST_32P,
552 	.st_val = 0x00001234,
553 	.st_res = 20
554 }, {
555 	.st_types = STDBIT_TEST_32P,
556 	.st_val = 0x2bb22bb2,
557 	.st_res = 3
558 }, {
559 	.st_types = STDBIT_TEST_32P,
560 	.st_val = 0x00420000,
561 	.st_res = 10
562 }, {
563 	.st_types = STDBIT_TEST_64P,
564 	.st_val = UINT64_MAX,
565 	.st_res = 1
566 }, {
567 	.st_types = STDBIT_TEST_64P,
568 	.st_val = 0x000000000c000000,
569 	.st_res = 37
570 }, {
571 	.st_types = STDBIT_TEST_64P,
572 	.st_val = 0x000fedcba9abcdef,
573 	.st_res = 13
574 }, {
575 	.st_types = STDBIT_TEST_64P,
576 	.st_val = 0x000001992aa3bb4c,
577 	.st_res = 24
578 }, {
579 	.st_types = STDBIT_TEST_64P,
580 	.st_val = 0x0706050403020100,
581 	.st_res = 6
582 } };
583 
584 /*
585  * First Trailing Zero. This numbers indexes in the way that someone expects
586  * where the bit 0 is least significant index zero, which returns a value of 1.
587  * When there are no zeros this returns 0. There is no reliable increment
588  * pattern here.
589  */
590 static const stdbit_ops_t stdbit_ftz_ops = {
591 	.so_name = "First Trailing Zero",
592 	.so_uc = stdc_first_trailing_zero_uc,
593 	.so_us = stdc_first_trailing_zero_us,
594 	.so_ui = stdc_first_trailing_zero_ui,
595 	.so_ul = stdc_first_trailing_zero_ul,
596 	.so_ull = stdc_first_trailing_zero_ull,
597 };
598 
599 static const stdbit_test_t stdbit_ftz_tests[] = { {
600 	.st_types = STDBIT_TEST_ALL,
601 	.st_val = 0,
602 	.st_res = 1
603 }, {
604 	.st_types = STDBIT_TEST_U8,
605 	.st_val = UINT8_MAX,
606 	.st_res = 0
607 }, {
608 	.st_types = STDBIT_TEST_U8,
609 	.st_val = 0xfe,
610 	.st_res = 1
611 }, {
612 	.st_types = STDBIT_TEST_U8,
613 	.st_val = 0xef,
614 	.st_res = 5
615 }, {
616 	.st_types = STDBIT_TEST_U8,
617 	.st_val = 0x7f,
618 	.st_res = 8
619 }, {
620 	.st_types = STDBIT_TEST_U16,
621 	.st_val = UINT8_MAX,
622 	.st_res = 9
623 }, {
624 	.st_types = STDBIT_TEST_U16,
625 	.st_val = UINT16_MAX,
626 	.st_res = 0
627 }, {
628 	.st_types = STDBIT_TEST_U16,
629 	.st_val = 0xfffe,
630 	.st_res = 1
631 }, {
632 	.st_types = STDBIT_TEST_U16,
633 	.st_val = 0xefff,
634 	.st_res = 13
635 }, {
636 	.st_types = STDBIT_TEST_U16,
637 	.st_val = 0x07ff,
638 	.st_res = 12
639 }, {
640 	.st_types = STDBIT_TEST_U32,
641 	.st_val = UINT16_MAX,
642 	.st_res = 17
643 }, {
644 	.st_types = STDBIT_TEST_U32,
645 	.st_val = UINT32_MAX,
646 	.st_res = 0
647 }, {
648 	.st_types = STDBIT_TEST_U32,
649 	.st_val = 0xcaffffff,
650 	.st_res = 25
651 }, {
652 	.st_types = STDBIT_TEST_U32,
653 	.st_val = 0xcabfffff,
654 	.st_res = 23
655 }, {
656 	.st_types = STDBIT_TEST_U64,
657 	.st_val = UINT32_MAX,
658 	.st_res = 33
659 }, {
660 	.st_types = STDBIT_TEST_U64,
661 	.st_val = UINT64_MAX,
662 	.st_res = 0
663 }, {
664 	.st_types = STDBIT_TEST_U64,
665 	.st_val = 0xface2bface95a2ff,
666 	.st_res = 9
667 }, {
668 	.st_types = STDBIT_TEST_U64,
669 	.st_val = 0x7777777777777777,
670 	.st_res = 4
671 } };
672 
673 /*
674  * First Trailing One. This numbers indexes in the way that someone expects
675  * where the bit 0 is least significant index zero, which returns a value of 1.
676  * When there are no zeros this returns 0. This is classical ffs().
677  */
678 static const stdbit_ops_t stdbit_fto_ops = {
679 	.so_name = "First Trailing One",
680 	.so_uc = stdc_first_trailing_one_uc,
681 	.so_us = stdc_first_trailing_one_us,
682 	.so_ui = stdc_first_trailing_one_ui,
683 	.so_ul = stdc_first_trailing_one_ul,
684 	.so_ull = stdc_first_trailing_one_ull,
685 };
686 
687 static const stdbit_test_t stdbit_fto_tests[] = { {
688 	.st_types = STDBIT_TEST_ALL,
689 	.st_val = 0,
690 	.st_res = 0
691 }, {
692 	.st_types = STDBIT_TEST_ALL,
693 	.st_val = UINT8_MAX,
694 	.st_res = 1
695 }, {
696 	.st_types = STDBIT_TEST_ALL,
697 	.st_val = 0xf7,
698 	.st_res = 1
699 }, {
700 	.st_types = STDBIT_TEST_ALL,
701 	.st_val = 0xf8,
702 	.st_res = 4
703 }, {
704 	.st_types = STDBIT_TEST_ALL,
705 	.st_val = 0x6d,
706 	.st_res = 1
707 }, {
708 	.st_types = STDBIT_TEST_ALL,
709 	.st_val = 0xd6,
710 	.st_res = 2
711 }, {
712 	.st_types = STDBIT_TEST_ALL,
713 	.st_val = 0x40,
714 	.st_res = 7
715 }, {
716 	.st_types = STDBIT_TEST_16P,
717 	.st_val = UINT16_MAX,
718 	.st_res = 1
719 }, {
720 	.st_types = STDBIT_TEST_16P,
721 	.st_val = 0xf840,
722 	.st_res = 7
723 }, {
724 	.st_types = STDBIT_TEST_16P,
725 	.st_val = 0x0a00,
726 	.st_res = 10
727 }, {
728 	.st_types = STDBIT_TEST_16P,
729 	.st_val = 0x8000,
730 	.st_res = 16
731 }, {
732 	.st_types = STDBIT_TEST_32P,
733 	.st_val = UINT32_MAX,
734 	.st_res = 1
735 }, {
736 	.st_types = STDBIT_TEST_32P,
737 	.st_val = 0xb0000000,
738 	.st_res = 29
739 }, {
740 	.st_types = STDBIT_TEST_32P,
741 	.st_val = 0xf9c00000,
742 	.st_res = 23
743 }, {
744 	.st_types = STDBIT_TEST_32P,
745 	.st_val = 0xfed81500,
746 	.st_res = 9
747 }, {
748 	.st_types = STDBIT_TEST_64P,
749 	.st_val = UINT64_MAX,
750 	.st_res = 1
751 }, {
752 	.st_types = STDBIT_TEST_64P,
753 	.st_val = 0xfed80d0000000000,
754 	.st_res = 41
755 }, {
756 	.st_types = STDBIT_TEST_64P,
757 	.st_val = 0xff70000000000000,
758 	.st_res = 53
759 } };
760 
761 /*
762  * Count Zeros.
763  */
764 static const stdbit_ops_t stdbit_cz_ops = {
765 	.so_name = "Count Zeros",
766 	.so_uc = stdc_count_zeros_uc,
767 	.so_us = stdc_count_zeros_us,
768 	.so_ui = stdc_count_zeros_ui,
769 	.so_ul = stdc_count_zeros_ul,
770 	.so_ull = stdc_count_zeros_ull,
771 	.so_delta = { 8, 16, 32 }
772 };
773 
774 static const stdbit_test_t stdbit_cz_tests[] = { {
775 	.st_types = STDBIT_TEST_ALL,
776 	.st_val = 0,
777 	.st_res = 8
778 }, {
779 	.st_types = STDBIT_TEST_ALL,
780 	.st_val = UINT8_MAX,
781 	.st_res = 0
782 }, {
783 	.st_types = STDBIT_TEST_ALL,
784 	.st_val = 0x77,
785 	.st_res = 2
786 }, {
787 	.st_types = STDBIT_TEST_ALL,
788 	.st_val = 0x88,
789 	.st_res = 6
790 }, {
791 	.st_types = STDBIT_TEST_ALL,
792 	.st_val = 0x5,
793 	.st_res = 6
794 }, {
795 	.st_types = STDBIT_TEST_ALL,
796 	.st_val = 0x1f,
797 	.st_res = 3
798 }, {
799 	.st_types = STDBIT_TEST_16P,
800 	.st_val = UINT16_MAX,
801 	.st_res = 0
802 }, {
803 	.st_types = STDBIT_TEST_16P,
804 	.st_val = 0x1234,
805 	.st_res = 11
806 }, {
807 	.st_types = STDBIT_TEST_16P,
808 	.st_val = 0x4321,
809 	.st_res = 11
810 }, {
811 	.st_types = STDBIT_TEST_16P,
812 	.st_val = 0x2ba2,
813 	.st_res = 9
814 }, {
815 	.st_types = STDBIT_TEST_32P,
816 	.st_val = UINT32_MAX,
817 	.st_res = 0
818 }, {
819 	.st_types = STDBIT_TEST_32P,
820 	.st_val = 0xdeadbeef,
821 	.st_res = 8
822 }, {
823 	.st_types = STDBIT_TEST_32P,
824 	.st_val = 0x12345678,
825 	.st_res = 19
826 }, {
827 	.st_types = STDBIT_TEST_64P,
828 	.st_val = UINT64_MAX,
829 	.st_res = 0
830 }, {
831 	.st_types = STDBIT_TEST_64P,
832 	.st_val = 0xabbabccbcddcdeed,
833 	.st_res = 22
834 }, {
835 	.st_types = STDBIT_TEST_64P,
836 	.st_val = 0x1221244248848008,
837 	.st_res = 50
838 }, {
839 	.st_types = STDBIT_TEST_64P,
840 	.st_val = 0xfffffffeefffffff,
841 	.st_res = 2
842 } };
843 
844 /*
845  * Count Ones.
846  */
847 static const stdbit_ops_t stdbit_co_ops = {
848 	.so_name = "Count Ones",
849 	.so_uc = stdc_count_ones_uc,
850 	.so_us = stdc_count_ones_us,
851 	.so_ui = stdc_count_ones_ui,
852 	.so_ul = stdc_count_ones_ul,
853 	.so_ull = stdc_count_ones_ull,
854 };
855 
856 static const stdbit_test_t stdbit_co_tests[] = { {
857 	.st_types = STDBIT_TEST_ALL,
858 	.st_val = 0,
859 	.st_res = 0
860 }, {
861 	.st_types = STDBIT_TEST_ALL,
862 	.st_val = UINT8_MAX,
863 	.st_res = 8
864 }, {
865 	.st_types = STDBIT_TEST_ALL,
866 	.st_val = 0x77,
867 	.st_res = 6
868 }, {
869 	.st_types = STDBIT_TEST_ALL,
870 	.st_val = 0x88,
871 	.st_res = 2
872 }, {
873 	.st_types = STDBIT_TEST_ALL,
874 	.st_val = 0x5,
875 	.st_res = 2
876 }, {
877 	.st_types = STDBIT_TEST_ALL,
878 	.st_val = 0x1f,
879 	.st_res = 5
880 }, {
881 	.st_types = STDBIT_TEST_16P,
882 	.st_val = UINT16_MAX,
883 	.st_res = 16
884 }, {
885 	.st_types = STDBIT_TEST_16P,
886 	.st_val = 0x1234,
887 	.st_res = 5
888 }, {
889 	.st_types = STDBIT_TEST_16P,
890 	.st_val = 0x4321,
891 	.st_res = 5
892 }, {
893 	.st_types = STDBIT_TEST_16P,
894 	.st_val = 0x2ba2,
895 	.st_res = 7
896 }, {
897 	.st_types = STDBIT_TEST_32P,
898 	.st_val = UINT32_MAX,
899 	.st_res = 32
900 }, {
901 	.st_types = STDBIT_TEST_32P,
902 	.st_val = 0xdeadbeef,
903 	.st_res = 24
904 }, {
905 	.st_types = STDBIT_TEST_32P,
906 	.st_val = 0x12345678,
907 	.st_res = 13
908 }, {
909 	.st_types = STDBIT_TEST_64P,
910 	.st_val = UINT64_MAX,
911 	.st_res = 64
912 }, {
913 	.st_types = STDBIT_TEST_64P,
914 	.st_val = 0xabbabccbcddcdeed,
915 	.st_res = 42
916 }, {
917 	.st_types = STDBIT_TEST_64P,
918 	.st_val = 0x1221244248848008,
919 	.st_res = 14
920 }, {
921 	.st_types = STDBIT_TEST_64P,
922 	.st_val = 0xfffffffeefffffff,
923 	.st_res = 62
924 } };
925 
926 /*
927  * Bit width tests. These values should stay the same as we increase integer
928  * sizes as values are only adding zeros.
929  */
930 static const stdbit_ops_t stdbit_bw_ops = {
931 	.so_name = "Bit Width",
932 	.so_uc = stdc_bit_width_uc,
933 	.so_us = stdc_bit_width_us,
934 	.so_ui = stdc_bit_width_ui,
935 	.so_ul = stdc_bit_width_ul,
936 	.so_ull = stdc_bit_width_ull,
937 };
938 
939 static const stdbit_test_t stdbit_bw_tests[] = { {
940 	.st_types = STDBIT_TEST_ALL,
941 	.st_val = 0,
942 	.st_res = 0
943 }, {
944 	.st_types = STDBIT_TEST_ALL,
945 	.st_val = UINT8_MAX,
946 	.st_res = 8
947 }, {
948 	.st_types = STDBIT_TEST_ALL,
949 	.st_val = 0x80,
950 	.st_res = 8
951 }, {
952 	.st_types = STDBIT_TEST_ALL,
953 	.st_val = 0x08,
954 	.st_res = 4
955 }, {
956 	.st_types = STDBIT_TEST_ALL,
957 	.st_val = 0x17,
958 	.st_res = 5
959 }, {
960 	.st_types = STDBIT_TEST_16P,
961 	.st_val = UINT16_MAX,
962 	.st_res = 16
963 }, {
964 	.st_types = STDBIT_TEST_16P,
965 	.st_val = 0x7777,
966 	.st_res = 15
967 }, {
968 	.st_types = STDBIT_TEST_16P,
969 	.st_val = 0x2bb2,
970 	.st_res = 14
971 }, {
972 	.st_types = STDBIT_TEST_16P,
973 	.st_val = 0x0230,
974 	.st_res = 10
975 }, {
976 	.st_types = STDBIT_TEST_32P,
977 	.st_val = UINT32_MAX,
978 	.st_res = 32
979 }, {
980 	.st_types = STDBIT_TEST_32P,
981 	.st_val = 0xfedc4000,
982 	.st_res = 32
983 }, {
984 	.st_types = STDBIT_TEST_32P,
985 	.st_val = 0x0004cedf,
986 	.st_res = 19
987 }, {
988 	.st_types = STDBIT_TEST_32P,
989 	.st_val = 0x001ee100,
990 	.st_res = 21
991 }, {
992 	.st_types = STDBIT_TEST_64P,
993 	.st_val = 0x8000000000000000,
994 	.st_res = 64
995 }, {
996 	.st_types = STDBIT_TEST_64P,
997 	.st_val = 0x00ff11ee22dd33cc,
998 	.st_res = 56
999 }, {
1000 	.st_types = STDBIT_TEST_64P,
1001 	.st_val = UINT64_MAX,
1002 	.st_res = 64
1003 } };
1004 
1005 static void
stdbit_print_pass(stdbit_test_type_t types,uint64_t val,const char * cat)1006 stdbit_print_pass(stdbit_test_type_t types, uint64_t val, const char *cat)
1007 {
1008 	bool first = true;
1009 	(void) printf("TEST PASSED: %s (0x%" PRIx64 ") [", cat, val);
1010 	if ((types & STDBIT_TEST_U8) != 0) {
1011 		(void) printf("8");
1012 		first = false;
1013 	}
1014 
1015 	if ((types & STDBIT_TEST_U16) != 0) {
1016 		(void) printf("%s16", first ? "" : ",");
1017 		first = false;
1018 	}
1019 
1020 	if ((types & STDBIT_TEST_U32) != 0) {
1021 		(void) printf("%s32", first ? "" : ",");
1022 		first = false;
1023 	}
1024 
1025 	if ((types & STDBIT_TEST_U64) != 0) {
1026 		(void) printf("%s64", first ? "" : ",");
1027 		first = false;
1028 	}
1029 
1030 	(void) printf("]\n");
1031 }
1032 
1033 static bool
stdbit_test_one(const stdbit_test_t * test,const stdbit_ops_t * ops)1034 stdbit_test_one(const stdbit_test_t *test, const stdbit_ops_t *ops)
1035 {
1036 	bool ret = true;
1037 	uint64_t comp = test->st_res;
1038 
1039 	VERIFY3U(test->st_types, !=, 0);
1040 	if ((test->st_types & STDBIT_TEST_U8) != 0) {
1041 		unsigned res = ops->so_uc(test->st_val);
1042 		if (res != comp) {
1043 			warnx("TEST FAILED: %s (0x%" PRIx64 ") 8-bit (uchar) "
1044 			    "returned 0x%x, expected 0x%" PRIx64,
1045 			    ops->so_name, test->st_val, res, comp);
1046 			ret = false;
1047 		}
1048 
1049 		comp += ops->so_delta[0];
1050 	}
1051 
1052 	if ((test->st_types & STDBIT_TEST_U16) != 0) {
1053 		unsigned res = ops->so_us(test->st_val);
1054 		if (res != comp) {
1055 			warnx("TEST FAILED: %s (0x%" PRIx64 ") 16-bit (ushort) "
1056 			    "returned 0x%x, expected 0x%" PRIx64,
1057 			    ops->so_name, test->st_val, res, comp);
1058 			ret = false;
1059 		}
1060 
1061 		comp += ops->so_delta[1];
1062 	}
1063 
1064 	if ((test->st_types & STDBIT_TEST_U32) != 0) {
1065 		unsigned res = ops->so_ui(test->st_val);
1066 		if (res != comp) {
1067 			warnx("TEST FAILED: %s (0x%" PRIx64 ") 32-bit (uint) "
1068 			    "returned 0x%x, expected 0x%" PRIx64,
1069 			    ops->so_name, test->st_val, res, comp);
1070 			ret = false;
1071 		}
1072 
1073 #ifdef	_LP32
1074 		res = ops->so_ul(test->st_val);
1075 		if (res != comp) {
1076 			warnx("TEST FAILED: %s (0x%" PRIx64 ") 32-bit (ulong) "
1077 			    "returned 0x%x, expected 0x%" PRIx64,
1078 			    ops->so_name, test->st_val, res, comp);
1079 			ret = false;
1080 		}
1081 #endif	/* _LP32 */
1082 
1083 		comp += ops->so_delta[2];
1084 	}
1085 
1086 	if ((test->st_types & STDBIT_TEST_U64) != 0) {
1087 		unsigned res;
1088 #ifdef	_LP64
1089 		res = ops->so_ul(test->st_val);
1090 		if (res != comp) {
1091 			warnx("TEST FAILED: %s (0x%" PRIx64 ") 64-bit (ulong) "
1092 			    "returned 0x%x, expected 0x%" PRIx64,
1093 			    ops->so_name, test->st_val, res, comp);
1094 			ret = false;
1095 		}
1096 #endif	/* _LP64 */
1097 
1098 		res = ops->so_ull(test->st_val);
1099 		if (res != comp) {
1100 			warnx("TEST FAILED: %s (0x%" PRIx64 ") 64-bit (ulong "
1101 			    "long) returned 0x%x, expected 0x%" PRIx64,
1102 			    ops->so_name, test->st_val, res, comp);
1103 			ret = false;
1104 		}
1105 	}
1106 
1107 	if (ret) {
1108 		stdbit_print_pass(test->st_types, test->st_val, ops->so_name);
1109 	}
1110 
1111 	return (ret);
1112 }
1113 
1114 /*
1115  * This is used for all the functions that can return unsigned.
1116  */
1117 typedef struct {
1118 	const stdbit_ops_t *sg_ops;
1119 	const stdbit_test_t *sg_tests;
1120 	size_t sg_ntests;
1121 } stdbit_std_group_t;
1122 
1123 static const stdbit_std_group_t stdbit_groups[] = {
1124 	{ &stdbit_clz_ops, stdbit_clz_tests, ARRAY_SIZE(stdbit_clz_tests) },
1125 	{ &stdbit_clo_ops, stdbit_clo_tests, ARRAY_SIZE(stdbit_clo_tests) },
1126 	{ &stdbit_ctz_ops, stdbit_ctz_tests, ARRAY_SIZE(stdbit_ctz_tests) },
1127 	{ &stdbit_cto_ops, stdbit_cto_tests, ARRAY_SIZE(stdbit_cto_tests) },
1128 	{ &stdbit_flz_ops, stdbit_flz_tests, ARRAY_SIZE(stdbit_flz_tests) },
1129 	{ &stdbit_flo_ops, stdbit_flo_tests, ARRAY_SIZE(stdbit_flo_tests) },
1130 	{ &stdbit_ftz_ops, stdbit_ftz_tests, ARRAY_SIZE(stdbit_ftz_tests) },
1131 	{ &stdbit_fto_ops, stdbit_fto_tests, ARRAY_SIZE(stdbit_fto_tests) },
1132 	{ &stdbit_cz_ops, stdbit_cz_tests, ARRAY_SIZE(stdbit_cz_tests) },
1133 	{ &stdbit_co_ops, stdbit_co_tests, ARRAY_SIZE(stdbit_co_tests) },
1134 	{ &stdbit_bw_ops, stdbit_bw_tests, ARRAY_SIZE(stdbit_bw_tests) },
1135 };
1136 
1137 /*
1138  * Tests for is a single bit set. These should be the same regardless of integer
1139  * size.
1140  */
1141 static const stdbit_test_t stdbit_1b_tests[] = { {
1142 	.st_types = STDBIT_TEST_ALL,
1143 	.st_val = 0,
1144 	.st_res = false
1145 }, {
1146 	.st_types = STDBIT_TEST_ALL,
1147 	.st_val = UINT8_MAX,
1148 	.st_res = false
1149 }, {
1150 	.st_types = STDBIT_TEST_ALL,
1151 	.st_val = 0x40,
1152 	.st_res = true
1153 }, {
1154 	.st_types = STDBIT_TEST_ALL,
1155 	.st_val = 0x23,
1156 	.st_res = false
1157 }, {
1158 	.st_types = STDBIT_TEST_ALL,
1159 	.st_val = 0x81,
1160 	.st_res = false
1161 }, {
1162 	.st_types = STDBIT_TEST_ALL,
1163 	.st_val = 0x08,
1164 	.st_res = true
1165 }, {
1166 	.st_types = STDBIT_TEST_16P,
1167 	.st_val = UINT16_MAX,
1168 	.st_res = false
1169 }, {
1170 	.st_types = STDBIT_TEST_16P,
1171 	.st_val = 0x0100,
1172 	.st_res = true
1173 }, {
1174 	.st_types = STDBIT_TEST_16P,
1175 	.st_val = 0x7777,
1176 	.st_res = false
1177 }, {
1178 	.st_types = STDBIT_TEST_16P,
1179 	.st_val = 0x8000,
1180 	.st_res = true
1181 }, {
1182 	.st_types = STDBIT_TEST_16P,
1183 	.st_val = 0x0400,
1184 	.st_res = true
1185 }, {
1186 	.st_types = STDBIT_TEST_16P,
1187 	.st_val = 0x0020,
1188 	.st_res = true
1189 }, {
1190 	.st_types = STDBIT_TEST_16P,
1191 	.st_val = 0x0001,
1192 	.st_res = true
1193 }, {
1194 	.st_types = STDBIT_TEST_32P,
1195 	.st_val = UINT32_MAX,
1196 	.st_res = false
1197 }, {
1198 	.st_types = STDBIT_TEST_32P,
1199 	.st_val = 0x00200000,
1200 	.st_res = true
1201 }, {
1202 	.st_types = STDBIT_TEST_32P,
1203 	.st_val = 0xbaddcafe,
1204 	.st_res = false
1205 }, {
1206 	.st_types = STDBIT_TEST_32P,
1207 	.st_val = 0x80000000,
1208 	.st_res = true
1209 }, {
1210 	.st_types = STDBIT_TEST_64P,
1211 	.st_val = UINT64_MAX,
1212 	.st_res = false
1213 }, {
1214 	.st_types = STDBIT_TEST_64P,
1215 	.st_val = 0x8000000000000000,
1216 	.st_res = true
1217 }, {
1218 	.st_types = STDBIT_TEST_64P,
1219 	.st_val = 0x0010000000000000,
1220 	.st_res = true
1221 } };
1222 
1223 /*
1224  * The single bit set tests require a slightly different runner because they
1225  * return a boolean.
1226  */
1227 static bool
stdbit_1b_test_one(const stdbit_test_t * test)1228 stdbit_1b_test_one(const stdbit_test_t *test)
1229 {
1230 	bool ret = true, comp;
1231 
1232 	VERIFY(test->st_res == 0 || test->st_res == 1);
1233 	comp = (bool)test->st_res;
1234 
1235 	VERIFY3U(test->st_types, !=, 0);
1236 	if ((test->st_types & STDBIT_TEST_U8) != 0) {
1237 		bool res = stdc_has_single_bit_uc(test->st_val);
1238 		if (res != comp) {
1239 			warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 8-bit "
1240 			    "(uchar) returned %s, expected %s", test->st_val,
1241 			    res ? "true" : "false", comp ? "true" : "false");
1242 			ret = false;
1243 		}
1244 	}
1245 
1246 	if ((test->st_types & STDBIT_TEST_U16) != 0) {
1247 		bool res = stdc_has_single_bit_us(test->st_val);
1248 		if (res != comp) {
1249 			warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 16-bit "
1250 			    "(ushort) returned %s, expected %s", test->st_val,
1251 			    res ? "true" : "false", comp ? "true" : "false");
1252 			ret = false;
1253 		}
1254 	}
1255 
1256 	if ((test->st_types & STDBIT_TEST_U32) != 0) {
1257 		bool res = stdc_has_single_bit_ui(test->st_val);
1258 		if (res != comp) {
1259 			warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 32-bit "
1260 			    "(uint) returned %s, expected %s", test->st_val,
1261 			    res ? "true" : "false", comp ? "true" : "false");
1262 			ret = false;
1263 		}
1264 
1265 #ifdef	_LP32
1266 		res = stdc_has_single_bit_ul(test->st_val);
1267 		if (res != comp) {
1268 			warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 32-bit "
1269 			    "(ulong) returned %s, expected %s", test->st_val,
1270 			    res ? "true" : "false", comp ? "true" : "false");
1271 			ret = false;
1272 		}
1273 #endif	/* _LP32 */
1274 	}
1275 
1276 	if ((test->st_types & STDBIT_TEST_U64) != 0) {
1277 		bool res;
1278 #ifdef	_LP64
1279 		res = stdc_has_single_bit_ul(test->st_val);
1280 		if (res != comp) {
1281 			warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 64-bit "
1282 			    "(ulong) returned %s, expected %s", test->st_val,
1283 			    res ? "true" : "false", comp ? "true" : "false");
1284 			ret = false;
1285 		}
1286 #endif	/* _LP64 */
1287 
1288 		res = stdc_has_single_bit_ull(test->st_val);
1289 		if (res != comp) {
1290 			warnx("TEST FAILED: Single-bit (0x%" PRIx64 ") 64-bit "
1291 			    "(ulong long) returned %s, expected %s",
1292 			    test->st_val, res ? "true" : "false",
1293 			    comp ? "true" : "false");
1294 			ret = false;
1295 		}
1296 	}
1297 
1298 	if (ret) {
1299 		stdbit_print_pass(test->st_types, test->st_val, "Single-bit");
1300 	}
1301 
1302 	return (ret);
1303 }
1304 
1305 /*
1306  * We use a different test structure for the floor and ceiling tests and check
1307  * both at each stop.
1308  */
1309 typedef struct {
1310 	stdbit_test_type_t sfc_types;
1311 	uint64_t sfc_val;
1312 	uint64_t sfc_floor;
1313 	uint64_t sfc_ceil;
1314 } stdbit_fc_test_t;
1315 
1316 /*
1317  * Bit floor and ceiling tests. Note, a bit ceiling test can fail and return 0
1318  * if the value would overlap the type it's in. In those cases we don't use all
1319  * tests. This happens when the most significant bit in a given integer is set.
1320  * It will work at the next size up. All others should always pass all tests.
1321  */
1322 static const stdbit_fc_test_t stdbit_fc_tests[] = { {
1323 	.sfc_types = STDBIT_TEST_ALL,
1324 	.sfc_val = 0,
1325 	.sfc_floor = 0,
1326 	.sfc_ceil = 1
1327 }, {
1328 	.sfc_types = STDBIT_TEST_U8,
1329 	.sfc_val = UINT8_MAX,
1330 	.sfc_floor = 1ULL << 7,
1331 	.sfc_ceil = 0
1332 }, {
1333 	.sfc_types = STDBIT_TEST_ALL,
1334 	.sfc_val = 0x23,
1335 	.sfc_floor = 1ULL << 5,
1336 	.sfc_ceil = 1ULL << 6
1337 }, {
1338 	.sfc_types = STDBIT_TEST_ALL,
1339 	.sfc_val = 0x06,
1340 	.sfc_floor = 1ULL << 2,
1341 	.sfc_ceil = 1ULL << 3
1342 }, {
1343 	.sfc_types = STDBIT_TEST_ALL,
1344 	.sfc_val = 0x18,
1345 	.sfc_floor = 1ULL << 4,
1346 	.sfc_ceil = 1ULL << 5
1347 }, {
1348 	.sfc_types = STDBIT_TEST_U8,
1349 	.sfc_val = 0x81,
1350 	.sfc_floor = 1ULL << 7,
1351 	.sfc_ceil = 0
1352 }, {
1353 	.sfc_types = STDBIT_TEST_16P,
1354 	.sfc_val = UINT8_MAX,
1355 	.sfc_floor = 1ULL << 7,
1356 	.sfc_ceil = 1ULL << 8
1357 }, {
1358 	.sfc_types = STDBIT_TEST_16P,
1359 	.sfc_val = 0x0ff7,
1360 	.sfc_floor = 1ULL << 11,
1361 	.sfc_ceil = 1ULL << 12
1362 }, {
1363 	.sfc_types = STDBIT_TEST_16P,
1364 	.sfc_val = 0x20a4,
1365 	.sfc_floor = 1ULL << 13,
1366 	.sfc_ceil = 1ULL << 14
1367 }, {
1368 	.sfc_types = STDBIT_TEST_U16,
1369 	.sfc_val = 0x8ab1,
1370 	.sfc_floor = 1ULL << 15,
1371 	.sfc_ceil = 0
1372 }, {
1373 	.sfc_types = STDBIT_TEST_U16,
1374 	.sfc_val = UINT16_MAX,
1375 	.sfc_floor = 1ULL << 15,
1376 	.sfc_ceil = 0
1377 }, {
1378 	.sfc_types = STDBIT_TEST_32P,
1379 	.sfc_val = UINT16_MAX,
1380 	.sfc_floor = 1ULL << 15,
1381 	.sfc_ceil = 1ULL << 16
1382 }, {
1383 	.sfc_types = STDBIT_TEST_32P,
1384 	.sfc_val = 0x000271ab,
1385 	.sfc_floor = 1ULL << 17,
1386 	.sfc_ceil = 1ULL << 18
1387 }, {
1388 	.sfc_types = STDBIT_TEST_32P,
1389 	.sfc_val = 0x01000009,
1390 	.sfc_floor = 1ULL << 24,
1391 	.sfc_ceil = 1ULL << 25
1392 }, {
1393 	.sfc_types = STDBIT_TEST_32P,
1394 	.sfc_val = 0x02000000,
1395 	.sfc_floor = 1ULL << 25,
1396 	.sfc_ceil = 1ULL << 25
1397 }, {
1398 	.sfc_types = STDBIT_TEST_32P,
1399 	.sfc_val = 0x1cabf917,
1400 	.sfc_floor = 1ULL << 28,
1401 	.sfc_ceil = 1ULL << 29
1402 }, {
1403 	.sfc_types = STDBIT_TEST_U32,
1404 	.sfc_val = 0x800a9b03,
1405 	.sfc_floor = 1ULL << 31,
1406 	.sfc_ceil = 0
1407 }, {
1408 	.sfc_types = STDBIT_TEST_U32,
1409 	.sfc_val = UINT32_MAX,
1410 	.sfc_floor = 1ULL << 31,
1411 	.sfc_ceil = 0
1412 }, {
1413 	.sfc_types = STDBIT_TEST_64P,
1414 	.sfc_val = UINT32_MAX,
1415 	.sfc_floor = 1ULL << 31,
1416 	.sfc_ceil = 1ULL << 32
1417 }, {
1418 	.sfc_types = STDBIT_TEST_U64,
1419 	.sfc_val = 0x0089a23b1389ba87,
1420 	.sfc_floor = 1ULL << 55,
1421 	.sfc_ceil = 1ULL << 56
1422 }, {
1423 	.sfc_types = STDBIT_TEST_U64,
1424 	.sfc_val = 0x499aff6eb12e7777,
1425 	.sfc_floor = 1ULL << 62,
1426 	.sfc_ceil = 1ULL << 63
1427 }, {
1428 	.sfc_types = STDBIT_TEST_U64,
1429 	.sfc_val = 0xc00123481980ab87,
1430 	.sfc_floor = 1ULL << 63,
1431 	.sfc_ceil = 0
1432 }, {
1433 	.sfc_types = STDBIT_TEST_U64,
1434 	.sfc_val = UINT64_MAX,
1435 	.sfc_floor = 1ULL << 63,
1436 	.sfc_ceil = 0
1437 } };
1438 
1439 static bool
stdbit_fc_test_one(const stdbit_fc_test_t * test)1440 stdbit_fc_test_one(const stdbit_fc_test_t *test)
1441 {
1442 	bool ret = true;
1443 
1444 	VERIFY3U(test->sfc_types, !=, 0);
1445 	if ((test->sfc_types & STDBIT_TEST_U8) != 0) {
1446 		uint64_t res = stdc_bit_floor_uc(test->sfc_val);
1447 		if (res != test->sfc_floor) {
1448 			warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 8-bit "
1449 			    "(uchar) returned 0x%" PRIx64 ", expected 0x%"
1450 			    PRIx64, test->sfc_val, res, test->sfc_floor);
1451 			ret = false;
1452 		}
1453 
1454 		res = stdc_bit_ceil_uc(test->sfc_val);
1455 		if (res != test->sfc_ceil) {
1456 			warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 8-bit "
1457 			    "(uchar) returned 0x%" PRIx64 ", expected 0x%"
1458 			    PRIx64, test->sfc_val, res, test->sfc_ceil);
1459 			ret = false;
1460 		}
1461 	}
1462 
1463 	if ((test->sfc_types & STDBIT_TEST_U16) != 0) {
1464 		uint64_t res = stdc_bit_floor_us(test->sfc_val);
1465 		if (res != test->sfc_floor) {
1466 			warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 16-bit "
1467 			    "(ushort) returned 0x%" PRIx64 ", expected 0x%"
1468 			    PRIx64, test->sfc_val, res, test->sfc_floor);
1469 			ret = false;
1470 		}
1471 
1472 		res = stdc_bit_ceil_us(test->sfc_val);
1473 		if (res != test->sfc_ceil) {
1474 			warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 16-bit "
1475 			    "(ushort) returned 0x%" PRIx64 ", expected 0x%"
1476 			    PRIx64, test->sfc_val, res, test->sfc_ceil);
1477 			ret = false;
1478 		}
1479 	}
1480 
1481 	if ((test->sfc_types & STDBIT_TEST_U32) != 0) {
1482 		uint64_t res = stdc_bit_floor_ui(test->sfc_val);
1483 		if (res != test->sfc_floor) {
1484 			warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 32-bit "
1485 			    "(uint) returned 0x%" PRIx64 ", expected 0x%"
1486 			    PRIx64, test->sfc_val, res, test->sfc_floor);
1487 			ret = false;
1488 		}
1489 
1490 		res = stdc_bit_ceil_ui(test->sfc_val);
1491 		if (res != test->sfc_ceil) {
1492 			warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 32-bit "
1493 			    "(uint) returned 0x%" PRIx64 ", expected 0x%"
1494 			    PRIx64, test->sfc_val, res, test->sfc_ceil);
1495 			ret = false;
1496 		}
1497 
1498 #ifdef	_LP32
1499 		res = stdc_bit_floor_ul(test->sfc_val);
1500 		if (res != test->sfc_floor) {
1501 			warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 32-bit "
1502 			    "(ulong) returned 0x%" PRIx64 ", expected 0x%"
1503 			    PRIx64, test->sfc_val, res, test->sfc_floor);
1504 			ret = false;
1505 		}
1506 
1507 		res = stdc_bit_ceil_ul(test->sfc_val);
1508 		if (res != test->sfc_ceil) {
1509 			warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 32-bit "
1510 			    "(ulong) returned 0x%" PRIx64 ", expected 0x%"
1511 			    PRIx64, test->sfc_val, res, test->sfc_ceil);
1512 			ret = false;
1513 		}
1514 #endif	/* _LP32 */
1515 	}
1516 
1517 	if ((test->sfc_types & STDBIT_TEST_U64) != 0) {
1518 		uint64_t res;
1519 
1520 #ifdef	_LP64
1521 		res = stdc_bit_floor_ul(test->sfc_val);
1522 		if (res != test->sfc_floor) {
1523 			warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 64-bit "
1524 			    "(ulong) returned 0x%" PRIx64 ", expected 0x%"
1525 			    PRIx64, test->sfc_val, res, test->sfc_floor);
1526 			ret = false;
1527 		}
1528 
1529 		res = stdc_bit_ceil_ul(test->sfc_val);
1530 		if (res != test->sfc_ceil) {
1531 			warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 64-bit "
1532 			    "(ulong) returned 0x%" PRIx64 ", expected 0x%"
1533 			    PRIx64, test->sfc_val, res, test->sfc_ceil);
1534 			ret = false;
1535 		}
1536 #endif	/* _LP64 */
1537 
1538 		res = stdc_bit_floor_ull(test->sfc_val);
1539 		if (res != test->sfc_floor) {
1540 			warnx("TEST FAILED: Bit Floor (0x%" PRIx64 ") 64-bit "
1541 			    "(ulong long) returned 0x%" PRIx64 ", expected 0x%"
1542 			    PRIx64, test->sfc_val, res, test->sfc_floor);
1543 			ret = false;
1544 		}
1545 
1546 		res = stdc_bit_ceil_ull(test->sfc_val);
1547 		if (res != test->sfc_ceil) {
1548 			warnx("TEST FAILED: Bit Ceiling (0x%" PRIx64 ") 64-bit "
1549 			    "(ulong long) returned 0x%" PRIx64 ", expected 0x%"
1550 			    PRIx64, test->sfc_val, res, test->sfc_ceil);
1551 			ret = false;
1552 		}
1553 	}
1554 
1555 	if (ret) {
1556 		stdbit_print_pass(test->sfc_types, test->sfc_val,
1557 		    "Bit Floor/Ceiling");
1558 	}
1559 
1560 	return (ret);
1561 
1562 }
1563 
1564 int
main(void)1565 main(void)
1566 {
1567 	int ret = EXIT_SUCCESS;
1568 
1569 	for (size_t i = 0; i < ARRAY_SIZE(stdbit_groups); i++) {
1570 		for (size_t t = 0; t < stdbit_groups[i].sg_ntests; t++) {
1571 			if (!stdbit_test_one(&stdbit_groups[i].sg_tests[t],
1572 			    stdbit_groups[i].sg_ops)) {
1573 				ret = EXIT_FAILURE;
1574 			}
1575 		}
1576 	}
1577 
1578 	for (size_t i = 0; i < ARRAY_SIZE(stdbit_1b_tests); i++) {
1579 		if (!stdbit_1b_test_one(&stdbit_1b_tests[i])) {
1580 			ret = EXIT_FAILURE;
1581 		}
1582 	}
1583 
1584 	for (size_t i = 0; i < ARRAY_SIZE(stdbit_fc_tests); i++) {
1585 		if (!stdbit_fc_test_one(&stdbit_fc_tests[i])) {
1586 			ret = EXIT_FAILURE;
1587 		}
1588 	}
1589 
1590 	if (ret == EXIT_SUCCESS) {
1591 		(void) printf("All tests passed successfully\n");
1592 	}
1593 
1594 	return (ret);
1595 }
1596