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

[Bug rtl-optimization/49807] Missed byte (subreg) extraction when storing to volatile mem


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49807

--- Comment #2 from Eric Weddington <eric.weddington at atmel dot com> 2011-07-21 20:12:58 UTC ---
(In reply to comment #0)
> This C source:
> 
> #define SPDR (*((char volatile*) 0x2c))

Hi Johann,

That's not quite correct. In avr-libc the header file sfr_defs.h will define a
register as this:

#define SPDR (*((volatile char *) 0x2c))

It's a pointer to a volatile char, not a volatile pointer to a char.

> Changing the source like
> 
> #define SPDR0 (*((char*) 0x2c))
> #define SPDR1 (*((char*) 0x2d))
> #define SPDR2 (*((char*) 0x2e))
> #define SPDR3 (*((char*) 0x2f))
> 
> void read_adc (long big)
> { 
>    SPDR0 = big >> 24;
>    SPDR1 = big >> 16;
>    SPDR2 = big >> 8;
>    SPDR3 = big;
> }
> 
> 
> and it compiles fine:

Is your intent to change the address AND remove the volatile keyword? If you
want to test if it's the volatile keyword that is the cause then you should
only change that part:

#define SPDR (*((char *) 0x2c))

void read_adc (long big)
{ 
   SPDR = big >> 24;
   SPDR = big >> 16;
   SPDR = big >> 8;
   SPDR = big;
}


Overall, though, I think you're on the right track. Most users would like to be
able to do the shift-and-assign pattern in C and have it compile to storing the
individual byte without a shift in the assembly. Right now, the only way to do
a workaround to achieve that result is through the use of a union with a struct
and an integer type (like a long). If this issue can be fixed then I think that
this has a chance to reduce a lot of code size problems.


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