xref: /freebsd/lib/libc/stdbit/stdc_bit_ceil.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 <assert.h>
8 #include <limits.h>
9 #include <stdbit.h>
10 
11 /* Ensure we don't shift 1U out of range. */
12 static_assert(UCHAR_WIDTH < UINT_WIDTH,
13     "stdc_bit_ceil_uc needs UCHAR_WIDTH < UINT_WIDTH");
14 
15 unsigned char
stdc_bit_ceil_uc(unsigned char x)16 stdc_bit_ceil_uc(unsigned char x)
17 {
18 	if (x <= 1)
19 		return (1);
20 
21 	return (1U << (UINT_WIDTH - __builtin_clz(x - 1)));
22 }
23 
24 /* Ensure we don't shift 1U out of range. */
25 static_assert(USHRT_WIDTH < UINT_WIDTH,
26     "stdc_bit_ceil_us needs USHRT_WIDTH < UINT_WIDTH");
27 
28 unsigned short
stdc_bit_ceil_us(unsigned short x)29 stdc_bit_ceil_us(unsigned short x)
30 {
31 	if (x <= 1)
32 		return (1);
33 
34 	return (1U << (UINT_WIDTH - __builtin_clz(x - 1)));
35 }
36 
37 unsigned int
stdc_bit_ceil_ui(unsigned int x)38 stdc_bit_ceil_ui(unsigned int x)
39 {
40 	if (x <= 1)
41 		return (1);
42 
43 	if (x > UINT_MAX/2 + 1)
44 		return (0);
45 
46 	return (1U << (UINT_WIDTH - __builtin_clz(x - 1)));
47 }
48 
49 unsigned long
stdc_bit_ceil_ul(unsigned long x)50 stdc_bit_ceil_ul(unsigned long x)
51 {
52 	if (x <= 1)
53 		return (1);
54 
55 	if (x > ULONG_MAX/2 + 1)
56 		return (0);
57 
58 	return (1UL << (ULONG_WIDTH - __builtin_clzl(x - 1)));
59 }
60 
61 unsigned long long
stdc_bit_ceil_ull(unsigned long long x)62 stdc_bit_ceil_ull(unsigned long long x)
63 {
64 	if (x <= 1)
65 		return (1);
66 
67 	if (x > ULLONG_MAX/2 + 1)
68 		return (0);
69 
70 	return (1ULL << (ULLONG_WIDTH - __builtin_clzll(x - 1)));
71 }
72