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