Help with SH2E -O2 instruction ordering with volatile

Alex Brown alex.g.brown@gmail.com
Sun Dec 20 07:15:00 GMT 2015


Hi,

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.

Alex

On 12/20/15, Alex Brown <alex.g.brown@gmail.com> wrote:
> Hi,
>
> I have some asm being generated that I am having trouble
> understanding. The following example compiled with GCC 5.3 using -O2:
>
> typedef struct {
>     unsigned a;
>     unsigned b;
>     unsigned c;
>     unsigned d;
>     unsigned e;
> } peripheral_t;
>
> volatile peripheral_t peripheral;
>
> extern void lock() ;
> extern void unlock() ;
>
> 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;
>   peripheral.e = (unsigned)text;
>   unlock();
> }
>
> Generated code is:
>
> _update:
>         mov.l   r8,@-r15
>         mov     r6,r8
>         mov.l   r9,@-r15
>         mov     r5,r9
>         mov.l   r10,@-r15
>         mov     r4,r10
>         mov.l   r11,@-r15
>         exts.b  r7,r11              ; Move the value of "c" to r11
>         mov.l   .L3,r1
>         sts.l   pr,@-r15
>         jsr     @r1
>         add     #-4,r15
>         mov.l   .L4,r1
>         mov     #0,r0
>         mov.l   @(24,r15),r3
>         mov.l   r10,@r1
>         mov.l   r9,@(4,r1)
>         mov.l   r8,@(8,r1)
>         mov.l   r3,@(12,r1)
>         mov.l   r15,@(16,r1)   ; Move r15 to "peripheral.e"
>         mov.l   .L5,r1
>         mov.b   r11,@r15       ; Move r11 to @R15  ; text[0] = c
>         jsr     @r1
>         mov.b   r0,@(1,r15)    ; Move 0 to @R15+1  ; text[1] = 0
>         add     #4,r15
>         lds.l   @r15+,pr
>         mov.l   @r15+,r11
>         mov.l   @r15+,r10
>         mov.l   @r15+,r9
>         rts
>         mov.l   @r15+,r8
>
> I can fix this in various ways, (see below), but the question I am
> asking: is my original code wrong ?
>
> Regards
>
> Alex
>
> Working versions:
>
> void
> update(unsigned a, int x, int y, char c, unsigned color, unsigned char
> size)
> {
>   char text[2] = { c, 0};
>   lock();
>   peripheral.a = a;
>   peripheral.b = x;
>   peripheral.c = y;
>   peripheral.d = color;
>   peripheral.e = (unsigned)text;
>   unlock();
> }
>
> void
> update(unsigned a, int x, int y, char c, unsigned color, unsigned char
> size)
> {
>
>   lock();
>   volatile char text[2] = { c, 0};
>   peripheral.a = a;
>   peripheral.b = x;
>   peripheral.c = y;
>   peripheral.d = color;
>   peripheral.e = (unsigned)text;
>   unlock();
> }
>



More information about the Gcc-help mailing list