Page MenuHomeFreeBSD

libkern: Add libcalls for ffs and __ffsdi2
ClosedPublic

Authored by jhb on Jan 30 2026, 3:06 PM.
Tags
None
Referenced Files
Unknown Object (File)
Tue, Feb 10, 9:25 PM
Unknown Object (File)
Mon, Feb 9, 11:15 PM
Unknown Object (File)
Feb 1 2026, 11:41 AM
Unknown Object (File)
Feb 1 2026, 4:39 AM
Unknown Object (File)
Feb 1 2026, 12:53 AM
Unknown Object (File)
Feb 1 2026, 12:16 AM
Unknown Object (File)
Jan 31 2026, 11:48 PM
Unknown Object (File)
Jan 31 2026, 11:48 AM
Subscribers

Details

Summary

These are needed when compiling a RISC-V kernel with GCC which does
not inline __builtin_ffs*.

The __ffsdi2 is adapated from the previous ffsl.c.

This partially reverts commit f4db342d44198973c1c7b9005d0c5683a582707e.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 70238
Build 67121: arc lint + arc unit

Event Timeline

I don't know why __builtin_ffs for RISC-V on GCC calls ffs rather than __ffssi2 for its libcall. The latter would seem cleaner to me.

mhorne added a subscriber: dougm.

Fine by me.

A little more context: there were previously a handful of places in the kernel which implemented binary search instead of using the slow ffs/fls variants from our libkern. In 2023, @dougm and I cleaned these up, under the assumption that the compiler builtins would always provide an equally optimal implementation, if not better. See also: D40698, D40703, D40704, D40705, ffaea08319.

So this assumption is violated by this particular combination of riscv built by GCC, and the hidden consequence is that it will have a performance penalty in a couple areas, as compared to clang which picks up the compiler-rt versions of these functions. I do not think this is anything to fret over, but I want to note this as being quite obscure, and likely to be forgotten in the future.

This revision is now accepted and ready to land.Jan 30 2026, 5:58 PM

Fine by me.

A little more context: there were previously a handful of places in the kernel which implemented binary search instead of using the slow ffs/fls variants from our libkern. In 2023, @dougm and I cleaned these up, under the assumption that the compiler builtins would always provide an equally optimal implementation, if not better. See also: D40698, D40703, D40704, D40705, ffaea08319.

So this assumption is violated by this particular combination of riscv built by GCC, and the hidden consequence is that it will have a performance penalty in a couple areas, as compared to clang which picks up the compiler-rt versions of these functions. I do not think this is anything to fret over, but I want to note this as being quite obscure, and likely to be forgotten in the future.

Clang doesn't pick up the compiler-rt versions, it just inlines these things instead of emitting libcalls. GCC tends to fall back to libcalls more often than clang. When I previously tried to build the riscv64 world with GCC it emitted a bunch of libcalls for atomics that are provided by libatomic.a in GCC (and which don't have an equivalent in compiler_rt), but GCC seems to have fixed that and now does direct code-generation instead. My primary goal with building the base system with GCC is getting the extra warning coverage as GCC finds things clang doesn't (and vice versa). I haven't tried to actually boot a kernel/world built with GCC in quite a long time (though I do kind of wish someone was testing that as well).

If we cared about the performance of these, we could certainly make them less dumb following something similar to the ctz* implementations in compiler_rt.

This revision was automatically updated to reflect the committed changes.