This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Help with SH2E -O2 instruction ordering with volatile
- From: Oleg Endo <oleg dot endo at t-online dot de>
- To: Alex Brown <alex dot g dot brown at gmail dot com>, gcc-help at gcc dot gnu dot org
- Date: Sun, 20 Dec 2015 15:18:32 +0900
- Subject: Re: Help with SH2E -O2 instruction ordering with volatile
- Authentication-results: sourceware.org; auth=none
- References: <CAB-RZVTLmhdvvqXDHxBc_qAz2Nnm7mRrwHJU6Df8S4HOxxqaaw at mail dot gmail dot com>
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