00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __loaded__cmpxchg_h__
00021 #define __loaded__cmpxchg_h__
00022 using namespace std;
00023 #line 1 "cmpxchg.h++"
00024
00030 #ifndef __HAVE_ARCH_CMPXCHG
00031 #ifdef CONFIG_SMP
00032 #define LOCK_PREFIX \
00033 ".section .smp_locks,\"a\"\n" \
00034 " .align 8\n" \
00035 " .quad 661f\n" \
00036 ".previous\n" \
00037 "661:\n\tlock; "
00038 #else
00039 #define LOCK_PREFIX ""
00040 #endif
00041
00042 #define __xg(x) ((volatile long *)(x))
00043
00044 static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
00045 unsigned long nieuw, int size)
00046 {
00047 unsigned long prev;
00048 switch (size) {
00049 case 1:
00050 __asm__ __volatile__(LOCK_PREFIX "cmpxchg %b1,%2"
00051 : "=a"(prev)
00052 : "q"(nieuw), "m"(*__xg(ptr)), "0"(old)
00053 : "memory");
00054 return prev;
00055 case 2:
00056 __asm__ __volatile__(LOCK_PREFIX "cmpxchg %w1,%2"
00057 : "=a"(prev)
00058 : "r"(nieuw), "m"(*__xg(ptr)), "0"(old)
00059 : "memory");
00060 return prev;
00061 case 4:
00062 __asm__ __volatile__(LOCK_PREFIX "cmpxchg %k1,%2"
00063 : "=a"(prev)
00064 : "r"(nieuw), "m"(*__xg(ptr)), "0"(old)
00065 : "memory");
00066 return prev;
00067 case 8:
00068 __asm__ __volatile__(LOCK_PREFIX "cmpxchg %1,%2"
00069 : "=a"(prev)
00070 : "r"(nieuw), "m"(*__xg(ptr)), "0"(old)
00071 : "memory");
00072 return prev;
00073 }
00074 return old;
00075 }
00076
00077 #define cmpxchg(ptr,o,n)\
00078 ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
00079 (unsigned long)(n),sizeof(*(ptr))))
00080 #endif
00081 #endif // __loaded__cmpxchg_h__