[v0,1/2] newlib/libc: Add C23 stdbit.h from FreeBSD

Message ID 20260313170335.2240233-2-joel@rtems.org
State New
Headers
Series Add C23 stdbit.h functions |

Commit Message

Joel Sherrill March 13, 2026, 5:03 p.m. UTC
  FreeBSD git hash: 80b4129bef8b908eb19fe47853cb6e45e4513d76
---
 newlib/libc/include/stdbit.h                  | 124 ++++++++++++++++++
 newlib/libc/stdbit/stdc_bit_ceil.3            |  81 ++++++++++++
 newlib/libc/stdbit/stdc_bit_ceil.c            |  71 ++++++++++
 newlib/libc/stdbit/stdc_bit_floor.3           |  83 ++++++++++++
 newlib/libc/stdbit/stdc_bit_floor.c           |  53 ++++++++
 newlib/libc/stdbit/stdc_bit_width.3           | 104 +++++++++++++++
 newlib/libc/stdbit/stdc_bit_width.c           |  53 ++++++++
 newlib/libc/stdbit/stdc_count_ones.3          |  85 ++++++++++++
 newlib/libc/stdbit/stdc_count_ones.c          |  38 ++++++
 newlib/libc/stdbit/stdc_count_zeros.3         |  84 ++++++++++++
 newlib/libc/stdbit/stdc_count_zeros.c         |  38 ++++++
 newlib/libc/stdbit/stdc_first_leading_one.3   |  93 +++++++++++++
 newlib/libc/stdbit/stdc_first_leading_one.c   |  57 ++++++++
 newlib/libc/stdbit/stdc_first_leading_zero.3  |  92 +++++++++++++
 newlib/libc/stdbit/stdc_first_leading_zero.c  |  57 ++++++++
 newlib/libc/stdbit/stdc_first_trailing_one.3  | 110 ++++++++++++++++
 newlib/libc/stdbit/stdc_first_trailing_one.c  |  52 ++++++++
 newlib/libc/stdbit/stdc_first_trailing_zero.3 |  93 +++++++++++++
 newlib/libc/stdbit/stdc_first_trailing_zero.c |  53 ++++++++
 newlib/libc/stdbit/stdc_has_single_bit.3      |  98 ++++++++++++++
 newlib/libc/stdbit/stdc_has_single_bit.c      |  38 ++++++
 newlib/libc/stdbit/stdc_leading_ones.3        |  86 ++++++++++++
 newlib/libc/stdbit/stdc_leading_ones.c        |  60 +++++++++
 newlib/libc/stdbit/stdc_leading_zeros.3       |  86 ++++++++++++
 newlib/libc/stdbit/stdc_leading_zeros.c       |  60 +++++++++
 newlib/libc/stdbit/stdc_trailing_ones.3       |  86 ++++++++++++
 newlib/libc/stdbit/stdc_trailing_ones.c       |  56 ++++++++
 newlib/libc/stdbit/stdc_trailing_zeros.3      |  87 ++++++++++++
 newlib/libc/stdbit/stdc_trailing_zeros.c      |  56 ++++++++
 29 files changed, 2134 insertions(+)
 create mode 100644 newlib/libc/include/stdbit.h
 create mode 100644 newlib/libc/stdbit/stdc_bit_ceil.3
 create mode 100644 newlib/libc/stdbit/stdc_bit_ceil.c
 create mode 100644 newlib/libc/stdbit/stdc_bit_floor.3
 create mode 100644 newlib/libc/stdbit/stdc_bit_floor.c
 create mode 100644 newlib/libc/stdbit/stdc_bit_width.3
 create mode 100644 newlib/libc/stdbit/stdc_bit_width.c
 create mode 100644 newlib/libc/stdbit/stdc_count_ones.3
 create mode 100644 newlib/libc/stdbit/stdc_count_ones.c
 create mode 100644 newlib/libc/stdbit/stdc_count_zeros.3
 create mode 100644 newlib/libc/stdbit/stdc_count_zeros.c
 create mode 100644 newlib/libc/stdbit/stdc_first_leading_one.3
 create mode 100644 newlib/libc/stdbit/stdc_first_leading_one.c
 create mode 100644 newlib/libc/stdbit/stdc_first_leading_zero.3
 create mode 100644 newlib/libc/stdbit/stdc_first_leading_zero.c
 create mode 100644 newlib/libc/stdbit/stdc_first_trailing_one.3
 create mode 100644 newlib/libc/stdbit/stdc_first_trailing_one.c
 create mode 100644 newlib/libc/stdbit/stdc_first_trailing_zero.3
 create mode 100644 newlib/libc/stdbit/stdc_first_trailing_zero.c
 create mode 100644 newlib/libc/stdbit/stdc_has_single_bit.3
 create mode 100644 newlib/libc/stdbit/stdc_has_single_bit.c
 create mode 100644 newlib/libc/stdbit/stdc_leading_ones.3
 create mode 100644 newlib/libc/stdbit/stdc_leading_ones.c
 create mode 100644 newlib/libc/stdbit/stdc_leading_zeros.3
 create mode 100644 newlib/libc/stdbit/stdc_leading_zeros.c
 create mode 100644 newlib/libc/stdbit/stdc_trailing_ones.3
 create mode 100644 newlib/libc/stdbit/stdc_trailing_ones.c
 create mode 100644 newlib/libc/stdbit/stdc_trailing_zeros.3
 create mode 100644 newlib/libc/stdbit/stdc_trailing_zeros.c
  

Patch

diff --git a/newlib/libc/include/stdbit.h b/newlib/libc/include/stdbit.h
new file mode 100644
index 000000000..a529676be
--- /dev/null
+++ b/newlib/libc/include/stdbit.h
@@ -0,0 +1,124 @@ 
+/*-
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#ifndef __STDC_VERSION_STDBIT_H__
+#define __STDC_VERSION_STDBIT_H__ 202311L
+
+#include <sys/cdefs.h>
+
+/* byte order */
+#define  __STDC_ENDIAN_LITTLE__ __ORDER_LITTLE_ENDIAN__
+#define  __STDC_ENDIAN_BIG__ __ORDER_BIG_ENDIAN__
+#define  __STDC_ENDIAN_NATIVE__ __BYTE_ORDER__
+
+#define __generic_bitfunc(func, x) (_Generic(x,				\
+	unsigned char: func ## _uc,					\
+	unsigned short: func ## _us,					\
+	unsigned int: func ## _ui,					\
+	unsigned long: func ## _ul,					\
+	unsigned long long: func ## _ull)(x))
+
+__BEGIN_DECLS
+unsigned int stdc_leading_zeros_uc(unsigned char) __pure2;
+unsigned int stdc_leading_zeros_us(unsigned short) __pure2;
+unsigned int stdc_leading_zeros_ui(unsigned int) __pure2;
+unsigned int stdc_leading_zeros_ul(unsigned long) __pure2;
+unsigned int stdc_leading_zeros_ull(unsigned long long) __pure2;
+#define stdc_leading_zeros(x) __generic_bitfunc(stdc_leading_zeros, x)
+
+unsigned int stdc_leading_ones_uc(unsigned char) __pure2;
+unsigned int stdc_leading_ones_us(unsigned short) __pure2;
+unsigned int stdc_leading_ones_ui(unsigned int) __pure2;
+unsigned int stdc_leading_ones_ul(unsigned long) __pure2;
+unsigned int stdc_leading_ones_ull(unsigned long long) __pure2;
+#define stdc_leading_ones(x) __generic_bitfunc(stdc_leading_ones, x)
+
+unsigned int stdc_trailing_zeros_uc(unsigned char) __pure2;
+unsigned int stdc_trailing_zeros_us(unsigned short) __pure2;
+unsigned int stdc_trailing_zeros_ui(unsigned int) __pure2;
+unsigned int stdc_trailing_zeros_ul(unsigned long) __pure2;
+unsigned int stdc_trailing_zeros_ull(unsigned long long) __pure2;
+#define stdc_trailing_zeros(x) __generic_bitfunc(stdc_trailing_zeros, x)
+
+unsigned int stdc_trailing_ones_uc(unsigned char) __pure2;
+unsigned int stdc_trailing_ones_us(unsigned short) __pure2;
+unsigned int stdc_trailing_ones_ui(unsigned int) __pure2;
+unsigned int stdc_trailing_ones_ul(unsigned long) __pure2;
+unsigned int stdc_trailing_ones_ull(unsigned long long) __pure2;
+#define stdc_trailing_ones(x) __generic_bitfunc(stdc_trailing_ones, x)
+
+unsigned int stdc_first_leading_zero_uc(unsigned char) __pure2;
+unsigned int stdc_first_leading_zero_us(unsigned short) __pure2;
+unsigned int stdc_first_leading_zero_ui(unsigned int) __pure2;
+unsigned int stdc_first_leading_zero_ul(unsigned long) __pure2;
+unsigned int stdc_first_leading_zero_ull(unsigned long long) __pure2;
+#define stdc_first_leading_zero(x) __generic_bitfunc(stdc_first_leading_zero, x)
+
+unsigned int stdc_first_leading_one_uc(unsigned char) __pure2;
+unsigned int stdc_first_leading_one_us(unsigned short) __pure2;
+unsigned int stdc_first_leading_one_ui(unsigned int) __pure2;
+unsigned int stdc_first_leading_one_ul(unsigned long) __pure2;
+unsigned int stdc_first_leading_one_ull(unsigned long long) __pure2;
+#define stdc_first_leading_one(x) __generic_bitfunc(stdc_first_leading_one, x)
+
+unsigned int stdc_first_trailing_zero_uc(unsigned char) __pure2;
+unsigned int stdc_first_trailing_zero_us(unsigned short) __pure2;
+unsigned int stdc_first_trailing_zero_ui(unsigned int) __pure2;
+unsigned int stdc_first_trailing_zero_ul(unsigned long) __pure2;
+unsigned int stdc_first_trailing_zero_ull(unsigned long long) __pure2;
+#define stdc_first_trailing_zero(x) __generic_bitfunc(stdc_first_trailing_zero, x)
+
+unsigned int stdc_first_trailing_one_uc(unsigned char) __pure2;
+unsigned int stdc_first_trailing_one_us(unsigned short) __pure2;
+unsigned int stdc_first_trailing_one_ui(unsigned int) __pure2;
+unsigned int stdc_first_trailing_one_ul(unsigned long) __pure2;
+unsigned int stdc_first_trailing_one_ull(unsigned long long) __pure2;
+#define stdc_first_trailing_one(x) __generic_bitfunc(stdc_first_trailing_one, x)
+
+unsigned int stdc_count_zeros_uc(unsigned char) __pure2;
+unsigned int stdc_count_zeros_us(unsigned short) __pure2;
+unsigned int stdc_count_zeros_ui(unsigned int) __pure2;
+unsigned int stdc_count_zeros_ul(unsigned long) __pure2;
+unsigned int stdc_count_zeros_ull(unsigned long long) __pure2;
+#define stdc_count_zeros(x) __generic_bitfunc(stdc_count_zeros, x)
+
+unsigned int stdc_count_ones_uc(unsigned char) __pure2;
+unsigned int stdc_count_ones_us(unsigned short) __pure2;
+unsigned int stdc_count_ones_ui(unsigned int) __pure2;
+unsigned int stdc_count_ones_ul(unsigned long) __pure2;
+unsigned int stdc_count_ones_ull(unsigned long long) __pure2;
+#define stdc_count_ones(x) __generic_bitfunc(stdc_count_ones, x)
+
+_Bool stdc_has_single_bit_uc(unsigned char) __pure2;
+_Bool stdc_has_single_bit_us(unsigned short) __pure2;
+_Bool stdc_has_single_bit_ui(unsigned int) __pure2;
+_Bool stdc_has_single_bit_ul(unsigned long) __pure2;
+_Bool stdc_has_single_bit_ull(unsigned long long) __pure2;
+#define stdc_has_single_bit(x) __generic_bitfunc(stdc_has_single_bit, x)
+
+unsigned int stdc_bit_width_uc(unsigned char) __pure2;
+unsigned int stdc_bit_width_us(unsigned short) __pure2;
+unsigned int stdc_bit_width_ui(unsigned int) __pure2;
+unsigned int stdc_bit_width_ul(unsigned long) __pure2;
+unsigned int stdc_bit_width_ull(unsigned long long) __pure2;
+#define stdc_bit_width(x) __generic_bitfunc(stdc_bit_width, x)
+
+unsigned char stdc_bit_floor_uc(unsigned char) __pure2;
+unsigned short stdc_bit_floor_us(unsigned short) __pure2;
+unsigned stdc_bit_floor_ui(unsigned int) __pure2;
+unsigned long stdc_bit_floor_ul(unsigned long) __pure2;
+unsigned long long stdc_bit_floor_ull(unsigned long long) __pure2;
+#define stdc_bit_floor(x) __generic_bitfunc(stdc_bit_floor, x)
+
+unsigned char stdc_bit_ceil_uc(unsigned char) __pure2;
+unsigned short stdc_bit_ceil_us(unsigned short) __pure2;
+unsigned int stdc_bit_ceil_ui(unsigned int) __pure2;
+unsigned long stdc_bit_ceil_ul(unsigned long) __pure2;
+unsigned long long stdc_bit_ceil_ull(unsigned long long) __pure2;
+#define stdc_bit_ceil(x) __generic_bitfunc(stdc_bit_ceil, x)
+__END_DECLS
+
+#endif /* __STDC_VERSION_STDBIT_H__ */
diff --git a/newlib/libc/stdbit/stdc_bit_ceil.3 b/newlib/libc/stdbit/stdc_bit_ceil.3
new file mode 100644
index 000000000..470b255f4
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_bit_ceil.3
@@ -0,0 +1,81 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_BIT_CEIL 3
+.Os
+.Sh NAME
+.Nm stdc_bit_ceil
+.Nd round up to the next power of\~2
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned char
+.Fn stdc_bit_ceil_uc "unsigned char value"
+.Ft unsigned short
+.Fn stdc_bit_ceil_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_bit_ceil_ui "unsigned int value"
+.Ft unsigned long
+.Fn stdc_bit_ceil_ul "unsigned long value"
+.Ft unsigned long long
+.Fn stdc_bit_ceil_ull "unsigned long long value"
+.Ft typeof Ns Pq Em value
+.Fn stdc_bit_ceil "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_bit_ceil_ Ns Em type Ns ()
+family of functions rounds
+.Fa value
+up to the next power of\~2, where
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_bit_ceil "value"
+type-generic macro picks the appropriate
+.Nm stdc_bit_ceil_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns
+.Fa value
+round up to the next power of\~2.
+If this value is not representable,
+0\~is returned.
+.Sh SEE ALSO
+.Xr stdbit 3 ,
+.Xr stdc_bit_floor 3
+.Sh STANDARDS
+The
+.Nm stdc_bit_ceil_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_bit_ceil
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_bit_ceil_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_bit_ceil
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_bit_ceil.c b/newlib/libc/stdbit/stdc_bit_ceil.c
new file mode 100644
index 000000000..2dfd7bbcb
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_bit_ceil.c
@@ -0,0 +1,71 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbit.h>
+
+/* Ensure we don't shift 1U out of range. */
+static_assert(UCHAR_WIDTH < UINT_WIDTH,
+    "stdc_bit_ceil_uc needs UCHAR_WIDTH < UINT_WIDTH");
+
+unsigned char
+stdc_bit_ceil_uc(unsigned char x)
+{
+	if (x <= 1)
+		return (1);
+
+	return (1U << (UINT_WIDTH - __builtin_clz(x - 1)));
+}
+
+/* Ensure we don't shift 1U out of range. */
+static_assert(USHRT_WIDTH < UINT_WIDTH,
+    "stdc_bit_ceil_us needs USHRT_WIDTH < UINT_WIDTH");
+
+unsigned short
+stdc_bit_ceil_us(unsigned short x)
+{
+	if (x <= 1)
+		return (1);
+
+	return (1U << (UINT_WIDTH - __builtin_clz(x - 1)));
+}
+
+unsigned int
+stdc_bit_ceil_ui(unsigned int x)
+{
+	if (x <= 1)
+		return (1);
+
+	if (x > UINT_MAX/2 + 1)
+		return (0);
+
+	return (1U << (UINT_WIDTH - __builtin_clz(x - 1)));
+}
+
+unsigned long
+stdc_bit_ceil_ul(unsigned long x)
+{
+	if (x <= 1)
+		return (1);
+
+	if (x > ULONG_MAX/2 + 1)
+		return (0);
+
+	return (1UL << (ULONG_WIDTH - __builtin_clzl(x - 1)));
+}
+
+unsigned long long
+stdc_bit_ceil_ull(unsigned long long x)
+{
+	if (x <= 1)
+		return (1);
+
+	if (x > ULLONG_MAX/2 + 1)
+		return (0);
+
+	return (1ULL << (ULLONG_WIDTH - __builtin_clzll(x - 1)));
+}
diff --git a/newlib/libc/stdbit/stdc_bit_floor.3 b/newlib/libc/stdbit/stdc_bit_floor.3
new file mode 100644
index 000000000..3e90c34f0
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_bit_floor.3
@@ -0,0 +1,83 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_BIT_FLOOR 3
+.Os
+.Sh NAME
+.Nm stdc_bit_floor
+.Nd round down to the previous power of\~2
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned char
+.Fn stdc_bit_floor_uc "unsigned char value"
+.Ft unsigned short
+.Fn stdc_bit_floor_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_bit_floor_ui "unsigned int value"
+.Ft unsigned long
+.Fn stdc_bit_floor_ul "unsigned long value"
+.Ft unsigned long long
+.Fn stdc_bit_floor_ull "unsigned long long value"
+.Ft typeof Ns Pq Em value
+.Fn stdc_bit_floor "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_bit_floor_ Ns Em type Ns ()
+family of functions rounds
+.Fa value
+down to the previous power of\~2, where
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_bit_floor "value"
+type-generic macro picks the appropriate
+.Nm stdc_bit_floor_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns
+.Fa value
+round down to the previous power of\~2.
+If
+.Fa value
+is equal to zero,
+zero is returned.
+.Sh SEE ALSO
+.Xr stdbit 3 ,
+.Xr stdc_bit_ceil 3
+.Sh STANDARDS
+The
+.Nm stdc_bit_floor_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_bit_floor
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_bit_floor_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_bit_floor
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_bit_floor.c b/newlib/libc/stdbit/stdc_bit_floor.c
new file mode 100644
index 000000000..0a491d6ec
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_bit_floor.c
@@ -0,0 +1,53 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <limits.h>
+#include <stdbit.h>
+
+unsigned char
+stdc_bit_floor_uc(unsigned char x)
+{
+	if (x == 0)
+		return (0);
+
+	return (1U << (UINT_WIDTH - __builtin_clz(x) - 1));
+}
+
+unsigned short
+stdc_bit_floor_us(unsigned short x)
+{
+	if (x == 0)
+		return (0);
+
+	return (1U << (UINT_WIDTH - __builtin_clz(x) - 1));
+}
+
+unsigned int
+stdc_bit_floor_ui(unsigned int x)
+{
+	if (x == 0)
+		return (0);
+
+	return (1U << (UINT_WIDTH - __builtin_clz(x) - 1));
+}
+
+unsigned long
+stdc_bit_floor_ul(unsigned long x)
+{
+	if (x == 0)
+		return (0);
+
+	return (1UL << (ULONG_WIDTH - __builtin_clzl(x) - 1));
+}
+
+unsigned long long
+stdc_bit_floor_ull(unsigned long long x)
+{
+	if (x == 0)
+		return (0);
+
+	return (1ULL << (ULLONG_WIDTH - __builtin_clzll(x) - 1));
+}
diff --git a/newlib/libc/stdbit/stdc_bit_width.3 b/newlib/libc/stdbit/stdc_bit_width.3
new file mode 100644
index 000000000..8d5988681
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_bit_width.3
@@ -0,0 +1,104 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_BIT_WIDTH 3
+.Os
+.Sh NAME
+.Nm stdc_bit_width
+.Nd find the first trailing one in an intege
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_bit_width_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_bit_width_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_bit_width_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_bit_width_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_bit_width_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_bit_width "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_bit_width_ Ns Em type Ns ()
+family of functions returns the number of bits needed to represent
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_bit_width "value"
+type-generic macro picks the appropriate
+.Nm stdc_bit_width_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Pp
+Functions
+.Fn stdc_bit_width_ui ,
+.Fn stdc_bit_width_ul ,
+and
+.Fn stdc_bit_width_ull
+are identical to
+.Bx 4.3
+functions
+.Xr fls 3 ,
+.Xr flsl 3 ,
+and
+.Xr flsll 3
+respectively, except for operating on unsigned instead of signed values.
+.Sh RETURN VALUES
+Returns the least number of bits needed to represent
+.Fa value .
+If
+.Fa value
+is zero, the return value is zero.
+Otherwise it is
+.EQ
+1 + \(lf log sub 2 italic value \(rf .
+.EN
+.Sh SEE ALSO
+.Xr bit_fls 3 ,
+.Xr fls 3 ,
+.Xr flsl 3 ,
+.Xr flsll 3 ,
+.Xr stdbit 3 ,
+.Xr stdc_count_leading_zeros 3 ,
+.Xr stdc_first_leading_one 3
+.Sh STANDARDS
+The
+.Nm stdc_bit_width_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_bit_width
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_bit_width_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_bit_width
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_bit_width.c b/newlib/libc/stdbit/stdc_bit_width.c
new file mode 100644
index 000000000..e248fae48
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_bit_width.c
@@ -0,0 +1,53 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <limits.h>
+#include <stdbit.h>
+
+unsigned int
+stdc_bit_width_uc(unsigned char x)
+{
+	if (x == 0)
+		return (0);
+
+	return (UINT_WIDTH - __builtin_clz(x));
+}
+
+unsigned int
+stdc_bit_width_us(unsigned short x)
+{
+	if (x == 0)
+		return (0);
+
+	return (UINT_WIDTH - __builtin_clz(x));
+}
+
+unsigned int
+stdc_bit_width_ui(unsigned int x)
+{
+	if (x == 0)
+		return (0);
+
+	return (UINT_WIDTH - __builtin_clz(x));
+}
+
+unsigned int
+stdc_bit_width_ul(unsigned long x)
+{
+	if (x == 0)
+		return (0);
+
+	return (ULONG_WIDTH - __builtin_clzl(x));
+}
+
+unsigned int
+stdc_bit_width_ull(unsigned long long x)
+{
+	if (x == 0)
+		return (0);
+
+	return (ULLONG_WIDTH - __builtin_clzll(x));
+}
diff --git a/newlib/libc/stdbit/stdc_count_ones.3 b/newlib/libc/stdbit/stdc_count_ones.3
new file mode 100644
index 000000000..6de92216c
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_count_ones.3
@@ -0,0 +1,85 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_COUNT_ONES 3
+.Os
+.Sh NAME
+.Nm stdc_count_ones
+.Nd count the ones in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_count_ones_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_count_ones_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_count_ones_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_count_ones_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_count_ones_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_count_ones "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_count_ones_ Ns Em type Ns ()
+family of functions returns the number of bits set to\~1 in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+This is also known as the
+.Dq population count
+(popcount) or
+.Dq Hamming weight
+operation.
+The
+.Fn stdc_count_ones "value"
+type-generic macro picks the appropriate
+.Nm stdc_count_ones_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the number of bits set to\~1 in
+.Fa value .
+.Sh SEE ALSO
+.Xr bit_count 3 ,
+.Xr stdbit 3 ,
+.Xr stdc_count_zeros 3 ,
+.Xr stdc_has_single_bit 3
+.Sh STANDARDS
+The
+.Nm stdc_count_ones_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_count_ones
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_count_ones_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_count_ones
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_count_ones.c b/newlib/libc/stdbit/stdc_count_ones.c
new file mode 100644
index 000000000..c5198dca8
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_count_ones.c
@@ -0,0 +1,38 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <limits.h>
+#include <stdbit.h>
+
+unsigned int
+stdc_count_ones_uc(unsigned char x)
+{
+	return (__builtin_popcount(x));
+}
+
+unsigned int
+stdc_count_ones_us(unsigned short x)
+{
+	return (__builtin_popcount(x));
+}
+
+unsigned int
+stdc_count_ones_ui(unsigned int x)
+{
+	return (__builtin_popcount(x));
+}
+
+unsigned int
+stdc_count_ones_ul(unsigned long x)
+{
+	return (__builtin_popcountl(x));
+}
+
+unsigned int
+stdc_count_ones_ull(unsigned long long x)
+{
+	return (__builtin_popcountll(x));
+}
diff --git a/newlib/libc/stdbit/stdc_count_zeros.3 b/newlib/libc/stdbit/stdc_count_zeros.3
new file mode 100644
index 000000000..762ba62d3
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_count_zeros.3
@@ -0,0 +1,84 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_COUNT_ZEROS 3
+.Os
+.Sh NAME
+.Nm stdc_count_zeros
+.Nd count the zeros in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_count_zeros_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_count_zeros_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_count_zeros_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_count_zeros_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_count_zeros_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_count_zeros "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_count_zeros_ Ns Em type Ns ()
+family of functions returns the number of bits set to\~0 in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+This is also known as the
+.Dq population count
+(popcount) or
+.Dq Hamming weight
+of the complement of
+.Fa value .
+The
+.Fn stdc_count_zeros "value"
+type-generic macro picks the appropriate
+.Nm stdc_count_zeros_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the number of bits set to\~0 in
+.Fa value .
+.Sh SEE ALSO
+.Xr stdbit 3 ,
+.Xr stdc_count_ones 3
+.Sh STANDARDS
+The
+.Nm stdc_count_zeros_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_count_zeros
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_count_zeros_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_count_zeros
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_count_zeros.c b/newlib/libc/stdbit/stdc_count_zeros.c
new file mode 100644
index 000000000..35db965af
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_count_zeros.c
@@ -0,0 +1,38 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <limits.h>
+#include <stdbit.h>
+
+unsigned int
+stdc_count_zeros_uc(unsigned char x)
+{
+	return (__builtin_popcount(x ^ UCHAR_MAX));
+}
+
+unsigned int
+stdc_count_zeros_us(unsigned short x)
+{
+	return (__builtin_popcount(x ^ USHRT_MAX));
+}
+
+unsigned int
+stdc_count_zeros_ui(unsigned int x)
+{
+	return (__builtin_popcount(~x));
+}
+
+unsigned int
+stdc_count_zeros_ul(unsigned long x)
+{
+	return (__builtin_popcountl(~x));
+}
+
+unsigned int
+stdc_count_zeros_ull(unsigned long long x)
+{
+	return (__builtin_popcountll(~x));
+}
diff --git a/newlib/libc/stdbit/stdc_first_leading_one.3 b/newlib/libc/stdbit/stdc_first_leading_one.3
new file mode 100644
index 000000000..48f62d997
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_first_leading_one.3
@@ -0,0 +1,93 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_FIRST_LEADING_ONE 3
+.Os
+.Sh NAME
+.Nm stdc_first_leading_one
+.Nd find the first leading one in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_first_leading_one_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_first_leading_one_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_first_leading_one_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_first_leading_one_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_first_leading_one_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_first_leading_one "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_first_leading_one_ Ns Em type Ns ()
+family of functions returns the index of the most significant set bit in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_first_leading_one "value"
+type-generic macro picks the appropriate
+.Nm stdc_first_leading_one_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the index of the most significant set bit in
+.Fa value .
+The bits are numbered such that the most significant bit has number\~1,
+and the least significant bit has number
+.Ms w
+where
+.Ms w
+is the number of bits in the type of
+.Fa value .
+If no bits are set in
+.Fa value
+(i.\^e.\&
+.Fa value
+is zero), zero is returned.
+.Sh SEE ALSO
+.Xr fls 3 ,
+.Xr stdbit 3 ,
+.Xr stdc_leading_zeros 3 ,
+.Xr stdc_first_leading_zero 3 ,
+.Xr stdc_first_trailing_one 3
+.Sh STANDARDS
+The
+.Nm stdc_first_leading_one_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_first_leading_one
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_first_leading_one_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_first_leading_one
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_first_leading_one.c b/newlib/libc/stdbit/stdc_first_leading_one.c
new file mode 100644
index 000000000..de4368565
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_first_leading_one.c
@@ -0,0 +1,57 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <limits.h>
+#include <stdbit.h>
+
+unsigned int
+stdc_first_leading_one_uc(unsigned char x)
+{
+	const int offset = UINT_WIDTH - UCHAR_WIDTH;
+
+	if (x == 0)
+		return (0);
+
+	return (__builtin_clz(x << offset) + 1);
+}
+
+unsigned int
+stdc_first_leading_one_us(unsigned short x)
+{
+	const int offset = UINT_WIDTH - USHRT_WIDTH;
+
+	if (x == 0)
+		return (0);
+
+	return (__builtin_clz(x << offset) + 1);
+}
+
+unsigned int
+stdc_first_leading_one_ui(unsigned int x)
+{
+	if (x == 0)
+		return (0);
+
+	return (__builtin_clz(x) + 1);
+}
+
+unsigned int
+stdc_first_leading_one_ul(unsigned long x)
+{
+	if (x == 0)
+		return (0);
+
+	return (__builtin_clzl(x) + 1);
+}
+
+unsigned int
+stdc_first_leading_one_ull(unsigned long long x)
+{
+	if (x == 0)
+		return (0);
+
+	return (__builtin_clzll(x) + 1);
+}
diff --git a/newlib/libc/stdbit/stdc_first_leading_zero.3 b/newlib/libc/stdbit/stdc_first_leading_zero.3
new file mode 100644
index 000000000..317b6263a
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_first_leading_zero.3
@@ -0,0 +1,92 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_FIRST_LEADING_ZERO 3
+.Os
+.Sh NAME
+.Nm stdc_first_leading_zero
+.Nd find the first leading zero in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_first_leading_zero_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_first_leading_zero_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_first_leading_zero_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_first_leading_zero_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_first_leading_zero_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_first_leading_zero "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_first_leading_zero_ Ns Em type Ns ()
+family of functions returns the index of the most significant clear bit in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_first_leading_zero "value"
+type-generic macro picks the appropriate
+.Nm stdc_first_leading_zero_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the index of the most significant clear bit in
+.Fa value .
+The bits are numbered such that the most significant bit has number\~1,
+and the least significant bit has number
+.Ms w
+where
+.Ms w
+is the number of bits in the type of
+.Fa value .
+If no bits are clear in
+.Fa value
+(i.\^e.\&
+.Fa value
+is the bitwise complement of zero), zero is returned.
+.Sh SEE ALSO
+.Xr stdbit 3 ,
+.Xr stdc_leading_ones 3 ,
+.Xr stdc_first_leading_ones 3 ,
+.Xr stdc_first_trailing_zero 3
+.Sh STANDARDS
+The
+.Nm stdc_first_leading_zero_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_first_leading_zero
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_first_leading_zero_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_first_leading_zero
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_first_leading_zero.c b/newlib/libc/stdbit/stdc_first_leading_zero.c
new file mode 100644
index 000000000..e6609b51b
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_first_leading_zero.c
@@ -0,0 +1,57 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <limits.h>
+#include <stdbit.h>
+
+unsigned int
+stdc_first_leading_zero_uc(unsigned char x)
+{
+	const int offset = UINT_WIDTH - UCHAR_WIDTH;
+
+	if (x == UCHAR_MAX)
+		return (0);
+
+	return (__builtin_clz(~(unsigned int)x << offset) + 1);
+}
+
+unsigned int
+stdc_first_leading_zero_us(unsigned short x)
+{
+	const int offset = UINT_WIDTH - USHRT_WIDTH;
+
+	if (x == USHRT_MAX)
+		return (0);
+
+	return (__builtin_clz(~(unsigned int)x << offset) + 1);
+}
+
+unsigned int
+stdc_first_leading_zero_ui(unsigned int x)
+{
+	if (x == ~0U)
+		return (0);
+
+	return (__builtin_clz(~x) + 1);
+}
+
+unsigned int
+stdc_first_leading_zero_ul(unsigned long x)
+{
+	if (x == ~0UL)
+		return (0);
+
+	return (__builtin_clzl(~x) + 1);
+}
+
+unsigned int
+stdc_first_leading_zero_ull(unsigned long long x)
+{
+	if (x == ~0ULL)
+		return (0);
+
+	return (__builtin_clzll(~x) + 1);
+}
diff --git a/newlib/libc/stdbit/stdc_first_trailing_one.3 b/newlib/libc/stdbit/stdc_first_trailing_one.3
new file mode 100644
index 000000000..0b590ac39
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_first_trailing_one.3
@@ -0,0 +1,110 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_FIRST_TRAILING_ONE 3
+.Os
+.Sh NAME
+.Nm stdc_first_trailing_one
+.Nd find the first trailing one in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_first_trailing_one_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_first_trailing_one_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_first_trailing_one_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_first_trailing_one_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_first_trailing_one_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_first_trailing_one "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_first_trailing_one_ Ns Em type Ns ()
+family of functions returns the index of the least significant set bit in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_first_trailing_one "value"
+type-generic macro picks the appropriate
+.Nm stdc_first_trailing_one_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Pp
+Functions
+.Fn stdc_first_trailing_one_ui ,
+.Fn stdc_first_trailing_one_ul ,
+and
+.Fn stdc_first_trailing_one_ull
+are identical to
+.Bx 4.3
+functions
+.Xr ffs 3 ,
+.Xr ffsl 3 ,
+and
+.Xr ffsll 3
+respectively, except for operating on unsigned instead of signed values.
+.Sh RETURN VALUES
+Returns the index of the least significant set bit in
+.Fa value .
+The bits are numbered such that the least significant bit has number\~1,
+and the most significant bit has number
+.Ms w
+where
+.Ms w
+is the number of bits in the type of
+.Fa value .
+If no bits are set in
+.Fa value
+(i.\^e.\&
+.Fa value
+is zero), one is returned.
+.Sh SEE ALSO
+.Xr bit_ffs 3 ,
+.Xr ffs 3 ,
+.Xr ffsl 3 ,
+.Xr ffsll 3 ,
+.Xr stdbit 3 ,
+.Xr stdc_trailing_zeros 3 ,
+.Xr stdc_first_trailing_zero 3 ,
+.Xr stdc_first_leading_one 3
+.Sh STANDARDS
+The
+.Nm stdc_first_trailing_one_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_first_trailing_one
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_first_trailing_one_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_first_trailing_one
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_first_trailing_one.c b/newlib/libc/stdbit/stdc_first_trailing_one.c
new file mode 100644
index 000000000..22972758d
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_first_trailing_one.c
@@ -0,0 +1,52 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdbit.h>
+
+unsigned int
+stdc_first_trailing_one_uc(unsigned char x)
+{
+	if (x == 0)
+		return (0);
+
+	return (__builtin_ctz(x) + 1);
+}
+
+unsigned int
+stdc_first_trailing_one_us(unsigned short x)
+{
+	if (x == 0)
+		return (0);
+
+	return (__builtin_ctz(x) + 1);
+}
+
+unsigned int
+stdc_first_trailing_one_ui(unsigned int x)
+{
+	if (x == 0)
+		return (0);
+
+	return (__builtin_ctz(x) + 1);
+}
+
+unsigned int
+stdc_first_trailing_one_ul(unsigned long x)
+{
+	if (x == 0)
+		return (0);
+
+	return (__builtin_ctzl(x) + 1);
+}
+
+unsigned int
+stdc_first_trailing_one_ull(unsigned long long x)
+{
+	if (x == 0)
+		return (0);
+
+	return (__builtin_ctzll(x) + 1);
+}
diff --git a/newlib/libc/stdbit/stdc_first_trailing_zero.3 b/newlib/libc/stdbit/stdc_first_trailing_zero.3
new file mode 100644
index 000000000..bc4f7982d
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_first_trailing_zero.3
@@ -0,0 +1,93 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_FIRST_TRAILING_ZERO 3
+.Os
+.Sh NAME
+.Nm stdc_first_trailing_zero
+.Nd find the first trailing zero in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_first_trailing_zero_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_first_trailing_zero_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_first_trailing_zero_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_first_trailing_zero_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_first_trailing_zero_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_first_trailing_zero "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_first_trailing_zero_ Ns Em type Ns ()
+family of functions returns the index of the least significant clear bit in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_first_trailing_zero "value"
+type-generic macro picks the appropriate
+.Nm stdc_first_trailing_zero_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the index of the least significant clear bit in
+.Fa value .
+The bits are numbered such that the least significant bit has number\~1,
+and the most significant bit has number
+.Ms w
+where
+.Ms w
+is the number of bits in the type of
+.Fa value .
+If no bits are clear in
+.Fa value
+(i.\^e.\&
+.Fa value
+is the bitwise complement of zero), zero is returned.
+.Sh SEE ALSO
+.Xr bit_ffc 3 ,
+.Xr stdbit 3 ,
+.Xr stdc_trailing_ones 3 ,
+.Xr stdc_first_trailing_ones 3 ,
+.Xr stdc_first_leading_zero 3
+.Sh STANDARDS
+The
+.Nm stdc_first_trailing_zero_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_first_trailing_zero
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_first_trailing_zero_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_first_trailing_zero
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_first_trailing_zero.c b/newlib/libc/stdbit/stdc_first_trailing_zero.c
new file mode 100644
index 000000000..27395c697
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_first_trailing_zero.c
@@ -0,0 +1,53 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <limits.h>
+#include <stdbit.h>
+
+unsigned int
+stdc_first_trailing_zero_uc(unsigned char x)
+{
+	if (x == UCHAR_MAX)
+		return (0);
+
+	return (__builtin_ctz(~x) + 1);
+}
+
+unsigned int
+stdc_first_trailing_zero_us(unsigned short x)
+{
+	if (x == USHRT_MAX)
+		return (0);
+
+	return (__builtin_ctz(~x) + 1);
+}
+
+unsigned int
+stdc_first_trailing_zero_ui(unsigned int x)
+{
+	if (x == ~0U)
+		return (0);
+
+	return (__builtin_ctz(~x) + 1);
+}
+
+unsigned int
+stdc_first_trailing_zero_ul(unsigned long x)
+{
+	if (x == ~0UL)
+		return (0);
+
+	return (__builtin_ctzl(~x) + 1);
+}
+
+unsigned int
+stdc_first_trailing_zero_ull(unsigned long long x)
+{
+	if (x == ~0ULL)
+		return (0);
+
+	return (__builtin_ctzll(~x) + 1);
+}
diff --git a/newlib/libc/stdbit/stdc_has_single_bit.3 b/newlib/libc/stdbit/stdc_has_single_bit.3
new file mode 100644
index 000000000..8f82c5522
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_has_single_bit.3
@@ -0,0 +1,98 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_HAS_SINGLE_BIT 3
+.Os
+.Sh NAME
+.Nm stdc_has_single_bit
+.Nd check for single bit set
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft bool
+.Fn stdc_has_single_bit_uc "unsigned char value"
+.Ft bool
+.Fn stdc_has_single_bit_us "unsigned short value"
+.Ft bool
+.Fn stdc_has_single_bit_ui "unsigned int value"
+.Ft bool
+.Fn stdc_has_single_bit_ul "unsigned long value"
+.Ft bool
+.Fn stdc_has_single_bit_ull "unsigned long long value"
+.Ft bool
+.Fn stdc_has_single_bit "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_has_single_bit_ Ns Em type Ns ()
+family of functions checks if there is exactly one bit
+set in
+.Fa value ,
+where
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_has_single_bit "value"
+type-generic macro picks the appropriate
+.Nm stdc_has_single_bit_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Pp
+The functions in this family behave similarly to the
+.Fn powerof2 "value"
+macro of
+.In sys/param.h ,
+but differ when
+.Fa value
+is zero: while
+.Fn powerof2
+considers zero to be a power of two,
+.Fn stdc_has_single_bit
+does not.
+.Sh RETURN VALUES
+Returns
+.Sy true
+if exactly one bit is set in
+.Fa value ,
+otherwise returns
+.Sy false .
+I.\^e. the function determines if
+.Fa value
+is a power of two.
+.Sh SEE ALSO
+.Xr stdbit 3 ,
+.Xr stdc_count_ones 3
+.Sh STANDARDS
+The
+.Nm stdc_has_single_bit_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_has_single_bit
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_has_single_bit_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_has_single_bit
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_has_single_bit.c b/newlib/libc/stdbit/stdc_has_single_bit.c
new file mode 100644
index 000000000..a448464b0
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_has_single_bit.c
@@ -0,0 +1,38 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdbit.h>
+#include <stdbool.h>
+
+bool
+stdc_has_single_bit_uc(unsigned char x)
+{
+	return (x != 0 && (x & (x - 1)) == 0);
+}
+
+bool
+stdc_has_single_bit_us(unsigned short x)
+{
+	return (x != 0 && (x & (x - 1)) == 0);
+}
+
+bool
+stdc_has_single_bit_ui(unsigned int x)
+{
+	return (x != 0 && (x & (x - 1)) == 0);
+}
+
+bool
+stdc_has_single_bit_ul(unsigned long x)
+{
+	return (x != 0 && (x & (x - 1)) == 0);
+}
+
+bool
+stdc_has_single_bit_ull(unsigned long long x)
+{
+	return (x != 0 && (x & (x - 1)) == 0);
+}
diff --git a/newlib/libc/stdbit/stdc_leading_ones.3 b/newlib/libc/stdbit/stdc_leading_ones.3
new file mode 100644
index 000000000..6cf7989b7
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_leading_ones.3
@@ -0,0 +1,86 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_LEADING_ONES 3
+.Os
+.Sh NAME
+.Nm stdc_leading_ones
+.Nd find the number of leading ones in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_leading_ones_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_leading_ones_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_leading_ones_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_leading_ones_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_leading_ones_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_leading_ones "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_leading_ones_ Ns Em type Ns ()
+family of functions returns the number of leading ones in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_leading_ones "value"
+type-generic macro picks the appropriate
+.Nm stdc_leading_ones_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the number of leading ones in
+.Fa value .
+If
+.Fa value
+is all ones,
+the total number of bits in the type of
+.Fa value
+is returned.
+.Sh SEE ALSO
+.Xr stdbit 3 ,
+.Xr stdc_leading_zeros 3 ,
+.Xr stdc_trailing_ones 3 ,
+.Xr stdc_first_leading_zero 3
+.Sh STANDARDS
+The
+.Nm stdc_leading_ones_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_leading_ones
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_leading_ones_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_leading_ones
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_leading_ones.c b/newlib/libc/stdbit/stdc_leading_ones.c
new file mode 100644
index 000000000..79d3ec7f2
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_leading_ones.c
@@ -0,0 +1,60 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbit.h>
+
+/* Avoid triggering undefined behavior if x == 0. */
+static_assert(UCHAR_WIDTH < UINT_WIDTH,
+    "stdc_leading_ones_uc needs UCHAR_WIDTH < UINT_WIDTH");
+
+unsigned int
+stdc_leading_ones_uc(unsigned char x)
+{
+	const int offset = UINT_WIDTH - UCHAR_WIDTH;
+
+	return (__builtin_clz(~(x << offset)));
+}
+
+/* Avoid triggering undefined behavior if x == 0. */
+static_assert(USHRT_WIDTH < UINT_WIDTH,
+    "stdc_leading_ones_us needs USHRT_WIDTH < UINT_WIDTH");
+
+unsigned int
+stdc_leading_ones_us(unsigned short x)
+{
+	const int offset = UINT_WIDTH - USHRT_WIDTH;
+
+	return (__builtin_clz(~(x << offset)));
+}
+
+unsigned int
+stdc_leading_ones_ui(unsigned int x)
+{
+	if (x == ~0U)
+		return (UINT_WIDTH);
+
+	return (__builtin_clz(~x));
+}
+
+unsigned int
+stdc_leading_ones_ul(unsigned long x)
+{
+	if (x == ~0UL)
+		return (ULONG_WIDTH);
+
+	return (__builtin_clzl(~x));
+}
+
+unsigned int
+stdc_leading_ones_ull(unsigned long long x)
+{
+	if (x == ~0ULL)
+		return (ULLONG_WIDTH);
+
+	return (__builtin_clzll(~x));
+}
diff --git a/newlib/libc/stdbit/stdc_leading_zeros.3 b/newlib/libc/stdbit/stdc_leading_zeros.3
new file mode 100644
index 000000000..7a7a203ac
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_leading_zeros.3
@@ -0,0 +1,86 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_LEADING_ZEROS 3
+.Os
+.Sh NAME
+.Nm stdc_leading_zeros
+.Nd find the number of leading zeros in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_leading_zeros_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_leading_zeros_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_leading_zeros_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_leading_zeros_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_leading_zeros_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_leading_zeros "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_leading_zeros_ Ns Em type Ns ()
+family of functions returns the number of leading zeros in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_leading_zeros "value"
+type-generic macro picks the appropriate
+.Nm stdc_leading_zeros_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the number of leading zeros in
+.Fa value .
+If
+.Fa value
+is all zeros,
+the total number of bits in the type of
+.Fa value
+is returned.
+.Sh SEE ALSO
+.Xr stdbit 3 ,
+.Xr stdc_leading_ones 3 ,
+.Xr stdc_trailing_zeros 3 ,
+.Xr stdc_first_leading_one 3
+.Sh STANDARDS
+The
+.Nm stdc_leading_zeros_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_leading_zeros
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_leading_zeros_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_leading_zeros
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_leading_zeros.c b/newlib/libc/stdbit/stdc_leading_zeros.c
new file mode 100644
index 000000000..2fdf64ec9
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_leading_zeros.c
@@ -0,0 +1,60 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbit.h>
+
+/* Offset must be greater than zero. */
+static_assert(UCHAR_WIDTH < UINT_WIDTH,
+    "stdc_leading_zeros_uc needs UCHAR_WIDTH < UINT_WIDTH");
+
+unsigned int
+stdc_leading_zeros_uc(unsigned char x)
+{
+	const int offset = UINT_WIDTH - UCHAR_WIDTH;
+
+	return (__builtin_clz((x << offset) + (1U << (offset - 1))));
+}
+
+/* Offset must be greater than zero. */
+static_assert(USHRT_WIDTH < UINT_WIDTH,
+    "stdc_leading_zeros_us needs USHRT_WIDTH < UINT_WIDTH");
+
+unsigned int
+stdc_leading_zeros_us(unsigned short x)
+{
+	const int offset = UINT_WIDTH - USHRT_WIDTH;
+
+	return (__builtin_clz((x << offset) + (1U << (offset - 1))));
+}
+
+unsigned int
+stdc_leading_zeros_ui(unsigned int x)
+{
+	if (x == 0)
+		return (UINT_WIDTH);
+
+	return (__builtin_clz(x));
+}
+
+unsigned int
+stdc_leading_zeros_ul(unsigned long x)
+{
+	if (x == 0)
+		return (ULONG_WIDTH);
+
+	return (__builtin_clzl(x));
+}
+
+unsigned int
+stdc_leading_zeros_ull(unsigned long long x)
+{
+	if (x == 0)
+		return (ULLONG_WIDTH);
+
+	return (__builtin_clzll(x));
+}
diff --git a/newlib/libc/stdbit/stdc_trailing_ones.3 b/newlib/libc/stdbit/stdc_trailing_ones.3
new file mode 100644
index 000000000..96277506f
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_trailing_ones.3
@@ -0,0 +1,86 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_TRAILING_ONES 3
+.Os
+.Sh NAME
+.Nm stdc_trailing_ones
+.Nd find the number of trailing ones in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_trailing_ones_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_trailing_ones_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_trailing_ones_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_trailing_ones_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_trailing_ones_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_trailing_ones "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_trailing_ones_ Ns Em type Ns ()
+family of functions returns the number of trailing ones in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_trailing_ones "value"
+type-generic macro picks the appropriate
+.Nm stdc_trailing_ones_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the number of trailing ones in
+.Fa value .
+If
+.Fa value
+is all ones,
+the total number of bits in the type of
+.Fa value
+is returned.
+.Sh SEE ALSO
+.Xr stdbit 3 ,
+.Xr stdc_leading_ones 3 ,
+.Xr stdc_trailing_zeros 3 ,
+.Xr stdc_first_trailing_zero 3
+.Sh STANDARDS
+The
+.Nm stdc_trailing_ones_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_trailing_ones
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_trailing_ones_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_trailing_ones
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_trailing_ones.c b/newlib/libc/stdbit/stdc_trailing_ones.c
new file mode 100644
index 000000000..c1a0e6b99
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_trailing_ones.c
@@ -0,0 +1,56 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbit.h>
+
+/* Avoid triggering undefined behavior if x == ~0. */
+static_assert(UCHAR_WIDTH < UINT_WIDTH,
+    "stdc_trailing_ones_uc needs UCHAR_WIDTH < UINT_WIDTH");
+
+unsigned int
+stdc_trailing_ones_uc(unsigned char x)
+{
+	return (__builtin_ctz(~x));
+}
+
+/* Avoid triggering undefined behavior if x == ~0. */
+static_assert(USHRT_WIDTH < UINT_WIDTH,
+    "stdc_trailing_ones_uc needs USHRT_WIDTH < UINT_WIDTH");
+
+unsigned int
+stdc_trailing_ones_us(unsigned short x)
+{
+	return (__builtin_ctz(~x));
+}
+
+unsigned int
+stdc_trailing_ones_ui(unsigned int x)
+{
+	if (x == ~0U)
+		return (UINT_WIDTH);
+
+	return (__builtin_ctz(~x));
+}
+
+unsigned int
+stdc_trailing_ones_ul(unsigned long x)
+{
+	if (x == ~0UL)
+		return (ULONG_WIDTH);
+
+	return (__builtin_ctzl(~x));
+}
+
+unsigned int
+stdc_trailing_ones_ull(unsigned long long x)
+{
+	if (x == ~0ULL)
+		return (ULLONG_WIDTH);
+
+	return (__builtin_ctzll(~x));
+}
diff --git a/newlib/libc/stdbit/stdc_trailing_zeros.3 b/newlib/libc/stdbit/stdc_trailing_zeros.3
new file mode 100644
index 000000000..4bc675590
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_trailing_zeros.3
@@ -0,0 +1,87 @@ 
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 9, 2025
+.Dt STDC_TRAILING_ZEROS 3
+.Os
+.Sh NAME
+.Nm stdc_trailing_zeros
+.Nd find the number of trailing zeros in an integer
+.Sh SYNOPSIS
+.Lb libc
+.In stdbit.h
+.Ft unsigned int
+.Fn stdc_trailing_zeros_uc "unsigned char value"
+.Ft unsigned int
+.Fn stdc_trailing_zeros_us "unsigned short value"
+.Ft unsigned int
+.Fn stdc_trailing_zeros_ui "unsigned int value"
+.Ft unsigned int
+.Fn stdc_trailing_zeros_ul "unsigned long value"
+.Ft unsigned int
+.Fn stdc_trailing_zeros_ull "unsigned long long value"
+.Ft unsigned int
+.Fn stdc_trailing_zeros "value"
+.Sh DESCRIPTION
+The
+.Nm stdc_trailing_zeros_ Ns Em type Ns ()
+family of functions returns the number of trailing zeros in
+.Fa value ,
+where 
+.Fa value
+is of type
+.Va unsigned char ,
+.Va unsigned short ,
+.Va unsigned int ,
+.Va unsigned long ,
+or
+.Va unsigned long long
+for
+.Em type
+being
+.Sy uc ,
+.Sy us ,
+.Sy ui ,
+.Sy ul ,
+or
+.Sy ull
+respectively.
+The
+.Fn stdc_trailing_zeros "value"
+type-generic macro picks the appropriate
+.Nm stdc_trailing_zeros_ Ns Em type Ns ()
+function based on the type of
+.Fa value .
+.Sh RETURN VALUES
+Returns the number of trailing zeros in
+.Fa value .
+If
+.Fa value
+is all zeros,
+the total number of bits in the type of
+.Fa value
+is returned.
+.Sh SEE ALSO
+.Xr ffs 3 ,
+.Xr stdbit 3 ,
+.Xr stdc_leading_zeros 3 ,
+.Xr stdc_trailing_ones 3 ,
+.Xr stdc_first_trailing_one 3
+.Sh STANDARDS
+The
+.Nm stdc_trailing_zeros_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_trailing_zeros
+type-generic macro conform to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Nm stdc_trailing_zeros_ Ns Em type Ns ()
+family of functions and the
+.Fn stdc_trailing_zeros
+type-generic macro were added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/newlib/libc/stdbit/stdc_trailing_zeros.c b/newlib/libc/stdbit/stdc_trailing_zeros.c
new file mode 100644
index 000000000..6213f62cf
--- /dev/null
+++ b/newlib/libc/stdbit/stdc_trailing_zeros.c
@@ -0,0 +1,56 @@ 
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <assert.h>
+#include <limits.h>
+#include <stdbit.h>
+
+/* Ensure we do not shift 1U out of range. */
+static_assert(UCHAR_WIDTH < UINT_WIDTH,
+    "stdc_trailing_zeros_uc needs UCHAR_WIDTH < UINT_WIDTH");
+
+unsigned int
+stdc_trailing_zeros_uc(unsigned char x)
+{
+	return (__builtin_ctz(x | 1U << UCHAR_WIDTH));
+}
+
+/* Ensure we do not shift 1U out of range. */
+static_assert(USHRT_WIDTH < UINT_WIDTH,
+    "stdc_trailing_zeros_uc needs USHRT_WIDTH < UINT_WIDTH");
+
+unsigned int
+stdc_trailing_zeros_us(unsigned short x)
+{
+	return (__builtin_ctz(x | 1U << USHRT_WIDTH));
+}
+
+unsigned int
+stdc_trailing_zeros_ui(unsigned int x)
+{
+	if (x == 0U)
+		return (UINT_WIDTH);
+
+	return (__builtin_ctz(x));
+}
+
+unsigned int
+stdc_trailing_zeros_ul(unsigned long x)
+{
+	if (x == 0UL)
+		return (ULONG_WIDTH);
+
+	return (__builtin_ctzl(x));
+}
+
+unsigned int
+stdc_trailing_zeros_ull(unsigned long long x)
+{
+	if (x == 0ULL)
+		return (ULLONG_WIDTH);
+
+	return (__builtin_ctzll(x));
+}