This is the mail archive of the gcc-help@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]

Merging changes to volatile bitfield structs


Dear Experts,

I have a volatile bitfield struct that corresponds to a hardware register. When I modify single fields, gcc generates read-modify-write cycles. This is great.

However, sometimes I want to modify several fields at the same time:

  reg.a = 0;
  reg.b = 0;
  reg.c = 0;
  ...

In this case, gcc generates a long series of read-modify-write operations changing each field in turn. This is OK, but it would use much less code and be equally correct to do all of the changes in a single read-modify-write.

Essentially the problem is that "volatile" is _too_ volatile in this case. What can I do about it? One option is to not use the bitfield syntax, i.e. declare reg as a volatile int* and write

*reg &=~ 0x00fffff0;

or whatever. This has the disadvantage of being much less clear. It would be great if I could write

reg = { .a=0, .b=0, .c=0 };

and something like that might even be valid, if I wanted to set ALL of the fields; but I don't think I can selectively change just some of the fields like that (can I?).

So maybe I need to not declare it as volatile, and use some sort of "memory barrier". That's a term that I have heard used but don't really understand. But borrowing database terminology, how about

  BEGIN
    reg.a = 0;
    reg.b = 0;
    reg.c = 0;
  COMMIT

Can anyone share their preferred approach to this sort of problem?


Many thanks in advance for any advice.


Regards, Phil.





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