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 /* Offset must be greater than zero. */ 12 static_assert(UCHAR_WIDTH < UINT_WIDTH, 13 "stdc_leading_zeros_uc needs UCHAR_WIDTH < UINT_WIDTH"); 14 15 unsigned int stdc_leading_zeros_uc(unsigned char x)16stdc_leading_zeros_uc(unsigned char x) 17 { 18 const int offset = UINT_WIDTH - UCHAR_WIDTH; 19 20 return (__builtin_clz((x << offset) + (1U << (offset - 1)))); 21 } 22 23 /* Offset must be greater than zero. */ 24 static_assert(USHRT_WIDTH < UINT_WIDTH, 25 "stdc_leading_zeros_us needs USHRT_WIDTH < UINT_WIDTH"); 26 27 unsigned int stdc_leading_zeros_us(unsigned short x)28stdc_leading_zeros_us(unsigned short x) 29 { 30 const int offset = UINT_WIDTH - USHRT_WIDTH; 31 32 return (__builtin_clz((x << offset) + (1U << (offset - 1)))); 33 } 34 35 unsigned int stdc_leading_zeros_ui(unsigned int x)36stdc_leading_zeros_ui(unsigned int x) 37 { 38 if (x == 0) 39 return (UINT_WIDTH); 40 41 return (__builtin_clz(x)); 42 } 43 44 unsigned int stdc_leading_zeros_ul(unsigned long x)45stdc_leading_zeros_ul(unsigned long x) 46 { 47 if (x == 0) 48 return (ULONG_WIDTH); 49 50 return (__builtin_clzl(x)); 51 } 52 53 unsigned int stdc_leading_zeros_ull(unsigned long long x)54stdc_leading_zeros_ull(unsigned long long x) 55 { 56 if (x == 0) 57 return (ULLONG_WIDTH); 58 59 return (__builtin_clzll(x)); 60 } 61