Thread (35 messages) flat view 35 messages, 6 authors, 2025-12-11

Re: [PATCH 0/9] bitfield: tidy up bitfield.h

From: David Laight <hidden>
Date: 2025-12-11 10:51:12
Also in: linux-usb, lkml

On Wed, 10 Dec 2025 13:20:16 -0500
Yury Norov [off-list ref] wrote:
On Tue, Dec 09, 2025 at 10:03:04AM +0000, david.laight.linux@gmail.com wrote:
quoted
From: David Laight <redacted>
...
quoted
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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help