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

Re: Help with SH2E -O2 instruction ordering with volatile


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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]