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