xref: /illumos-gate/usr/src/common/bitext/stdbit.c (revision 2e07277863d69344215bd0c72e171d0c854dbe56)
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