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
_______________________________________________
coreboot mailing list -- coreboot@coreboot.org
To unsubscribe send an email to coreboot-le...@coreboot.org

Reply via email to