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(3C) 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 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 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 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 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 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