Merging changes to volatile bitfield structs

Phil Endecott spam_from_gcc_help_2@chezphil.org
Tue Oct 16 11:23:00 GMT 2007


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.






More information about the Gcc-help mailing list