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 /* Offset must be greater than zero. */ 12*6296500aSRobert Clausecker static_assert(UCHAR_WIDTH < UINT_WIDTH, 13*6296500aSRobert Clausecker "stdc_leading_zeros_uc needs UCHAR_WIDTH < UINT_WIDTH"); 14*6296500aSRobert Clausecker 15*6296500aSRobert Clausecker unsigned int stdc_leading_zeros_uc(unsigned char x)16*6296500aSRobert Clauseckerstdc_leading_zeros_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) + (1U << (offset - 1)))); 21*6296500aSRobert Clausecker } 22*6296500aSRobert Clausecker 23*6296500aSRobert Clausecker /* Offset must be greater than zero. */ 24*6296500aSRobert Clausecker static_assert(USHRT_WIDTH < UINT_WIDTH, 25*6296500aSRobert Clausecker "stdc_leading_zeros_us needs USHRT_WIDTH < UINT_WIDTH"); 26*6296500aSRobert Clausecker 27*6296500aSRobert Clausecker unsigned int stdc_leading_zeros_us(unsigned short x)28*6296500aSRobert Clauseckerstdc_leading_zeros_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) + (1U << (offset - 1)))); 33*6296500aSRobert Clausecker } 34*6296500aSRobert Clausecker 35*6296500aSRobert Clausecker unsigned int stdc_leading_zeros_ui(unsigned int x)36*6296500aSRobert Clauseckerstdc_leading_zeros_ui(unsigned int x) 37*6296500aSRobert Clausecker { 38*6296500aSRobert Clausecker if (x == 0) 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_zeros_ul(unsigned long x)45*6296500aSRobert Clauseckerstdc_leading_zeros_ul(unsigned long x) 46*6296500aSRobert Clausecker { 47*6296500aSRobert Clausecker if (x == 0) 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_zeros_ull(unsigned long long x)54*6296500aSRobert Clauseckerstdc_leading_zeros_ull(unsigned long long x) 55*6296500aSRobert Clausecker { 56*6296500aSRobert Clausecker if (x == 0) 57*6296500aSRobert Clausecker return (ULLONG_WIDTH); 58*6296500aSRobert Clausecker 59*6296500aSRobert Clausecker return (__builtin_clzll(x)); 60*6296500aSRobert Clausecker } 61