xref: /freebsd/lib/libc/stdbit/stdc_first_leading_zero.c (revision 6296500a85c8474e3ff3fe2f8e4a9d56dd0acd64)
1*6296500aSRobert Clausecker /*
2*6296500aSRobert Clausecker  * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
3*6296500aSRobert Clausecker  *
4*6296500aSRobert Clausecker  * SPDX-License-Identifier: BSD-2-Clause
5*6296500aSRobert Clausecker  */
6*6296500aSRobert Clausecker 
7*6296500aSRobert Clausecker #include <limits.h>
8*6296500aSRobert Clausecker #include <stdbit.h>
9*6296500aSRobert Clausecker 
10*6296500aSRobert Clausecker unsigned int
stdc_first_leading_zero_uc(unsigned char x)11*6296500aSRobert Clausecker stdc_first_leading_zero_uc(unsigned char x)
12*6296500aSRobert Clausecker {
13*6296500aSRobert Clausecker 	const int offset = UINT_WIDTH - UCHAR_WIDTH;
14*6296500aSRobert Clausecker 
15*6296500aSRobert Clausecker 	if (x == UCHAR_MAX)
16*6296500aSRobert Clausecker 		return (0);
17*6296500aSRobert Clausecker 
18*6296500aSRobert Clausecker 	return (__builtin_clz(~(unsigned int)x << offset) + 1);
19*6296500aSRobert Clausecker }
20*6296500aSRobert Clausecker 
21*6296500aSRobert Clausecker unsigned int
stdc_first_leading_zero_us(unsigned short x)22*6296500aSRobert Clausecker stdc_first_leading_zero_us(unsigned short x)
23*6296500aSRobert Clausecker {
24*6296500aSRobert Clausecker 	const int offset = UINT_WIDTH - USHRT_WIDTH;
25*6296500aSRobert Clausecker 
26*6296500aSRobert Clausecker 	if (x == USHRT_MAX)
27*6296500aSRobert Clausecker 		return (0);
28*6296500aSRobert Clausecker 
29*6296500aSRobert Clausecker 	return (__builtin_clz(~(unsigned int)x << offset) + 1);
30*6296500aSRobert Clausecker }
31*6296500aSRobert Clausecker 
32*6296500aSRobert Clausecker unsigned int
stdc_first_leading_zero_ui(unsigned int x)33*6296500aSRobert Clausecker stdc_first_leading_zero_ui(unsigned int x)
34*6296500aSRobert Clausecker {
35*6296500aSRobert Clausecker 	if (x == ~0U)
36*6296500aSRobert Clausecker 		return (0);
37*6296500aSRobert Clausecker 
38*6296500aSRobert Clausecker 	return (__builtin_clz(~x) + 1);
39*6296500aSRobert Clausecker }
40*6296500aSRobert Clausecker 
41*6296500aSRobert Clausecker unsigned int
stdc_first_leading_zero_ul(unsigned long x)42*6296500aSRobert Clausecker stdc_first_leading_zero_ul(unsigned long x)
43*6296500aSRobert Clausecker {
44*6296500aSRobert Clausecker 	if (x == ~0UL)
45*6296500aSRobert Clausecker 		return (0);
46*6296500aSRobert Clausecker 
47*6296500aSRobert Clausecker 	return (__builtin_clzl(~x) + 1);
48*6296500aSRobert Clausecker }
49*6296500aSRobert Clausecker 
50*6296500aSRobert Clausecker unsigned int
stdc_first_leading_zero_ull(unsigned long long x)51*6296500aSRobert Clausecker stdc_first_leading_zero_ull(unsigned long long x)
52*6296500aSRobert Clausecker {
53*6296500aSRobert Clausecker 	if (x == ~0ULL)
54*6296500aSRobert Clausecker 		return (0);
55*6296500aSRobert Clausecker 
56*6296500aSRobert Clausecker 	return (__builtin_clzll(~x) + 1);
57*6296500aSRobert Clausecker }
58