Hi, Thanks for that. I was trying to avoid using a memory barrier (ever time I write non portable code, I shed a small tear), but I am guessing that because I only access the address of the text variable, rather than the value, GCC can't know that it needs to fill in the values before the assignment ? Cheers Alex On Sun, Dec 20, 2015 at 6:28 PM, Oleg Endo <oleg.endo@xxxxxxxxxxx> wrote: > On Sun, 2015-12-20 at 06:41 +0000, Alex Brown wrote: > >> I know the code is somewhat weird ;-) >> >> Basically peripheral.e wants the address of a null terminated string >> (not the char value). >> >> My "platform/emulator" will use DMA to extract the string from RAM >> before the next instruction is executed. >> >> The issue is that at the time the address is assigned to peripheral.e >> is seems the values of the text array have not yet been written to >> the stack (or that's what I thing I am seeing). >> >> Making "text" volatile makes it output code that makes sense to me. > > Ah, that's the other thing I thought you might mean. It seems that the > same reordering happens on other architectures, too. So this is not > exactly SH specific. > > Just because "peripheral" is volatile doesn't mean that all the loads > and stores around it automatically become volatile. The compiler > doesn't know that there is some transitivity going on. > > Depending on your DMA circumstances, you might need a bit more than > that. For example the below code seems to do what you'd want in this > case: > > #define memory_barrier() do { asm volatile ("" : : : "memory"); } while (0) > > void > update(unsigned a, int x, int y, char c, unsigned color, unsigned char size) > { > lock(); > char text[2] = { c, 0}; > peripheral.a = a; > peripheral.b = x; > peripheral.c = y; > peripheral.d = color; > > memory_barrier (); > > peripheral.e = (unsigned)text; > > unlock(); > } > > Cheers, > Oleg