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: Alex Brown <alex dot g dot brown at gmail dot com>
- To: gcc-help at gcc dot gnu dot org
- Date: Sun, 20 Dec 2015 18:14:55 +1100
- 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>
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();
> }
>