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 * This provides a standard implementation for the C23 stdbit.h non-generic 18 * functions suitable for both libc and the kernel. These are implemented 19 * generally leveraging compiler builtins which should not use the FPU. 20 * 21 * It's worth remembering that the 'long' type varies in our two environments: 22 * ILP32 and LP64. As such, that's why we generally calculate type bit widths by 23 * using the sizeof (type) * CHAR_BITS. 24 */ 25 26 #include <sys/stdbit.h> 27 #ifndef _KERNEL 28 #include <limits.h> 29 #else 30 #include <sys/types.h> 31 #endif 32 33 /* 34 * Count Leading Zeros functions. These leverage a builtin which is undefined at 35 * zero. The builtin will promote everything to an unsigned int, therefore we 36 * need to make sure to subtract resulting values there to make sure we're not 37 * counting sign extension bits. 38 */ 39 unsigned int 40 stdc_leading_zeros_uc(unsigned char uc) 41 { 42 if (uc == 0) { 43 return (CHAR_BIT * sizeof (unsigned char)); 44 } 45 46 return (__builtin_clz(uc) - 47 (sizeof (unsigned int) - sizeof (unsigned char)) * CHAR_BIT); 48 } 49 50 unsigned int 51 stdc_leading_zeros_us(unsigned short us) 52 { 53 if (us == 0) { 54 return (CHAR_BIT * sizeof (unsigned short)); 55 } 56 57 return (__builtin_clz(us) - 58 (sizeof (unsigned int) - sizeof (unsigned short)) * CHAR_BIT); 59 } 60 61 unsigned int 62 stdc_leading_zeros_ui(unsigned int ui) 63 { 64 if (ui == 0) { 65 return (CHAR_BIT * sizeof (unsigned int)); 66 } 67 68 return (__builtin_clz(ui)); 69 } 70 71 unsigned int 72 stdc_leading_zeros_ul(unsigned long ul) 73 { 74 if (ul == 0) { 75 return (CHAR_BIT * sizeof (unsigned long)); 76 } 77 78 return (__builtin_clzl(ul)); 79 } 80 81 unsigned int 82 stdc_leading_zeros_ull(unsigned long long ull) 83 { 84 if (ull == 0) { 85 return (CHAR_BIT * sizeof (unsigned long long)); 86 } 87 88 return (__builtin_clzll(ull)); 89 } 90 91 /* 92 * Count Leading Ones functions. We simply invert these functions and then treat 93 * it as a leading zeros problem. 94 */ 95 unsigned int 96 stdc_leading_ones_uc(unsigned char uc) 97 { 98 return (stdc_leading_zeros_uc(~uc)); 99 } 100 101 unsigned int 102 stdc_leading_ones_us(unsigned short us) 103 { 104 return (stdc_leading_zeros_us(~us)); 105 } 106 107 unsigned int 108 stdc_leading_ones_ui(unsigned int ui) 109 { 110 return (stdc_leading_zeros_ui(~ui)); 111 } 112 113 unsigned int 114 stdc_leading_ones_ul(unsigned long ul) 115 { 116 return (stdc_leading_zeros_ul(~ul)); 117 } 118 119 unsigned int 120 stdc_leading_ones_ull(unsigned long long ull) 121 { 122 return (stdc_leading_zeros_ull(~ull)); 123 } 124 125 /* 126 * Count Trailing Zeros functions. These leverage a builtin check which is 127 * undefined at zero. While the builtin promotes smaller values to an unsigned 128 * int, we don't need to adjust the value like with count leading zeros. 129 */ 130 unsigned int 131 stdc_trailing_zeros_uc(unsigned char uc) 132 { 133 if (uc == 0) { 134 return (CHAR_BIT * sizeof (unsigned char)); 135 } 136 137 return (__builtin_ctz(uc)); 138 } 139 140 unsigned int 141 stdc_trailing_zeros_us(unsigned short us) 142 { 143 if (us == 0) { 144 return (CHAR_BIT * sizeof (unsigned short)); 145 } 146 147 return (__builtin_ctz(us)); 148 } 149 150 unsigned int 151 stdc_trailing_zeros_ui(unsigned int ui) 152 { 153 if (ui == 0) { 154 return (CHAR_BIT * sizeof (unsigned int)); 155 } 156 157 return (__builtin_ctz(ui)); 158 } 159 160 unsigned int 161 stdc_trailing_zeros_ul(unsigned long ul) 162 { 163 if (ul == 0) { 164 return (CHAR_BIT * sizeof (unsigned long)); 165 } 166 167 return (__builtin_ctzl(ul)); 168 } 169 170 unsigned int 171 stdc_trailing_zeros_ull(unsigned long long ull) 172 { 173 if (ull == 0) { 174 return (CHAR_BIT * sizeof (unsigned long long)); 175 } 176 177 return (__builtin_ctzll(ull)); 178 } 179 180 /* 181 * Count Trailing Ones functions. We treat these as just the inverse of the 182 * leading zeros problem. 183 */ 184 unsigned int 185 stdc_trailing_ones_uc(unsigned char uc) 186 { 187 return (stdc_trailing_zeros_uc(~uc)); 188 } 189 190 unsigned int 191 stdc_trailing_ones_us(unsigned short us) 192 { 193 return (stdc_trailing_zeros_us(~us)); 194 } 195 196 unsigned int 197 stdc_trailing_ones_ui(unsigned int ui) 198 { 199 return (stdc_trailing_zeros_ui(~ui)); 200 } 201 202 unsigned int 203 stdc_trailing_ones_ul(unsigned long ul) 204 { 205 return (stdc_trailing_zeros_ul(~ul)); 206 } 207 208 unsigned int 209 stdc_trailing_ones_ull(unsigned long long ull) 210 { 211 return (stdc_trailing_zeros_ull(~ull)); 212 } 213 214 /* 215 * First Leading Zero functions. We cannot use an inversed find first set here 216 * because the builtin operates on signed integers. As this is looking for the 217 * least significant zero, a different way to phrase this is how many leading 218 * ones exist. That indicates the first zero index is that plus one as long as 219 * we're not at the maximum unsigned integer value for the range, which we need 220 * to special case as zero. 221 */ 222 unsigned int 223 stdc_first_leading_zero_uc(unsigned char uc) 224 { 225 if (uc == UCHAR_MAX) { 226 return (0); 227 } 228 229 return (stdc_leading_ones_uc(uc) + 1); 230 } 231 232 unsigned int 233 stdc_first_leading_zero_us(unsigned short us) 234 { 235 if (us == USHRT_MAX) { 236 return (0); 237 } 238 239 return (stdc_leading_ones_us(us) + 1); 240 } 241 242 unsigned int 243 stdc_first_leading_zero_ui(unsigned int ui) 244 { 245 if (ui == UINT_MAX) { 246 return (0); 247 } 248 249 return (stdc_leading_ones_ui(ui) + 1); 250 } 251 252 unsigned int 253 stdc_first_leading_zero_ul(unsigned long ul) 254 { 255 if (ul == ULONG_MAX) { 256 return (0); 257 } 258 259 return (stdc_leading_ones_ul(ul) + 1); 260 } 261 262 unsigned int 263 stdc_first_leading_zero_ull(unsigned long long ull) 264 { 265 if (ull == ULLONG_MAX) { 266 return (0); 267 } 268 269 return (stdc_leading_ones_ull(ull) + 1); 270 } 271 272 /* 273 * First Leading One functions. This is looking for the most significant one. 274 * Like with finding the most significant zero, this can be phrased as counting 275 * the number of leading zeroes and then adding one to get the index. Here we 276 * need to special case zero rather than the maximum integer. 277 */ 278 unsigned int 279 stdc_first_leading_one_uc(unsigned char uc) 280 { 281 if (uc == 0) { 282 return (0); 283 } 284 285 return (stdc_leading_zeros_uc(uc) + 1); 286 } 287 288 unsigned int 289 stdc_first_leading_one_us(unsigned short us) 290 { 291 if (us == 0) { 292 return (0); 293 } 294 295 return (stdc_leading_zeros_us(us) + 1); 296 } 297 298 unsigned int 299 stdc_first_leading_one_ui(unsigned int ui) 300 { 301 if (ui == 0) { 302 return (0); 303 } 304 305 return (stdc_leading_zeros_ui(ui) + 1); 306 } 307 308 unsigned int 309 stdc_first_leading_one_ul(unsigned long ul) 310 { 311 if (ul == 0) { 312 return (0); 313 } 314 315 return (stdc_leading_zeros_ul(ul) + 1); 316 } 317 318 unsigned int 319 stdc_first_leading_one_ull(unsigned long long ull) 320 { 321 if (ull == 0) { 322 return (0); 323 } 324 325 return (stdc_leading_zeros_ull(ull) + 1); 326 } 327 328 /* 329 * First Trailing Zero functions. These look for the least-significant zero. We 330 * can do this in the same way we found the most-significant zero: count 331 * trailing ones as that value + 1 is where the first trailing zero is. Again, 332 * we need to avoid the maximum integer in each class. 333 */ 334 unsigned int 335 stdc_first_trailing_zero_uc(unsigned char uc) 336 { 337 if (uc == UCHAR_MAX) { 338 return (0); 339 } 340 341 return (stdc_trailing_ones_uc(uc) + 1); 342 } 343 344 unsigned int 345 stdc_first_trailing_zero_us(unsigned short us) 346 { 347 if (us == USHRT_MAX) { 348 return (0); 349 } 350 351 return (stdc_trailing_ones_us(us) + 1); 352 } 353 354 unsigned int 355 stdc_first_trailing_zero_ui(unsigned int ui) 356 { 357 if (ui == UINT_MAX) { 358 return (0); 359 } 360 361 return (stdc_trailing_ones_ui(ui) + 1); 362 } 363 364 unsigned int 365 stdc_first_trailing_zero_ul(unsigned long ul) 366 { 367 if (ul == ULONG_MAX) { 368 return (0); 369 } 370 371 return (stdc_trailing_ones_ul(ul) + 1); 372 } 373 374 unsigned int 375 stdc_first_trailing_zero_ull(unsigned long long ull) 376 { 377 if (ull == ULLONG_MAX) { 378 return (0); 379 } 380 381 return (stdc_trailing_ones_ull(ull) + 1); 382 } 383 384 /* 385 * First Trailing One functions. We do the same manipulation that we did with 386 * trailing zeros. Again, here we need to special case zero values as there are 387 * no ones there. 388 */ 389 unsigned int 390 stdc_first_trailing_one_uc(unsigned char uc) 391 { 392 if (uc == 0) { 393 return (0); 394 } 395 396 return (stdc_trailing_zeros_uc(uc) + 1); 397 } 398 399 unsigned int 400 stdc_first_trailing_one_us(unsigned short us) 401 { 402 if (us == 0) { 403 return (0); 404 } 405 406 return (stdc_trailing_zeros_us(us) + 1); 407 } 408 409 unsigned int 410 stdc_first_trailing_one_ui(unsigned int ui) 411 { 412 if (ui == 0) { 413 return (0); 414 } 415 416 return (stdc_trailing_zeros_ui(ui) + 1); 417 } 418 419 unsigned int 420 stdc_first_trailing_one_ul(unsigned long ul) 421 { 422 if (ul == 0) { 423 return (0); 424 } 425 426 return (stdc_trailing_zeros_ul(ul) + 1); 427 } 428 429 unsigned int 430 stdc_first_trailing_one_ull(unsigned long long ull) 431 { 432 if (ull == 0) { 433 return (0); 434 } 435 436 return (stdc_trailing_zeros_ull(ull) + 1); 437 } 438 439 /* 440 * Count Zeros and Count Ones functions. These can just defer to the popcnt 441 * builtin. The Count Ones is simply the return value there. Count zeros is 442 * going to be always our bit size minus the popcnt. We don't have to worry 443 * about integer promotion here because promotion will only add 0s, not 1s for 444 * unsigned values. 445 */ 446 unsigned int 447 stdc_count_zeros_uc(unsigned char uc) 448 { 449 return (CHAR_BIT * sizeof (unsigned char) - __builtin_popcount(uc)); 450 } 451 452 unsigned int 453 stdc_count_zeros_us(unsigned short us) 454 { 455 return (CHAR_BIT * sizeof (unsigned short) - __builtin_popcount(us)); 456 } 457 458 unsigned int 459 stdc_count_zeros_ui(unsigned int ui) 460 { 461 return (CHAR_BIT * sizeof (unsigned int) - __builtin_popcount(ui)); 462 } 463 464 unsigned int 465 stdc_count_zeros_ul(unsigned long ul) 466 { 467 return (CHAR_BIT * sizeof (unsigned long) - __builtin_popcountl(ul)); 468 } 469 470 unsigned int 471 stdc_count_zeros_ull(unsigned long long ull) 472 { 473 return (CHAR_BIT * sizeof (unsigned long long) - 474 __builtin_popcountll(ull)); 475 } 476 477 unsigned int 478 stdc_count_ones_uc(unsigned char uc) 479 { 480 return (__builtin_popcount(uc)); 481 } 482 483 unsigned int 484 stdc_count_ones_us(unsigned short us) 485 { 486 return (__builtin_popcount(us)); 487 } 488 489 unsigned int 490 stdc_count_ones_ui(unsigned int ui) 491 { 492 return (__builtin_popcount(ui)); 493 } 494 495 unsigned int 496 stdc_count_ones_ul(unsigned long ul) 497 { 498 return (__builtin_popcountl(ul)); 499 } 500 501 unsigned int 502 stdc_count_ones_ull(unsigned long long ull) 503 { 504 return (__builtin_popcountll(ull)); 505 } 506 507 /* 508 * Single Bit Check functions. These are supposed to return true if they only 509 * have a single 1 bit set. We simply implement this by calling the 510 * corresponding count ones function and checking its return value. There is 511 * probably a more clever algorithm out there. 512 */ 513 bool 514 stdc_has_single_bit_uc(unsigned char uc) 515 { 516 return (stdc_count_ones_uc(uc) == 1); 517 } 518 519 bool 520 stdc_has_single_bit_us(unsigned short us) 521 { 522 return (stdc_count_ones_us(us) == 1); 523 } 524 525 bool 526 stdc_has_single_bit_ui(unsigned int ui) 527 { 528 return (stdc_count_ones_ui(ui) == 1); 529 } 530 531 bool 532 stdc_has_single_bit_ul(unsigned long ul) 533 { 534 return (stdc_count_ones_ul(ul) == 1); 535 } 536 537 bool 538 stdc_has_single_bit_ull(unsigned long long ull) 539 { 540 return (stdc_count_ones_ull(ull) == 1); 541 } 542 543 /* 544 * Bit Width functions. This is asking us to calculate 1 + floor(log2(val)). 545 * When we are taking the floor of this, then we can simply calculate this as 546 * finding the first leading one. Because the first leading one logic uses the 547 * standard's 'most-significant' index logic, we then have to subtract the 548 * corresponding size. 549 */ 550 unsigned int 551 stdc_bit_width_uc(unsigned char uc) 552 { 553 if (uc == 0) { 554 return (0); 555 } 556 557 return (CHAR_BIT * sizeof (unsigned char) + 1 - 558 stdc_first_leading_one_uc(uc)); 559 } 560 561 unsigned int 562 stdc_bit_width_us(unsigned short us) 563 { 564 if (us == 0) { 565 return (0); 566 } 567 568 return (CHAR_BIT * sizeof (unsigned short) + 1 - 569 stdc_first_leading_one_us(us)); 570 } 571 572 unsigned int 573 stdc_bit_width_ui(unsigned int ui) 574 { 575 if (ui == 0) { 576 return (0); 577 } 578 579 return (CHAR_BIT * sizeof (unsigned int) + 1 - 580 stdc_first_leading_one_ui(ui)); 581 } 582 583 unsigned int 584 stdc_bit_width_ul(unsigned long ul) 585 { 586 if (ul == 0) { 587 return (0); 588 } 589 590 return (CHAR_BIT * sizeof (unsigned long) + 1 - 591 stdc_first_leading_one_ul(ul)); 592 } 593 594 unsigned int 595 stdc_bit_width_ull(unsigned long long ull) 596 { 597 if (ull == 0) { 598 return (0); 599 } 600 601 return (CHAR_BIT * sizeof (unsigned long long) + 1 - 602 stdc_first_leading_one_ull(ull)); 603 } 604 605 /* 606 * Bit Floor functions. These are trying to find the smallest power of two that 607 * is not greater than the value specified. We can use the bit width, subtract 608 * one, and then shift. This is defined by the spec such that a value of 0 609 * returns 0. 610 */ 611 unsigned char 612 stdc_bit_floor_uc(unsigned char uc) 613 { 614 if (uc == 0) { 615 return (0); 616 } 617 618 return (1U << (stdc_bit_width_uc(uc) - 1)); 619 } 620 621 unsigned short 622 stdc_bit_floor_us(unsigned short us) 623 { 624 if (us == 0) { 625 return (0); 626 } 627 628 return (1U << (stdc_bit_width_us(us) - 1)); 629 } 630 631 unsigned int 632 stdc_bit_floor_ui(unsigned int ui) 633 { 634 if (ui == 0) { 635 return (0); 636 } 637 638 return (1U << (stdc_bit_width_ui(ui) - 1)); 639 } 640 641 unsigned long 642 stdc_bit_floor_ul(unsigned long ul) 643 { 644 if (ul == 0) { 645 return (0); 646 } 647 648 return (1UL << (stdc_bit_width_ul(ul) - 1)); 649 } 650 651 unsigned long long 652 stdc_bit_floor_ull(unsigned long long ull) 653 { 654 if (ull == 0) { 655 return (0); 656 } 657 658 return (1ULL << (stdc_bit_width_ull(ull) - 1)); 659 } 660 661 /* 662 * Bit Ceiling functions. These are meant to return the next power of two that 663 * is greater than the value. If the value cannot fit, then it is supposed to 664 * return 0. Whenever we have a value greater than the signed maximum, then 665 * we're going to end up having to return zero. We don't have explicit checks 666 * for the value being representable because we're using shifts which by 667 * definition will shift in zero values and then integer rules will cause the 668 * value to be truncated. 669 * 670 * However, there is a slight challenge with this assumption. It is undefined 671 * behavior to shift a value by more bits than its bit width. For example, the 672 * bit width of the unsigned char 0xf0 is 8. 1 << 8 for an unsigned char is 673 * undefined (while integer promotion rules do come into effect you can see this 674 * at higher values). As a result, there are two ways to deal with this. We can 675 * either make it so we never shift by the maximum value of bits by doing 2 << 676 * (width - 1), or we can use an if statement to explicitly check for these 677 * values. For now, we do the former (reducing the branch predictor's burden), 678 * which also means that instead of checking just for zero, we need to check for 679 * 1 as well so we don't underflow the bit shift quantity! 680 * 681 * When a value is an exact power of two, then it by definition fits, so we 682 * always subtract one from the input value to make sure we end up getting it to 683 * fit. This results in us only needing to special case zero. 684 */ 685 unsigned char 686 stdc_bit_ceil_uc(unsigned char uc) 687 { 688 if (uc <= 1) { 689 return (1); 690 } 691 692 return (2U << (stdc_bit_width_uc(uc - 1) - 1)); 693 } 694 695 unsigned short 696 stdc_bit_ceil_us(unsigned short us) 697 { 698 if (us <= 1) { 699 return (1); 700 } 701 702 return (2U << (stdc_bit_width_us(us - 1) - 1)); 703 } 704 705 unsigned int 706 stdc_bit_ceil_ui(unsigned int ui) 707 { 708 if (ui <= 1) { 709 return (1); 710 } 711 712 return (2U << (stdc_bit_width_ui(ui - 1) - 1)); 713 } 714 715 unsigned long 716 stdc_bit_ceil_ul(unsigned long ul) 717 { 718 if (ul <= 1) { 719 return (1); 720 } 721 722 return (2UL << (stdc_bit_width_ul(ul - 1) - 1)); 723 } 724 725 unsigned long long 726 stdc_bit_ceil_ull(unsigned long long ull) 727 { 728 if (ull <= 1) { 729 return (1); 730 } 731 732 return (2ULL << (stdc_bit_width_ull(ull - 1) - 1)); 733 } 734