.../netronome/nfp/nfpcore/nfp_nsp_eth.c | 16 +- drivers/thunderbolt/tb.h | 2 +- include/linux/bitfield.h | 278 ++++++++++-------- include/linux/hw_bitfield.h | 17 +- 4 files changed, 166 insertions(+), 147 deletions(-)
From: David Laight <david.laight.linux@gmail.com> Re-send with patches going to everyone. (I'd forgotten I'd set 'ccCover = 0'.) I noticed some very long (18KB) error messages from the compiler. Turned out they were errors on lines that passed GENMASK() to FIELD_PREP(). Since most of the #defines are already statement functions the values can be copied to locals so the actual parameters only get expanded once. The 'bloat' is reduced further by using a simple test to ensure 'reg' is large enough, slightly simplifying the test for constant 'val' and only checking 'reg' and 'val' when the parameters are present. The first two patches are slightly problematic. drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c manages to use a #define that should be an internal to bitfield.h, the changed file is actually more similar to the previous version. drivers/thunderbolt/tb.h passes a bifield to FIELD_GET(), these can't be used with sizeof or __auto_type. The usual solution is to add zero, but that can't be done in FIELD_GET() because it doesn't want the value promoted to 'int' (no idea how _Generic() treated it.) The fix is just to add zero at the call site. (The bitfield seems to be in a structure rad from hardware - no idea how that works on BE (or any LE that uses an unusual order for bitfields.) Both changes may need to to through the same tree as the header file changes. The changes are based on 'next' and contain the addition of field_prep() and field_get() for non-constant values. I also know it is the merge window. I expect to be generating a v2 in the new year (someone always has a comment). David Laight (9): nfp: Call FIELD_PREP() in NFP_ETH_SET_BIT_CONFIG() wrapper thunderblot: Don't pass a bitfield to FIELD_GET bitmap: Use FIELD_PREP() in expansion of FIELD_PREP_WM16() bitfield: Copy #define parameters to locals bitfield: FIELD_MODIFY: Only do a single read/write on the target bitfield: Update sanity checks bitfield: Reduce indentation bitfield: Add comment block for the host/fixed endian functions bitfield: Update comments for le/be functions .../netronome/nfp/nfpcore/nfp_nsp_eth.c | 16 +- drivers/thunderbolt/tb.h | 2 +- include/linux/bitfield.h | 278 ++++++++++-------- include/linux/hw_bitfield.h | 17 +- 4 files changed, 166 insertions(+), 147 deletions(-) -- 2.39.5
On Tue, Dec 09, 2025 at 10:03:04AM +0000, david.laight.linux@gmail.com wrote: > From: David Laight <david.laight.linux@gmail.com> > > Re-send with patches going to everyone. > (I'd forgotten I'd set 'ccCover = 0'.) And this one again appeared in my spambox. Have you any ideas why? > I noticed some very long (18KB) error messages from the compiler. > Turned out they were errors on lines that passed GENMASK() to FIELD_PREP(). > Since most of the #defines are already statement functions the values > can be copied to locals so the actual parameters only get expanded once. > > The 'bloat' is reduced further by using a simple test to ensure 'reg' > is large enough, slightly simplifying the test for constant 'val' and > only checking 'reg' and 'val' when the parameters are present. So, can you share the before/after? > The first two patches are slightly problematic. > > drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c manages to use > a #define that should be an internal to bitfield.h, the changed file > is actually more similar to the previous version. > > drivers/thunderbolt/tb.h passes a bifield to FIELD_GET(), these can't > be used with sizeof or __auto_type. The usual solution is to add zero, > but that can't be done in FIELD_GET() because it doesn't want the value > promoted to 'int' (no idea how _Generic() treated it.) > The fix is just to add zero at the call site. > (The bitfield seems to be in a structure rad from hardware - no idea > how that works on BE (or any LE that uses an unusual order for bitfields.) > > Both changes may need to to through the same tree as the header file changes. > > The changes are based on 'next' and contain the addition of field_prep() > and field_get() for non-constant values. > > I also know it is the merge window. > I expect to be generating a v2 in the new year (someone always has a comment). > > David Laight (9): > nfp: Call FIELD_PREP() in NFP_ETH_SET_BIT_CONFIG() wrapper > thunderblot: Don't pass a bitfield to FIELD_GET > bitmap: Use FIELD_PREP() in expansion of FIELD_PREP_WM16() > bitfield: Copy #define parameters to locals > bitfield: FIELD_MODIFY: Only do a single read/write on the target > bitfield: Update sanity checks > bitfield: Reduce indentation > bitfield: Add comment block for the host/fixed endian functions > bitfield: Update comments for le/be functions > > .../netronome/nfp/nfpcore/nfp_nsp_eth.c | 16 +- > drivers/thunderbolt/tb.h | 2 +- > include/linux/bitfield.h | 278 ++++++++++-------- > include/linux/hw_bitfield.h | 17 +- > 4 files changed, 166 insertions(+), 147 deletions(-) > > -- > 2.39.5
On Wed, 10 Dec 2025 13:20:16 -0500
Yury Norov <yury.norov@gmail.com> wrote:
> On Tue, Dec 09, 2025 at 10:03:04AM +0000, david.laight.linux@gmail.com wrote:
> > From: David Laight <david.laight.linux@gmail.com>
...
> > I noticed some very long (18KB) error messages from the compiler.
> > Turned out they were errors on lines that passed GENMASK() to FIELD_PREP().
> > Since most of the #defines are already statement functions the values
> > can be copied to locals so the actual parameters only get expanded once.
> >
> > The 'bloat' is reduced further by using a simple test to ensure 'reg'
> > is large enough, slightly simplifying the test for constant 'val' and
> > only checking 'reg' and 'val' when the parameters are present.
>
> So, can you share the before/after?
Not that hard to generate since the kernel makefiles will create foo.i
I would have fed the .i file though xargs - but someone broke it
(there is no option to ignore quotes, and -s70 isn't allowed).
So I used:
tr ' ' '\n' foo.i | (ll=; while read -r l; do ll1="$ll $l"; [ ${#l} = 0 -o ${#ll1} -ge 70 ] && { echo "$ll"; ll="$l";} || ll="$ll1"; done; echo "$ll")
GENMASK(hi, lo)
((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))
A chunk of that would be removed by changing type_max() to do
2 * (n - 1) + 1 instead of (n - 1) + n, but for unsigned types
it isn't needed.
Changing type_max(t) to (t)-1 GENMASK(hi, lo) becomes
(patch not posted...)
((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) + ((unsigned long)-1
<< (lo) & (unsigned long)-1 >> ((sizeof(unsigned long) * 8) - 1 - (hi)))))
There are still four expansions of both lo and hi - but they are
usually trivial.
You asked for this one :-)
old FIELD_GET(GENMASK(hi, lo), reg)
({ do { __attribute__((__noreturn__)) extern void
__compiletime_assert_769(void) __attribute__((__error__("FIELD_GET: "
"type of reg too small for mask"))); if (!(!(((typeof(
_Generic((((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))), char: (unsigned
char)0, unsigned char: (unsigned char)0, signed char: (unsigned
char)0, unsigned short: (unsigned short)0, signed short: (unsigned
short)0, unsigned int: (unsigned int)0, signed int: (unsigned int)0,
unsigned long: (unsigned long)0, signed long: (unsigned long)0,
unsigned long long: (unsigned long long)0, signed long long:
(unsigned long long)0, default: (((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))))))(((unsigned
long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi))))))) > ((typeof(
_Generic((reg), char: (unsigned char)0, unsigned char: (unsigned
char)0, signed char: (unsigned char)0, unsigned short: (unsigned
short)0, signed short: (unsigned short)0, unsigned int: (unsigned
int)0, signed int: (unsigned int)0, unsigned long: (unsigned long)0,
signed long: (unsigned long)0, unsigned long long: (unsigned long
long)0, signed long long: (unsigned long long)0, default:
(reg))))(~0ull))))) __compiletime_assert_769(); } while (0); ({ ({ do
{ __attribute__((__noreturn__)) extern void
__compiletime_assert_770(void) __attribute__((__error__("FIELD_GET: "
"mask is not constant"))); if (!(!(!__builtin_constant_p(((unsigned
long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))))))
__compiletime_assert_770(); } while (0); do {
__attribute__((__noreturn__)) extern void
__compiletime_assert_771(void) __attribute__((__error__("FIELD_GET: "
"mask is zero"))); if (!(!((((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) == 0)))
__compiletime_assert_771(); } while (0); do {
__attribute__((__noreturn__)) extern void
__compiletime_assert_772(void) __attribute__((__error__("FIELD_GET: "
"value too large for the field"))); if (!(!(__builtin_constant_p(0U)
? ~((((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) >>
(__builtin_ffsll(((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) - 1)) & (0 + (0U)) :
0))) __compiletime_assert_772(); } while (0); do {
__attribute__((__noreturn__)) extern void
__compiletime_assert_773(void) __attribute__((__error__("BUILD_BUG_ON
failed: " "(((((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), \"const_true((lo) > (hi))\" \" is true\");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) + (1ULL <<
(__builtin_ffsll(((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), \"const_true((lo) > (hi))\" \" is true\");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) - 1))) &
(((((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), \"const_true((lo) > (hi))\" \" is true\");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) + (1ULL <<
(__builtin_ffsll(((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), \"const_true((lo) > (hi))\" \" is true\");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) - 1))) - 1)) !=
0"))); if (!(!((((((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) + (1ULL <<
(__builtin_ffsll(((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) - 1))) &
(((((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) + (1ULL <<
(__builtin_ffsll(((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) - 1))) - 1)) != 0)))
__compiletime_assert_773(); } while (0); }); (typeof(((unsigned
long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))))(((reg) & (((unsigned
long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi))))))) >>
(__builtin_ffsll(((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi)))))) - 1)); }); })
new FIELD_GET(GENMASK(hi, lo), reg)
({ __auto_type _mask = ((unsigned long)(((int)sizeof(struct
{_Static_assert(!(__builtin_choose_expr((sizeof(int) == sizeof(*(8 ?
((void *)((long)((lo) > (hi)) * 0l)) : (int *)8))), (lo) > (hi),
false)), "const_true((lo) > (hi))" " is true");})) +
(((typeof(unsigned long))((((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))) - 1) + ((typeof(unsigned long))1 <<
(8*sizeof(typeof(unsigned long)) - 1 - (((typeof(unsigned long))(-1))
< ( typeof(unsigned long))1))))) << (lo) & ((typeof(unsigned
long))((((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long))
- 1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1))) -
1) + ((typeof(unsigned long))1 << (8*sizeof(typeof(unsigned long)) -
1 - (((typeof(unsigned long))(-1)) < ( typeof(unsigned long))1)))))
>> ((sizeof(unsigned long) * 8) - 1 - (hi))))); __auto_type _reg =
reg; ({ do { do { __attribute__((__noreturn__)) extern void
__compiletime_assert_697(void) __attribute__((__error__("FIELD_GET: "
"mask is not constant"))); if (!(!(!__builtin_constant_p(_mask))))
__compiletime_assert_697(); } while (0); do {
__attribute__((__noreturn__)) extern void
__compiletime_assert_698(void) __attribute__((__error__("FIELD_GET: "
"mask is zero or not contiguous"))); if (!(!((!(_mask) || ((_mask) &
((_mask) + ((_mask) & -(_mask)))))))) __compiletime_assert_698(); }
while (0); } while (0); do { __attribute__((__noreturn__)) extern
void __compiletime_assert_699(void)
__attribute__((__error__("FIELD_GET: " "type of reg too small for
mask"))); if (!(!(_mask + 0U + 0UL + 0ULL > ~0ULL >> (64 - 8 * sizeof
(_reg))))) __compiletime_assert_699(); } while (0); ((_reg) &
(_mask)) >> (__builtin_ffsll(_mask) - 1); }); })
David
On Wed, 10 Dec 2025 13:20:16 -0500 Yury Norov <yury.norov@gmail.com> wrote: > On Tue, Dec 09, 2025 at 10:03:04AM +0000, david.laight.linux@gmail.com wrote: > > From: David Laight <david.laight.linux@gmail.com> > > > > Re-send with patches going to everyone. > > (I'd forgotten I'd set 'ccCover = 0'.) > > And this one again appeared in my spambox. Have you any ideas why? I'm getting the copies sent to my gmail account, but gmail has a mind of its own. It bounces and spams a lot of list emails (never might the emails/minute limit that meany you only get 'some of' lkml). The email headers are a slight lie, the From: doesn't match the 'envelope from'. Basically you can't send more than 100 emails/day (count of To: and Cc:) from a 'free' gmail address, so they are sent from elsewhere (with a 500/day limit). But I don't want that address appearing in the emails - hence the subterfuge. But the 'envelope from' is correct for where the emails come from. (A test email to xxx.gmail.com with an envelope from of xxx.gmail.com sent from a different smtp server confused gmail! The mail was errored, but it sent the bounce to itself!) David
© 2016 - 2026 Red Hat, Inc.