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]

How to implement atomic swap with asm on PowerPC


I implemented the atomic swap operation on PowerPC with the following code:

$ cat t.c
void * swap(volatile void * ptr, void * val)
{
 void * old;

 __asm__ __volatile__(
     "1:"
     "ldarx %0,0,%2\n"
     "stdcx. %1,0,%2\n"
     "bne- 1b\n"
     : "=r" (old)
     : "r" (val), "r" (ptr)
     : "cc" );

 return old;
}

Which is compiled to:

$ gcc -g -O2 -c t.c
$ gdb t.o
Reading symbols from /home/cy6/t.o...done.
(gdb) disas swap
Dump of assembler code for function swap:
  0x0000000000000000 <+0>:	ldarx   r3,0,r3
  0x0000000000000004 <+4>:	stdcx.  r4,0,r3
  0x0000000000000008 <+8>:	bne-    0x0 <swap>
  0x000000000000000c <+12>:	blr
  0x0000000000000010 <+16>:	.long 0x0
  0x0000000000000014 <+20>:	.long 0x0
  0x0000000000000018 <+24>:	.long 0x0
End of assembler dump.
(gdb) q

Notice that the ldarx instruction used the same register for both src and destination, which overwrites the pointer. This leads to the stdcx instruction to fail, because r3 no longer holds the pointer.

Since I specified ptr as an input, I assume GCC should not try to reuse the register. Am I missing a constraint here? What should I do to tell GCC to not to use the same register for ldarx instruction?

Iâm using GCC 4.4.7.

Thanks,
Chaoran

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