Alexandre Courbot
2025-Jun-12 14:01 UTC
[PATCH v5 05/23] rust: num: add the `fls` operation
Add an equivalent to the `fls` (Find Last Set bit) C function to Rust
unsigned types.
It is to be first used by the nova-core driver.
Signed-off-by: Alexandre Courbot <acourbot at nvidia.com>
---
rust/kernel/num.rs | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/rust/kernel/num.rs b/rust/kernel/num.rs
index
ee0f67ad1a89e69f5f8d2077eba5541b472e7d8a..934afe17719f789c569dbd54534adc2e26fe59f2
100644
--- a/rust/kernel/num.rs
+++ b/rust/kernel/num.rs
@@ -171,3 +171,34 @@ fn borrow(&self) -> &T {
&self.0
}
}
+
+macro_rules! impl_fls {
+ ($($t:ty),+) => {
+ $(
+ ::kernel::macros::paste! {
+ /// Find Last Set Bit: return the 1-based index of the last (i.e.
most significant) set
+ /// bit in `v`.
+ ///
+ /// Equivalent to the C `fls` function.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use kernel::num::fls_u32;
+ ///
+ /// assert_eq!(fls_u32(0x0), 0);
+ /// assert_eq!(fls_u32(0x1), 1);
+ /// assert_eq!(fls_u32(0x10), 5);
+ /// assert_eq!(fls_u32(0xffff), 16);
+ /// assert_eq!(fls_u32(0x8000_0000), 32);
+ /// ```
+ #[inline(always)]
+ pub const fn [<fls_ $t>](v: $t) -> u32 {
+ $t::BITS - v.leading_zeros()
+ }
+ }
+ )+
+ };
+}
+
+impl_fls!(usize, u8, u16, u32, u64, u128);
--
2.49.0
On Thu Jun 12, 2025 at 4:01 PM CEST, Alexandre Courbot wrote:> Add an equivalent to the `fls` (Find Last Set bit) C function to Rust > unsigned types.Have you tried to upstream this?> It is to be first used by the nova-core driver. > > Signed-off-by: Alexandre Courbot <acourbot at nvidia.com> > --- > rust/kernel/num.rs | 31 +++++++++++++++++++++++++++++++ > 1 file changed, 31 insertions(+) > > diff --git a/rust/kernel/num.rs b/rust/kernel/num.rs > index ee0f67ad1a89e69f5f8d2077eba5541b472e7d8a..934afe17719f789c569dbd54534adc2e26fe59f2 100644 > --- a/rust/kernel/num.rs > +++ b/rust/kernel/num.rs > @@ -171,3 +171,34 @@ fn borrow(&self) -> &T { > &self.0 > } > } > + > +macro_rules! impl_fls { > + ($($t:ty),+) => { > + $( > + ::kernel::macros::paste! { > + /// Find Last Set Bit: return the 1-based index of the last (i.e. most significant) set > + /// bit in `v`. > + /// > + /// Equivalent to the C `fls` function. > + /// > + /// # Examples > + /// > + /// ``` > + /// use kernel::num::fls_u32; > + /// > + /// assert_eq!(fls_u32(0x0), 0); > + /// assert_eq!(fls_u32(0x1), 1); > + /// assert_eq!(fls_u32(0x10), 5); > + /// assert_eq!(fls_u32(0xffff), 16); > + /// assert_eq!(fls_u32(0x8000_0000), 32); > + /// ``` > + #[inline(always)] > + pub const fn [<fls_ $t>](v: $t) -> u32 {Can we name this `find_last_set_bit_ $t`? When the upstream function lands, we should also rename this one. --- Cheers, Benno> + $t::BITS - v.leading_zeros() > + } > + } > + )+ > + }; > +} > + > +impl_fls!(usize, u8, u16, u32, u64, u128);
On Thu, Jun 12, 2025 at 4:02?PM Alexandre Courbot <acourbot at nvidia.com> wrote:> > + /// ``` > + /// use kernel::num::fls_u32; > + /// > + /// assert_eq!(fls_u32(0x0), 0); > + /// assert_eq!(fls_u32(0x1), 1); > + /// assert_eq!(fls_u32(0x10), 5); > + /// assert_eq!(fls_u32(0xffff), 16); > + /// assert_eq!(fls_u32(0x8000_0000), 32); > + /// ```For a future patch series: this could provide examples per type (passing them in the `impl_fls!` call). I can create a good first issue if this lands and it is not somewhere already. Cheers, Miguel
Alexandre Courbot
2025-Jun-15 10:51 UTC
[PATCH v5 05/23] rust: num: add the `fls` operation
On Sun Jun 15, 2025 at 6:37 PM JST, Miguel Ojeda wrote:> On Thu, Jun 12, 2025 at 4:02?PM Alexandre Courbot <acourbot at nvidia.com> wrote: >> >> + /// ``` >> + /// use kernel::num::fls_u32; >> + /// >> + /// assert_eq!(fls_u32(0x0), 0); >> + /// assert_eq!(fls_u32(0x1), 1); >> + /// assert_eq!(fls_u32(0x10), 5); >> + /// assert_eq!(fls_u32(0xffff), 16); >> + /// assert_eq!(fls_u32(0x8000_0000), 32); >> + /// ``` > > For a future patch series: this could provide examples per type > (passing them in the `impl_fls!` call). > > I can create a good first issue if this lands and it is not somewhere already.I was worried that the examples would be mostly duplicated, although it is true that seeing how the function behaves at the limits of each type is valuable. I'll prepare a patch to either squash for v6 or submit as a follow-up.