Issue when compiling assembly code in GCC 4.4.1 for ARM(inline issue)

naveen yadav
Tue Aug 31 17:11:00 GMT 2010

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)
        :"cc", "memory"
    return o;

int main()
    int   v = 1;
    int   s = 0;
    void* r = func(&s, &v);
    return 0;


More information about the Gcc-help mailing list