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: types vs modes?


DJ Delorie <dj@redhat.com> writes:

> So... can I/we move forward on this?  Or will such a change be
> rejected?
>
> BTW, Since sending this I discovered that gcc treats these
> differently wrt TARGET_NARROW_VOLATILE_BITFIELD:
>
> volatile struct
> {
>   unsigned int a:8;
>   unsigned int b:24;
> } t1;
>
> volatile struct
> {
>   unsigned int a:7;
>   unsigned int b:25;
> } t2;
>
> t1.a will be accessed as a byte regardless of the target's
> preferences, whereas t2.c follows the target preferences.
>
>> One of our customers has a chip with memory-mapped peripheral
>> registers that need to be accessed in a specific mode.  The registers
>> represent bitfields within the hardware, so a volatile struct is an
>> obvious choice to represent them in C.
>> 
>> However, gcc has a very simplistic heuristic for deciding what mode to
>> use to access bitfields in structures - it uses either the biggest or
>> smallest mode practical.  This offers the programmer no way to tell
>> gcc what mode the accesses need to be in, aside from manually
>> reading/writing memory with integer types and casting.
>> 
>> Options?  My thought, after some internal discussion, is that (if the
>> target chooses) we allow gcc to honor the type of a volatile bitfield
>> as the mode as long as it can do so without otherwise violating the
>> structure's layout.  Some new hook will be needed for the backend, and
>> perhaps a -W option for when the type cannot be honored.
>> 
>> I.e. if the programmer is careful enough to properly lay out the
>> struct, the programmer should get what the programmer asks for.
>> 
>> Comments?  Alternatives?


It's hard for me to get excited about something like this.  It's
straightforward a programmer to write code that is clearly correct in
this sort of situation: just don't use a bitfield.  gcc doesn't even
document the order of bits in a bitfield, so it's generally difficult to
reliably use bitfields to access memory mapped registers.  If this were
my customer, I would tell them to write inline functions which access
the data as integers of the appropriate size and do the required
shifting and masking.  That code only has to be written once, it will be
just as efficient as the code generated by using a volatile bitfield
struct, and it will be clearly correct with any reasonable compiler.

A volatile bitfield is a dubious construct all by itself.  The volatile
qualifier is supposed to direct the compiler to act exactly like the
virtual machine.  But what does the virtual machine do on an assignment
to a volatile bitfield?  Many real machines must read the value, change
some bits, and then write the value back.  Is that following the virtual
machine or not?  Is the volatile qualifier misleading in such a case?

In any case, while I recommend against it, I won't stop you if you
really want to follow your proposal.  The most important thing for this
approach would be the documentation, so write that first.  Your brief
description above is insufficient; I'm not sure what you mean by
"without otherwise violating the structure's layout," and I don't know
why you might need a -W option.  Then, of course, you will need a fairly
complete set of test cases.


I want to say that I think that this comment:

>> I.e. if the programmer is careful enough to properly lay out the
>> struct, the programmer should get what the programmer asks for.

is misleading.  When I give a type to a bitfield, I don't think I am
asking for the bitfield to be accessed in that type.  It's not a case of
the programmer getting what he or she asks for; it's a case of the
programmer wants to define a specific set of semantics to bitfields, a
language construct which can provide a range of different semantics.

Ian


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