This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Inlined assembly instruction pushed out of loop in GCC 4.4.1/ARM
Andrew Haley wrote:
> 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.
Ignore this comment. The problem gcc has with this asm is that it
doesn't read from memory and it doesn't have any side-effects.
volatile is the right answer, along with the other changes. The
right answer is:
while (i < len/8) {
uint64_t x;
asm volatile ("ldrd\t%0, [%1]" : "=&r" (x) : "r" (io_base) : "memory");
buf64[i++] = x;
Andrew.