Go to the documentation of this file.00001
00002 #ifndef __ORO_ARCH_x86_64__
00003 #define __ORO_ARCH_x86_64__
00004
00005 #ifndef CONFIG_FORCE_UP
00006 #define ORO_LOCK "lock ; "
00007 #else
00008 #define ORO_LOCK ""
00009 #endif
00010
00011 typedef struct { volatile int counter; } oro_atomic_t;
00012
00013 #define ORO_ATOMIC_SETUP oro_atomic_set
00014 #define ORO_ATOMIC_CLEANUP(v)
00015
00016 #define oro_atomic_read(v) ((v)->counter)
00017
00018 #define oro_atomic_set(v,i) (((v)->counter) = (i))
00019
00020 static __inline__ void oro_atomic_add(oro_atomic_t *v, int i)
00021 {
00022 __asm__ __volatile__(
00023 ORO_LOCK "addl %1,%0"
00024 :"=m" (v->counter)
00025 :"ir" (i), "m" (v->counter));
00026 }
00027
00028 static __inline__ void oro_atomic_sub(oro_atomic_t *v, int i)
00029 {
00030 __asm__ __volatile__(
00031 ORO_LOCK "subl %1,%0"
00032 :"=m" (v->counter)
00033 :"ir" (i), "m" (v->counter));
00034 }
00035
00036 static __inline__ int oro_atomic_sub_and_test(oro_atomic_t *v, int i)
00037 {
00038 unsigned char c;
00039
00040 __asm__ __volatile__(
00041 ORO_LOCK "subl %2,%0; sete %1"
00042 :"=m" (v->counter), "=qm" (c)
00043 :"ir" (i), "m" (v->counter) : "memory");
00044 return c;
00045 }
00046
00047 static __inline__ void oro_atomic_inc(oro_atomic_t *v)
00048 {
00049 __asm__ __volatile__(
00050 ORO_LOCK "incl %0"
00051 :"=m" (v->counter)
00052 :"m" (v->counter));
00053 }
00054
00055 static __inline__ void oro_atomic_dec(oro_atomic_t *v)
00056 {
00057 __asm__ __volatile__(
00058 ORO_LOCK "decl %0"
00059 :"=m" (v->counter)
00060 :"m" (v->counter));
00061 }
00062
00063 static __inline__ int oro_atomic_dec_and_test(oro_atomic_t *v)
00064 {
00065 unsigned char c;
00066
00067 __asm__ __volatile__(
00068 ORO_LOCK "decl %0; sete %1"
00069 :"=m" (v->counter), "=qm" (c)
00070 :"m" (v->counter) : "memory");
00071 return c != 0;
00072 }
00073
00074 static __inline__ int oro_atomic_inc_and_test(oro_atomic_t *v)
00075 {
00076 unsigned char c;
00077
00078 __asm__ __volatile__(
00079 ORO_LOCK "incl %0; sete %1"
00080 :"=m" (v->counter), "=qm" (c)
00081 :"m" (v->counter) : "memory");
00082 return c != 0;
00083 }
00084
00085 static __inline__ int oro_atomic_add_negative(int i, oro_atomic_t *v)
00086 {
00087 unsigned char c;
00088
00089 __asm__ __volatile__(
00090 ORO_LOCK "addl %2,%0; sets %1"
00091 :"=m" (v->counter), "=qm" (c)
00092 :"ir" (i), "m" (v->counter) : "memory");
00093 return c;
00094 }
00095
00096 #ifndef CONFIG_FORCE_UP
00097 #define ORO_LOCK_PREFIX "lock ; "
00098 #else
00099 #define ORO_LOCK_PREFIX ""
00100 #endif
00101
00102 struct oro__xchg_dummy { unsigned long a[100]; };
00103 #define oro__xg(x) ((struct oro__xchg_dummy *)(x))
00104
00105 static inline unsigned long __oro_cmpxchg(volatile void *ptr, unsigned long old,
00106 unsigned long _new, int size)
00107 {
00108 unsigned long prev;
00109 switch (size) {
00110 case 1:
00111 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgb %b1,%2"
00112 : "=a"(prev)
00113 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
00114 : "memory");
00115 return prev;
00116 case 2:
00117 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgw %w1,%2"
00118 : "=a"(prev)
00119 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
00120 : "memory");
00121 return prev;
00122 case 4:
00123 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgl %k1,%2"
00124 : "=a"(prev)
00125 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
00126 : "memory");
00127 return prev;
00128 case 8:
00129 __asm__ __volatile__(ORO_LOCK_PREFIX "cmpxchgq %1,%2"
00130 : "=a"(prev)
00131 : "q"(_new), "m"(*oro__xg(ptr)), "0"(old)
00132 : "memory");
00133 return prev;
00134
00135 }
00136 return old;
00137 }
00138
00139 #define oro_cmpxchg(ptr,o,n)\
00140 ((__typeof__(*(ptr)))__oro_cmpxchg((ptr),(unsigned long)(o),\
00141 (unsigned long)(n),sizeof(*(ptr))))
00142
00143 #undef ORO_LOCK_PREFIX
00144 #undef ORO_LOCK
00145 #endif