Re: Help with SH2E -O2 instruction ordering with volatile

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 2015-12-20 at 15:41 +1100, Alex Brown 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 ?

It's not entirely clear what you think is wrong with the code...

Your original code looks a bit strange.  You can't cast an "char
text[2]" to an "unsigned int".  What you're actually casting to
"unsigned int" there is a "char*", and that's what the code does.  It
stores the address of the text array on the stack into peripheral.e. 
 And it does so as you've specified between the calls to lock/unlock.

Probably what you want to do is:

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 int*)text;
  unlock();
}

But that's just my speculation.  What exactly do you think is wrong in
the generated code?

Cheers,
Oleg



[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux