This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bitfields


On Sun, 20 Sep 2009, Joseph S. Myers wrote:

> On Sun, 20 Sep 2009, Zoltán Kócsi wrote:
>
> > I wonder if there would be at least a theoretical support by the
> > developers to a proposal for volatile bitfields:
>
> It has been proposed (and not rejected, but not yet implemented) that
> volatile bit-fields should follow the ARM EABI specification (on all
> targets); that certainly seems better than inventing something new unless
> you have a very good reason to prefer the something new on some targets.

Yes, that discussion was that made me thinking and suggesting this
*before* the ARM EABI gets implemented. I don't suggest to implement
something instead of the ARM EABI, I suggest to implement something on top
of it. The suggested behaviour is also architecture-neutral.

It is nothing more than if the user expressly asks the compiler to break
the standard in a particular way, then the compiler does so. The breaking
of the standard is at one single point. The ARM EABI spec clearly states
that bitfield operations are never to be combined, not even in the case
where consecutive bitfield assignments refer to bitfields located in the
same machine word. My suggestion was that if a new command line switch is
present, then in the special case of consecutive bitfield assignments
being made to fields within the same word and the assignments being
separated by the comma operator, then the compiler combines those
assignments. The rationale of such behaviour is writing low-level code
dealing with HW registers. To have a practical example, let's have a SoC
chip with multi-function pins. Let's assume that we have a register that
has 2 bits for each actual pin and the value of the 2 bits selects the
actual function for the pin; a 32 bit register can thus control 16 pins.
Now if you want to, say, assign 4 pins to the SPI interface, without
bitfields you would (and indeed do) write something along these lines:

temp = *pin_control_reg;
temp &= ~(PIN_03_MASK | PIN_04_MASK | PIN_05_MASK | PIN_06_MASK);
temp |= PIN_O3_MISO | PIN_04_MOSI | PIN_05_SCLK | PIN_06_SSEL;
*pin_ctrl_reg = temp;

You can't really use bitfields to achieve the above, because if you write

pin_control_reg->pin_03 = MISO;
pin_control_reg->pin_04 = MOSI;

and so on, pin_xx being 2-bit wide bitfields, then according to the ARM
EABI spec each statement would be translated to a temp = *pin_contorl_reg;
temp &=...; temp |=...;  *pin_control_reg=temp; sequence. What I suggest
is that if you write

pin_control_reg->pin_03 = MISO,	// Note the comma
pin_control_reg->pin_04 = MOSI,
pin_control_reg->pin_05 = SCLK,
pin_control_reg->pin_06 = SSEL;

and compile it with a -fcomma-combines-bitfields switch, then you get the
equivalent of the first code fragment where you manually combined the
masks and the settings and only a single load and a single store was used.

If the switch is not given or the consecutive assignments are not
separated by commas or the bitfields do not belong to the same word, then
the behaviour falls back to the default ARM EABI spec.

The advantage of the suggested behaviour is that it would allow the use of
the more elegant and expressive bitfields in place of the many hundreds of
#define REGNAME_FIELDNAME_MASK and #define REGNAME_FIELDNAME_SHIFT macros
that you can currently find in code that deals with HW. The suggestion
does not introduce any new functionality or performance advantage, it just
provides a way of writing (in my opinion) more readable and more
maintainable code than what we have now with all the #defines. The fact
that structure members live in their own namespace as opposed to the
global #define namespace is an added benefit, of course.

The suggested extension does not break backward compatibility, because the
#define stuff would not be affected and the ARM EABI is not yet
implemented anyway; it would not break the expected behaviour because it
becomes active only when an explicite command line switch is given and has
no side-effects outside the single expression where the subexpressions are
separated by commas.

The change, I believe, would benefit gcc users who deal with HW a lot,
i.e. low level embedded system and device driver designers. Outside of
that circle the suggested behavior would have only a little performance
benefit.

Zoltan


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]