This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Issue when compiling assembly code in GCC 4.4.1 for ARM(inline issue)
- From: naveen yadav <yad dot naveen at gmail dot com>
- To: gcc-help at gcc dot gnu dot org
- Date: Tue, 31 Aug 2010 21:08:00 +0530
- Subject: Issue when compiling assembly code in GCC 4.4.1 for ARM(inline issue)
Hi All,
We are looking at an issue related to failure of arm-gcc ( version
4.4.1 ) in generating correct
assembly from inlined-asm code.
The generated assembly contains
strex r3,r3,[r2]
The corresponding iniline-asm is
" strex %2, %3, [%0];"
Its compilation fails as strex cannot have same register as first 2 operands.
/tmp/ccnJX1l7.s: Assembler messages:
/tmp/ccnJX1l7.s:36: Error: registers may not be the same -- `strex r3,r3,[r2]'
Operand %2 is specified as output and %3 is specified as input.
Compilation does pass if we also specify %2 with the additional
constraint & .That is "=&r"(t)
Is gcc not smart enough to recognise that strex cannot use same
register for both
operands ? Is this a known problem ? Note that the function where this is
used is small and is not using the rest of the ARM registers.
We tried this with arm-gcc version 4.2.0. This does
compile successfully , But the code seems to be buggy
as explained below.
The inline-asm
"ldrex %1, [%0];"
"strex %2, %3, [%0];"
has been compiled into
ldrex r2, [r3]
strex r1, r2, [r3]
So, instead of storing %3 at location %0, the code will store
back the current value that was read from the memory address %0.
The test code is given below for your reference.
void* func( volatile int* p, void* v )
{
void* o = 0;
int t;
asm volatile(
"1: ldrex %1, [%0];"
" strex %2, %3, [%0];"
" teq %2, #0;"
" bne 1b;"
:"+r"(p), "=r"(o), "=r"(t)
:"r"(v)
:"cc", "memory"
);
return o;
}
int main()
{
int v = 1;
int s = 0;
void* r = func(&s, &v);
return 0;
}
Thanks