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: Inlined assembly instruction pushed out of loop in GCC 4.4.1/ARM


Simon Kagstrom wrote:
> Hi!
> 
> I'm having a compile issue with the Linux kernel for ARM and GCC 4.4.1
> (also occurs in 4.3.3 at least). The code (from orion_nand.c in the
> Linux kernel, cooked down) looks like this:
> 
>   void *vobb = (void*)0x12345678;
> 
>   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));

> GCC is built with crosstool-ng and is called like this:
> 
>   arm-unknown-linux-gnueabi-gcc -mcpu=arm926ej-s -c tst.c -o /tmp/tst.o -Os
> 
> the problem does not occur without optimization, but with any -O level.
> It can be solved by making the inline asm statement volatile, but the
> Linux developers are not happy with that change:
> 
>   http://lists.infradead.org/pipermail/linux-mtd/2009-July/026399.html
> 
> 
> Now, I'm not sure that the inline assembly is completely correct
> either. The ldrd instruction
> 
>   http://infocenter.arm.com/help/topic/com.arm.doc.ddi0290g/Chddeedh.html
> 
> requires that the destination register should be even (I presume since
> it puts the result in a register pair), and maybe that should be
> encoded in the output operand constraints? At least GCC 3.4.4 gives me
> 
>   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.

Andrew.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]