RE: [PATCH 6.12.y-cip 02/11] bitfield: Add non-constant field_{prep,get}() helpers
Biju Das <[email protected]>
| Newsgroups | org.cip-project.lists.cip-dev |
|---|---|
| Message-ID | <TY3PR01MB11346232C8A98EE9BADE0E9CB86F72@TY3PR01MB11346.jpnprd01.prod.outlook.com> |
I believe you get build warning duplicate definitions [1] https://lore.kernel.org/cip-dev/177941154371.3955.14567547508285219672@330cfa3079ca/ Cheers, Biju > -----Original Message----- > From: Lad Prabhakar <[email protected]> > Sent: 29 June 2026 23:53 > To: [email protected]; Nobuhiro Iwamatsu <[email protected]>; Pavel Machek > <[email protected]> > Cc: Biju Das <[email protected]> > Subject: [PATCH 6.12.y-cip 02/11] bitfield: Add non-constant field_{prep,get}() helpers > > From: Geert Uytterhoeven <[email protected]> > > commit c1c6ab80b25c8db1e2ef5ae3ac8075d2c242ae13 upstream. > > The existing FIELD_{GET,PREP}() macros are limited to compile-time constants. However, it is very common > to prepare or extract bitfield elements where the bitfield mask is not a compile-time constant. > > To avoid this limitation, the AT91 clock driver and several other drivers already have their own non- > const field_{prep,get}() macros. > Make them available for general use by adding them to <linux/bitfield.h>, and improve them slightly: > 1. Avoid evaluating macro parameters more than once, > 2. Replace "ffs() - 1" by "__ffs()", > 3. Support 64-bit use on 32-bit architectures, > 4. Wire field_{get,prep}() to FIELD_{GET,PREP}() when mask is > actually constant. > > This is deliberately not merged into the existing FIELD_{GET,PREP}() macros, as people expressed the > desire to keep stricter variants for increased safety, or for performance critical paths. > > Yury: use __mask withing new macros. > > Signed-off-by: Geert Uytterhoeven <[email protected]> > Acked-by: Alexandre Belloni <[email protected]> > Acked-by: Jonathan Cameron <[email protected]> > Acked-by: Crt Mori <[email protected]> > Acked-by: Nuno Sá <[email protected]> > Acked-by: Richard Genoud <[email protected]> > Reviewed-by: Andy Shevchenko <[email protected]> > Reviewed-by: Yury Norov (NVIDIA) <[email protected]> > Signed-off-by: Yury Norov (NVIDIA) <[email protected]> > Signed-off-by: Lad Prabhakar <[email protected]> > --- > include/linux/bitfield.h | 59 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 59 insertions(+) > > diff --git a/include/linux/bitfield.h b/include/linux/bitfield.h index 3346c6009c2ce..22bbef382bb9c > 100644 > --- a/include/linux/bitfield.h > +++ b/include/linux/bitfield.h > @@ -17,6 +17,7 @@ > * FIELD_{GET,PREP} macros take as first parameter shifted mask > * from which they extract the base mask and shift amount. > * Mask must be a compilation time constant. > + * field_{get,prep} are variants that take a non-const mask. > * > * Example: > * > @@ -240,4 +241,62 @@ __MAKE_OP(64) > #undef __MAKE_OP > #undef ____MAKE_OP > > +#define __field_prep(mask, val) \ > + ({ \ > + __auto_type __mask = (mask); \ > + typeof(__mask) __val = (val); \ > + unsigned int __shift = BITS_PER_TYPE(__mask) <= 32 ? \ > + __ffs(__mask) : __ffs64(__mask); \ > + (__val << __shift) & __mask; \ > + }) > + > +#define __field_get(mask, reg) \ > + ({ \ > + __auto_type __mask = (mask); \ > + typeof(__mask) __reg = (reg); \ > + unsigned int __shift = BITS_PER_TYPE(__mask) <= 32 ? \ > + __ffs(__mask) : __ffs64(__mask); \ > + (__reg & __mask) >> __shift; \ > + }) > + > +/** > + * field_prep() - prepare a bitfield element > + * @mask: shifted mask defining the field's length and position, must be > + * non-zero > + * @val: value to put in the field > + * > + * Return: field value masked and shifted to its final destination > + * > + * field_prep() masks and shifts up the value. The result should be > + * combined with other fields of the bitfield using logical OR. > + * Unlike FIELD_PREP(), @mask is not limited to a compile-time constant. > + * Typical usage patterns are a value stored in a table, or calculated > +by > + * shifting a constant by a variable number of bits. > + * If you want to ensure that @mask is a compile-time constant, please > +use > + * FIELD_PREP() directly instead. > + */ > +#define field_prep(mask, val) \ > + (__builtin_constant_p(mask) ? __FIELD_PREP(mask, val, "field_prep: ") \ > + : __field_prep(mask, val)) > + > +/** > + * field_get() - extract a bitfield element > + * @mask: shifted mask defining the field's length and position, must be > + * non-zero > + * @reg: value of entire bitfield > + * > + * Return: extracted field value > + * > + * field_get() extracts the field specified by @mask from the > + * bitfield passed in as @reg by masking and shifting it down. > + * Unlike FIELD_GET(), @mask is not limited to a compile-time constant. > + * Typical usage patterns are a value stored in a table, or calculated > +by > + * shifting a constant by a variable number of bits. > + * If you want to ensure that @mask is a compile-time constant, please > +use > + * FIELD_GET() directly instead. > + */ > +#define field_get(mask, reg) \ > + (__builtin_constant_p(mask) ? __FIELD_GET(mask, reg, "field_get: ") \ > + : __field_get(mask, reg)) > + > #endif > -- > 2.43.0