Re: Inlined assembly instruction pushed out of loop in GCC 4.4.1/ARM

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

 



On Tue, 18 Aug 2009 15:35:22 +0100
Andrew Haley <aph@xxxxxxxxxx> wrote:

> >   void orion_nand_read_buf(uint8_t *buf, int len)
> >   {
> >   	void *io_base = vobb;
> >   	uint64_t *buf64;
> >   	int i = 0;
> > 
> >   	buf64 = (uint64_t *)buf;
> >   	while (i < len/8) {
> >   		uint64_t x;
> >   		asm ("ldrd\t%0, [%1]" : "=r" (x) : "r" (io_base));
> 
> This is wrong.  It tells gcc that an address is input to the asm and
> a uint64_t is returned.  But it doesn't tell gcc that some memory
> at io_base is being used.  So, it's legitimate to hoist the asm out
> of the loop.
> 
> Add a memory clobber and an earlyclobber:
> 
>      asm ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base));

Thanks, changing it to

  asm ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base) : "memory");

fixes the issue. I'll re-submit the patch to the kernel mailing list.

> >   Error: destination register must be even -- `ldrd r1,[r2]'
> > 
> > when compiling this code.
> 
> I think that is a bug.
> 
> > So is this a GCC bug or should I head back to the Linux people with it?
> 
> No-one here is going to fix bugs in gcc 3.4.4.  I think you'll need to
> use an explicit register variable to work round it.

Sorry, I was referring to the Linux code above, not the GCC 3.4.4 issue
I got.

// Simon

[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