Hi list,
Since register fields usually have more than one bit, I prefer to always use explicit shifts for consistency. The one case where I prefer the BIT() macro is to reduce the amount of nested braces when testing for individual bits in a mask. GCC encourages adding unnecessary braces for expressions such as `1 << x + 3`, so it's easy to end up with five levels of brace nesting in a single expression.
For silicon-specific code where portability isn't an issue (different hardware, different registers) and there's lots of hardware registers with multiple fields each, I prefer to use bitfield structs. The resulting code is rather verbose because it provides more information to both humans and compilers, so there can be less comments that can eventually become lies. This approach also prevents making certain kinds of mistakes, e.g. using the names from a different register or using too large constants in initializers, both of which will cause a build failure. This also avoids compiler woes when using bitwise negations in functions taking an AND-mask, where values get promoted to signed int and then need to be truncated to a smaller size unsigned type. Refer to https://review.coreboot.org/42134 for a more detailed explanation of the issue. When using bitfield structs, updating the value in a register field involves three discrete steps: read the register into a local variable, then assign the new value to the desired field (or fields), and finally write the updated value back. This is substantially more verbose, but it's also harder to make a dumb mistake such as forgetting to negate a mask.
Best regards, Angel