From 8cbd4e746f40c750809e34d04c0298e0a5ff6f42 Mon Sep 17 00:00:00 2001 From: claudio <> Date: Fri, 24 Oct 2025 11:30:06 +0000 Subject: Implement ffsl() and ffsll() using the compiler builtin __builtin_ctzl now that all archs use at least gcc4. ffsl() and ffsll() are now part of POSIX. OK deraadt@, input from miod@ and jsg@ --- src/lib/libc/string/Makefile.inc | 12 ++++++------ src/lib/libc/string/ffs.3 | 31 ++++++++++++++++++++++++++----- src/lib/libc/string/ffsl.c | 17 +++++++++++++++++ src/lib/libc/string/ffsll.c | 17 +++++++++++++++++ 4 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 src/lib/libc/string/ffsl.c create mode 100644 src/lib/libc/string/ffsll.c (limited to 'src/lib') diff --git a/src/lib/libc/string/Makefile.inc b/src/lib/libc/string/Makefile.inc index 204ca1b266..f8b6330453 100644 --- a/src/lib/libc/string/Makefile.inc +++ b/src/lib/libc/string/Makefile.inc @@ -1,13 +1,13 @@ -# $OpenBSD: Makefile.inc,v 1.40 2024/07/14 09:51:18 jca Exp $ +# $OpenBSD: Makefile.inc,v 1.41 2025/10/24 11:30:06 claudio Exp $ # string sources .PATH: ${LIBCSRCDIR}/arch/${MACHINE_CPU}/string ${LIBCSRCDIR}/string -SRCS+= explicit_bzero.c memccpy.c memmem.c memrchr.c stpcpy.c stpncpy.c \ - strcasecmp.c strcasecmp_l.c strcasestr.c strcoll.c strcoll_l.c \ - strdup.c strerror.c strerror_l.c strerror_r.c strmode.c \ - strndup.c strnlen.c strsignal.c strtok.c strxfrm.c strxfrm_l.c \ - timingsafe_bcmp.c timingsafe_memcmp.c \ +SRCS+= explicit_bzero.c ffsl.c ffsll.c memccpy.c memmem.c memrchr.c \ + stpcpy.c stpncpy.c strcasecmp.c strcasecmp_l.c strcasestr.c \ + strcoll.c strcoll_l.c strdup.c strerror.c strerror_l.c strerror_r.c \ + strmode.c strndup.c strnlen.c strsignal.c strtok.c strxfrm.c \ + strxfrm_l.c timingsafe_bcmp.c timingsafe_memcmp.c \ wcscat.c wcschr.c wcscmp.c wcscpy.c wcscspn.c wcslcat.c wcslcpy.c \ wcslen.c wcsncat.c wcsncmp.c wcsncpy.c wcsnlen.c wcspbrk.c wcsrchr.c \ wcsspn.c wcsstr.c wcstok.c wcswcs.c wcswidth.c wmemchr.c wmemcmp.c \ diff --git a/src/lib/libc/string/ffs.3 b/src/lib/libc/string/ffs.3 index e78ab99e8f..630db1c584 100644 --- a/src/lib/libc/string/ffs.3 +++ b/src/lib/libc/string/ffs.3 @@ -27,22 +27,31 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $OpenBSD: ffs.3,v 1.11 2019/08/30 18:35:03 deraadt Exp $ +.\" $OpenBSD: ffs.3,v 1.12 2025/10/24 11:30:06 claudio Exp $ .\" -.Dd $Mdocdate: August 30 2019 $ +.Dd $Mdocdate: October 24 2025 $ .Dt FFS 3 .Os .Sh NAME -.Nm ffs +.Nm ffs , +.Nm ffsl , +.Nm ffsll .Nd find first bit set in a bit string .Sh SYNOPSIS .In strings.h .Ft int .Fn ffs "int value" +.Ft int +.Fn ffsl "long value" +.Ft int +.Fn ffsll "long long value" .Sh DESCRIPTION The -.Fn ffs -function finds the first bit set in +.Fn ffs , +.Fn ffsl +and +.Fn ffsll +functions find the first bit set in .Fa value and returns the index of that bit. Bits are numbered starting from 1, starting at the rightmost bit. @@ -54,8 +63,20 @@ The .Fn ffs function conforms to .St -p1003.1-2008 . +The +.Fn ffsl +and +.Fn ffsll +functions conform to +.St -p1003.1-2024 . .Sh HISTORY The .Fn ffs function first appeared in .Bx 4.2 . +The +.Fn ffsl +and +.Fn ffsll +functions first appeared in +.Ox 7.9 . diff --git a/src/lib/libc/string/ffsl.c b/src/lib/libc/string/ffsl.c new file mode 100644 index 0000000000..182318c3d6 --- /dev/null +++ b/src/lib/libc/string/ffsl.c @@ -0,0 +1,17 @@ +/* $OpenBSD: ffsl.c,v 1.1 2025/10/24 11:30:06 claudio Exp $ */ + +/* + * Public domain. + * Written by Claudio Jeker. + */ + +#include + +/* + * ffs -- find the first (least significant) bit set + */ +int +ffsl(long mask) +{ + return (mask ? __builtin_ctzl(mask) + 1 : 0); +} diff --git a/src/lib/libc/string/ffsll.c b/src/lib/libc/string/ffsll.c new file mode 100644 index 0000000000..9370c5ae41 --- /dev/null +++ b/src/lib/libc/string/ffsll.c @@ -0,0 +1,17 @@ +/* $OpenBSD: ffsll.c,v 1.1 2025/10/24 11:30:06 claudio Exp $ */ + +/* + * Public domain. + * Written by Claudio Jeker. + */ + +#include + +/* + * ffs -- find the first (least significant) bit set + */ +int +ffsll(long long mask) +{ + return (mask ? __builtin_ctzll(mask) + 1 : 0); +} -- cgit v1.2.3-55-g6feb