Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bitfield: add FIELD_PREP_CONST()

Neither FIELD_PREP() nor *_encode_bits() can be used
in constant contexts (such as initializers), but we
don't want to define shift constants for all masks
just for use in initializers, and having checks that
the values fit is also useful.

Therefore, add FIELD_PREP_CONST() which is a smaller
version of FIELD_PREP() that can only take constant
arguments and has less friendly (but not less strict)
error checks, and expands to a constant value.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Link: https://lore.kernel.org/r/20230118142652.53f20593504b.Iaeea0aee77a6493d70e573b4aa55c91c00e01e4b@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

+26
+26
include/linux/bitfield.h
··· 115 115 ((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask); \ 116 116 }) 117 117 118 + #define __BF_CHECK_POW2(n) BUILD_BUG_ON_ZERO(((n) & ((n) - 1)) != 0) 119 + 120 + /** 121 + * FIELD_PREP_CONST() - prepare a constant bitfield element 122 + * @_mask: shifted mask defining the field's length and position 123 + * @_val: value to put in the field 124 + * 125 + * FIELD_PREP_CONST() masks and shifts up the value. The result should 126 + * be combined with other fields of the bitfield using logical OR. 127 + * 128 + * Unlike FIELD_PREP() this is a constant expression and can therefore 129 + * be used in initializers. Error checking is less comfortable for this 130 + * version, and non-constant masks cannot be used. 131 + */ 132 + #define FIELD_PREP_CONST(_mask, _val) \ 133 + ( \ 134 + /* mask must be non-zero */ \ 135 + BUILD_BUG_ON_ZERO((_mask) == 0) + \ 136 + /* check if value fits */ \ 137 + BUILD_BUG_ON_ZERO(~((_mask) >> __bf_shf(_mask)) & (_val)) + \ 138 + /* check if mask is contiguous */ \ 139 + __BF_CHECK_POW2((_mask) + (1ULL << __bf_shf(_mask))) + \ 140 + /* and create the value */ \ 141 + (((typeof(_mask))(_val) << __bf_shf(_mask)) & (_mask)) \ 142 + ) 143 + 118 144 /** 119 145 * FIELD_GET() - extract a bitfield element 120 146 * @_mask: shifted mask defining the field's length and position