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