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
stdc_leading_zeros_uc(unsigned char uc)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
stdc_leading_zeros_us(unsigned short us)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
stdc_leading_zeros_ui(unsigned int ui)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
stdc_leading_zeros_ul(unsigned long ul)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
stdc_leading_zeros_ull(unsigned long long ull)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
stdc_leading_ones_uc(unsigned char uc)96 stdc_leading_ones_uc(unsigned char uc)
97 {
98 return (stdc_leading_zeros_uc(~uc));
99 }
100
101 unsigned int
stdc_leading_ones_us(unsigned short us)102 stdc_leading_ones_us(unsigned short us)
103 {
104 return (stdc_leading_zeros_us(~us));
105 }
106
107 unsigned int
stdc_leading_ones_ui(unsigned int ui)108 stdc_leading_ones_ui(unsigned int ui)
109 {
110 return (stdc_leading_zeros_ui(~ui));
111 }
112
113 unsigned int
stdc_leading_ones_ul(unsigned long ul)114 stdc_leading_ones_ul(unsigned long ul)
115 {
116 return (stdc_leading_zeros_ul(~ul));
117 }
118
119 unsigned int
stdc_leading_ones_ull(unsigned long long ull)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
stdc_trailing_zeros_uc(unsigned char uc)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
stdc_trailing_zeros_us(unsigned short us)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
stdc_trailing_zeros_ui(unsigned int ui)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
stdc_trailing_zeros_ul(unsigned long ul)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
stdc_trailing_zeros_ull(unsigned long long ull)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
stdc_trailing_ones_uc(unsigned char uc)185 stdc_trailing_ones_uc(unsigned char uc)
186 {
187 return (stdc_trailing_zeros_uc(~uc));
188 }
189
190 unsigned int
stdc_trailing_ones_us(unsigned short us)191 stdc_trailing_ones_us(unsigned short us)
192 {
193 return (stdc_trailing_zeros_us(~us));
194 }
195
196 unsigned int
stdc_trailing_ones_ui(unsigned int ui)197 stdc_trailing_ones_ui(unsigned int ui)
198 {
199 return (stdc_trailing_zeros_ui(~ui));
200 }
201
202 unsigned int
stdc_trailing_ones_ul(unsigned long ul)203 stdc_trailing_ones_ul(unsigned long ul)
204 {
205 return (stdc_trailing_zeros_ul(~ul));
206 }
207
208 unsigned int
stdc_trailing_ones_ull(unsigned long long ull)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
stdc_first_leading_zero_uc(unsigned char uc)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
stdc_first_leading_zero_us(unsigned short us)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
stdc_first_leading_zero_ui(unsigned int ui)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
stdc_first_leading_zero_ul(unsigned long ul)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
stdc_first_leading_zero_ull(unsigned long long ull)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
stdc_first_leading_one_uc(unsigned char uc)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
stdc_first_leading_one_us(unsigned short us)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
stdc_first_leading_one_ui(unsigned int ui)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
stdc_first_leading_one_ul(unsigned long ul)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
stdc_first_leading_one_ull(unsigned long long ull)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
stdc_first_trailing_zero_uc(unsigned char uc)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
stdc_first_trailing_zero_us(unsigned short us)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
stdc_first_trailing_zero_ui(unsigned int ui)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
stdc_first_trailing_zero_ul(unsigned long ul)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
stdc_first_trailing_zero_ull(unsigned long long ull)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
stdc_first_trailing_one_uc(unsigned char uc)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
stdc_first_trailing_one_us(unsigned short us)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
stdc_first_trailing_one_ui(unsigned int ui)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
stdc_first_trailing_one_ul(unsigned long ul)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
stdc_first_trailing_one_ull(unsigned long long ull)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
stdc_count_zeros_uc(unsigned char uc)447 stdc_count_zeros_uc(unsigned char uc)
448 {
449 return (CHAR_BIT * sizeof (unsigned char) - __builtin_popcount(uc));
450 }
451
452 unsigned int
stdc_count_zeros_us(unsigned short us)453 stdc_count_zeros_us(unsigned short us)
454 {
455 return (CHAR_BIT * sizeof (unsigned short) - __builtin_popcount(us));
456 }
457
458 unsigned int
stdc_count_zeros_ui(unsigned int ui)459 stdc_count_zeros_ui(unsigned int ui)
460 {
461 return (CHAR_BIT * sizeof (unsigned int) - __builtin_popcount(ui));
462 }
463
464 unsigned int
stdc_count_zeros_ul(unsigned long ul)465 stdc_count_zeros_ul(unsigned long ul)
466 {
467 return (CHAR_BIT * sizeof (unsigned long) - __builtin_popcountl(ul));
468 }
469
470 unsigned int
stdc_count_zeros_ull(unsigned long long ull)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
stdc_count_ones_uc(unsigned char uc)478 stdc_count_ones_uc(unsigned char uc)
479 {
480 return (__builtin_popcount(uc));
481 }
482
483 unsigned int
stdc_count_ones_us(unsigned short us)484 stdc_count_ones_us(unsigned short us)
485 {
486 return (__builtin_popcount(us));
487 }
488
489 unsigned int
stdc_count_ones_ui(unsigned int ui)490 stdc_count_ones_ui(unsigned int ui)
491 {
492 return (__builtin_popcount(ui));
493 }
494
495 unsigned int
stdc_count_ones_ul(unsigned long ul)496 stdc_count_ones_ul(unsigned long ul)
497 {
498 return (__builtin_popcountl(ul));
499 }
500
501 unsigned int
stdc_count_ones_ull(unsigned long long ull)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
stdc_has_single_bit_uc(unsigned char uc)514 stdc_has_single_bit_uc(unsigned char uc)
515 {
516 return (stdc_count_ones_uc(uc) == 1);
517 }
518
519 bool
stdc_has_single_bit_us(unsigned short us)520 stdc_has_single_bit_us(unsigned short us)
521 {
522 return (stdc_count_ones_us(us) == 1);
523 }
524
525 bool
stdc_has_single_bit_ui(unsigned int ui)526 stdc_has_single_bit_ui(unsigned int ui)
527 {
528 return (stdc_count_ones_ui(ui) == 1);
529 }
530
531 bool
stdc_has_single_bit_ul(unsigned long ul)532 stdc_has_single_bit_ul(unsigned long ul)
533 {
534 return (stdc_count_ones_ul(ul) == 1);
535 }
536
537 bool
stdc_has_single_bit_ull(unsigned long long ull)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
stdc_bit_width_uc(unsigned char uc)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
stdc_bit_width_us(unsigned short us)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
stdc_bit_width_ui(unsigned int ui)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
stdc_bit_width_ul(unsigned long ul)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
stdc_bit_width_ull(unsigned long long ull)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
stdc_bit_floor_uc(unsigned char uc)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
stdc_bit_floor_us(unsigned short us)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
stdc_bit_floor_ui(unsigned int ui)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
stdc_bit_floor_ul(unsigned long ul)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
stdc_bit_floor_ull(unsigned long long ull)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
stdc_bit_ceil_uc(unsigned char uc)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
stdc_bit_ceil_us(unsigned short us)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
stdc_bit_ceil_ui(unsigned int ui)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
stdc_bit_ceil_ul(unsigned long ul)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
stdc_bit_ceil_ull(unsigned long long ull)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