Bug 35624 - ARM embeded assembly result error
Summary: ARM embeded assembly result error
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 4.1.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-03-18 09:03 UTC by wang qiang
Modified: 2008-12-16 17:39 UTC (History)
1 user (show)

See Also:
Host: CentOS release 4.6 (Final)(Kernel 2.6.9-67.ELsmp on an i686)
Target: arm-elf
Build: ./configure --target=arm-elf --prefix=/rdisk1/users/wangqiang/to
Known to work:
Known to fail:
Last reconfirmed:


Attachments
C source code (197 bytes, text/plain)
2008-03-18 09:29 UTC, wang qiang
Details

Note You need to log in before you can comment on or make changes to this bug.
Description wang qiang 2008-03-18 09:03:41 UTC
command is as below.

arm-elf-gcc -v -save-temps -O2 -ffreestanding -c -msoft-float -nostdinc test.c

Using built-in specs.
Target: arm-elf
Configured with: ./configure --target=arm-elf --prefix=/rdisk1/users/wangqiang/tool-chain --enable-interwork --enable-multilib --with-float=soft --enable-languages=c,c++ --with-newlib --with-headers=/rdisk1/users/wangqiang/software/src/newlib-1.14.0/newlib/libc/include
Thread model: single
gcc version 4.1.1
 /rdisk5/xgsoc/ExDB/ARM/ARM_GCC/tool-chain/bin/../libexec/gcc/arm-elf/4.1.1/cc1 -E -quiet -nostdinc -v -iprefix /rdisk5/xgsoc/ExDB/ARM/ARM_GCC/tool-chain/bin/../lib/gcc/arm-elf/4.1.1/ -D__USES_INITFINI__ test.c -msoft-float -ffreestanding -O2 -fpch-preprocess -o test.i
#include "..." search starts here:
#include <...> search starts here:
End of search list.
 /rdisk5/xgsoc/ExDB/ARM/ARM_GCC/tool-chain/bin/../libexec/gcc/arm-elf/4.1.1/cc1 -fpreprocessed test.i -quiet -dumpbase test.c -msoft-float -auxbase test -O2 -version -ffreestanding -o test.s
GNU C version 4.1.1 (arm-elf)
        compiled by GNU C version 2.96 20000731 (Red Hat Linux 7.3 2.96-113).
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 3cdb4d57ef011d2fa661601e3cf86274
 /rdisk5/xgsoc/ExDB/ARM/ARM_GCC/tool-chain/bin/../lib/gcc/arm-elf/4.1.1/../../../../arm-elf/bin/as -mfloat-abi=soft -o test.o test.s

Source Code is as below.
test.c
#define burst_copy(dst,src,len) {\
  __asm__ __volatile__ ( \
 "1: \n\t" \
   "ldmia %1!,{r3-r6} \n\t" \
   "stmia %0!,{r3-r6} \n\t" \
   "subs %2, %2, #1 \n\t" \
   "bne 1b \n\t" \
   ::"r"(dst),"r"(src),"r"(len) \
   :"r3","r4","r5","r6"); \
}

int main() {
  burst_copy(0xFFFF0000,0xC0000000,0x8);
  burst_copy(0xFFFF2000,0xFFFF0000,0x8);
}

Problem:
the destination of first burst_copy is the source of the second.

but source of the second burst_copy will use the result of first,as 
0xFFFF0080,and no the Address(0xFFFF0000) I surposed to.
Comment 1 wang qiang 2008-03-18 09:29:34 UTC
Created attachment 15341 [details]
C source code
Comment 2 Hans-Peter Nilsson 2008-03-19 05:04:40 UTC
You're updating the source and destination register but marking them only as input in the asm. That's invalid.  You trick GCC into believing that as it hasn't changed, it can re-use the register with the source-address.
Comment 3 wang qiang 2008-03-21 09:33:38 UTC
I modified the source as below.
It seems that It does not work.
I am not sure whether it is a bug.Or gcc can not treat this situation?
// copy 128 bit one time
 #define burst_copy(dst,src,len) {\
   __asm__ __volatile__ ( \
 "1: \n\t" \
   "ldmia %1!,{r3-r6} \n\t" \
   "stmia %0!,{r3-r6} \n\t" \
   "subs %2, %2, #1 \n\t" \
   "bne 1b \n\t" \
   ::"r"(dst),"r"(src),"r"(len) \
   :"%0", "%1" , "%2","r3","r4","r5","r6" ); \
 }

Comment 4 Richard Earnshaw 2008-12-16 17:39:45 UTC
Not a bug.  You need to write your macro like this:

#define burst_copy(dst,src,len) {\
  unsigned t1, t2, t3; \
  __asm__ __volatile__ ( \
 "1: \n\t" \
   "ldmia %1!,{r3-r6} \n\t" \
   "stmia %0!,{r3-r6} \n\t" \
   "subs %2, %2, #1 \n\t" \
   "bne 1b \n\t" \
   :"=r"(t1),"=r"(t2),"=r"(t3) \
   :"0"(dst),"1"(src),"2"(len) \
   :"r3","r4","r5","r6", "memory"); \
}

Note that the results are never used, but this informs the compiler that the input values have been destroyed by the operation.  Also note the clobber of "memory" to indicate that values in memory have been updated by the operation.

It might be better to use an inline function for this rather than a macro, then you can use the input operands as your output operands and don't need to declare the temporaries.   It would also give better error checking in some circumstances.