Inline Assembly queries
Andrew Haley
aph at redhat.com
Tue Jun 30 19:30:53 EST 2009
kernel mailz wrote:
> Consider atomic_add and atomic_add_return in kernel code.
>
> On Tue, Jun 30, 2009 at 2:59 AM, Ian Lance Taylor<iant at google.com> wrote:
>> kernel mailz <kernelmailz at googlemail.com> writes:
>>
>>> I tried a small example
>>>
>>> int *p = 0x1000;
>>> int a = *p;
>>> asm("sync":::"memory");
>>> a = *p;
>>>
>>> and
>>>
>>> volatile int *p = 0x1000;
>>> int a = *p;
>>> asm("sync");
>>> a = *p
>>>
>>> Got the same assembly.
>>> Which is right.
>>>
>>> So does it mean, if proper use of volatile is done, there is no need
>>> of "memory" ?
>> You have to consider the effects of inlining, which may bring in other
>> memory loads and stores through non-volatile pointers.
> Consider
>
> static __inline__ void atomic_add(int a, atomic_t *v)
> {
> int t;
>
> __asm__ __volatile__(
> "1: lwarx %0,0,%3 # atomic_add\n\
> add %0,%2,%0\n"
> PPC405_ERR77(0,%3)
> " stwcx. %0,0,%3 \n\
> bne- 1b"
> : "=&r" (t), "+m" (v->counter)
> : "r" (a), "r" (&v->counter)
> : "cc");
> }
>
> static __inline__ int atomic_add_return(int a, atomic_t *v)
> {
> int t;
>
> __asm__ __volatile__(
> LWSYNC_ON_SMP
> "1: lwarx %0,0,%2 # atomic_add_return\n\
> add %0,%1,%0\n"
> PPC405_ERR77(0,%2)
> " stwcx. %0,0,%2 \n\
> bne- 1b"
> ISYNC_ON_SMP
> : "=&r" (t)
> : "r" (a), "r" (&v->counter)
> : "cc", "memory");
>
> return t;
> }
>
> I am not able to figure out why "memory" is added in latter
The latter, as well as its stated purpose, forms a memory barrier, so the
compiler must be prevented from moving memory access across it. See
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2745.html
Andrew.
More information about the Linuxppc-dev
mailing list