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