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 /* Avoid triggering undefined behavior if x == 0. */ 12*6296500aSRobert Clausecker static_assert(UCHAR_WIDTH < UINT_WIDTH, 13*6296500aSRobert Clausecker "stdc_leading_ones_uc needs UCHAR_WIDTH < UINT_WIDTH"); 14*6296500aSRobert Clausecker 15*6296500aSRobert Clausecker unsigned int stdc_leading_ones_uc(unsigned char x)16*6296500aSRobert Clauseckerstdc_leading_ones_uc(unsigned char x) 17*6296500aSRobert Clausecker { 18*6296500aSRobert Clausecker const int offset = UINT_WIDTH - UCHAR_WIDTH; 19*6296500aSRobert Clausecker 20*6296500aSRobert Clausecker return (__builtin_clz(~(x << offset))); 21*6296500aSRobert Clausecker } 22*6296500aSRobert Clausecker 23*6296500aSRobert Clausecker /* Avoid triggering undefined behavior if x == 0. */ 24*6296500aSRobert Clausecker static_assert(USHRT_WIDTH < UINT_WIDTH, 25*6296500aSRobert Clausecker "stdc_leading_ones_us needs USHRT_WIDTH < UINT_WIDTH"); 26*6296500aSRobert Clausecker 27*6296500aSRobert Clausecker unsigned int stdc_leading_ones_us(unsigned short x)28*6296500aSRobert Clauseckerstdc_leading_ones_us(unsigned short x) 29*6296500aSRobert Clausecker { 30*6296500aSRobert Clausecker const int offset = UINT_WIDTH - USHRT_WIDTH; 31*6296500aSRobert Clausecker 32*6296500aSRobert Clausecker return (__builtin_clz(~(x << offset))); 33*6296500aSRobert Clausecker } 34*6296500aSRobert Clausecker 35*6296500aSRobert Clausecker unsigned int stdc_leading_ones_ui(unsigned int x)36*6296500aSRobert Clauseckerstdc_leading_ones_ui(unsigned int x) 37*6296500aSRobert Clausecker { 38*6296500aSRobert Clausecker if (x == ~0U) 39*6296500aSRobert Clausecker return (UINT_WIDTH); 40*6296500aSRobert Clausecker 41*6296500aSRobert Clausecker return (__builtin_clz(~x)); 42*6296500aSRobert Clausecker } 43*6296500aSRobert Clausecker 44*6296500aSRobert Clausecker unsigned int stdc_leading_ones_ul(unsigned long x)45*6296500aSRobert Clauseckerstdc_leading_ones_ul(unsigned long x) 46*6296500aSRobert Clausecker { 47*6296500aSRobert Clausecker if (x == ~0UL) 48*6296500aSRobert Clausecker return (ULONG_WIDTH); 49*6296500aSRobert Clausecker 50*6296500aSRobert Clausecker return (__builtin_clzl(~x)); 51*6296500aSRobert Clausecker } 52*6296500aSRobert Clausecker 53*6296500aSRobert Clausecker unsigned int stdc_leading_ones_ull(unsigned long long x)54*6296500aSRobert Clauseckerstdc_leading_ones_ull(unsigned long long x) 55*6296500aSRobert Clausecker { 56*6296500aSRobert Clausecker if (x == ~0ULL) 57*6296500aSRobert Clausecker return (ULLONG_WIDTH); 58*6296500aSRobert Clausecker 59*6296500aSRobert Clausecker return (__builtin_clzll(~x)); 60*6296500aSRobert Clausecker } 61