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


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.



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