6 #include "atomic_arch.h"
20 static inline int a_cas(volatile int *p, int t, int s)
25 while (old==t && !a_sc(p, s));
33 static inline int a_swap(volatile int *p, int v)
45 #define a_fetch_add a_fetch_add
46 static inline int a_fetch_add(volatile int *p, int v)
51 while (!a_sc(p, (unsigned)old + v));
58 #define a_fetch_and a_fetch_and
59 static inline int a_fetch_and(volatile int *p, int v)
64 while (!a_sc(p, old & v));
71 #define a_fetch_or a_fetch_or
72 static inline int a_fetch_or(volatile int *p, int v)
77 while (!a_sc(p, old | v));
88 #define a_cas_p a_cas_p
89 static inline void *a_cas_p(volatile void *p, void *t, void *s)
94 while (old==t && !a_sc_p(p, s));
103 #error missing definition of a_cas
107 #define a_swap a_swap
108 static inline int a_swap(volatile int *p, int v)
112 while (a_cas(p, old, v) != old);
118 #define a_fetch_add a_fetch_add
119 static inline int a_fetch_add(volatile int *p, int v)
123 while (a_cas(p, old, (unsigned)old+v) != old);
129 #define a_fetch_and a_fetch_and
130 static inline int a_fetch_and(volatile int *p, int v)
134 while (a_cas(p, old, old&v) != old);
139 #define a_fetch_or a_fetch_or
140 static inline int a_fetch_or(volatile int *p, int v)
144 while (a_cas(p, old, old|v) != old);
151 static inline void a_and(volatile int *p, int v)
159 static inline void a_or(volatile int *p, int v)
167 static inline void a_inc(volatile int *p)
175 static inline void a_dec(volatile int *p)
182 #define a_store a_store
183 static inline void a_store(volatile int *p, int v)
196 #define a_barrier a_barrier
197 static void a_barrier()
199 volatile int tmp = 0;
205 #define a_spin a_barrier
209 #define a_and_64 a_and_64
210 static inline void a_and_64(volatile uint64_t *p, uint64_t v)
212 union { uint64_t v; uint32_t r[2]; } u = { v };
213 if (u.r[0]+1) a_and((int *)p, u.r[0]);
214 if (u.r[1]+1) a_and((int *)p+1, u.r[1]);
219 #define a_or_64 a_or_64
220 static inline void a_or_64(volatile uint64_t *p, uint64_t v)
222 union { uint64_t v; uint32_t r[2]; } u = { v };
223 if (u.r[0]) a_or((int *)p, u.r[0]);
224 if (u.r[1]) a_or((int *)p+1, u.r[1]);
229 typedef char a_cas_p_undefined_but_pointer_not_32bit[-sizeof(char) == 0xffffffff ? 1 : -1];
230 #define a_cas_p a_cas_p
231 static inline void *a_cas_p(volatile void *p, void *t, void *s)
233 return (void *)a_cas((volatile int *)p, (int)t, (int)s);
238 #define a_or_l a_or_l
239 static inline void a_or_l(volatile void *p, long v)
241 if (sizeof(long) == sizeof(int)) a_or(p, v);
247 #define a_crash a_crash
248 static inline void a_crash()
250 *(volatile char *)0=0;
255 #define a_ctz_32 a_ctz_32
256 static inline int a_ctz_32(uint32_t x)
259 return 31-a_clz_32(x&-x);
261 static const char debruijn32[32] = {
262 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13,
263 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14
265 return debruijn32[(x&-x)*0x076be629 >> 27];
271 #define a_ctz_64 a_ctz_64
272 static inline int a_ctz_64(uint64_t x)
274 static const char debruijn64[64] = {
275 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
276 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
277 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
278 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12
280 if (sizeof(long) < 8) {
284 return 32 + a_ctz_32(y);
288 return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58];
292 static inline int a_ctz_l(unsigned long x)
294 return (sizeof(long) < 8) ? a_ctz_32(x) : a_ctz_64(x);
298 #define a_clz_64 a_clz_64
299 static inline int a_clz_64(uint64_t x)
303 return a_clz_32(x>>32);
304 return a_clz_32(x) + 32;
308 if (x>>32) y=x>>32, r=0; else y=x, r=32;
309 if (y>>16) y>>=16; else r |= 16;
310 if (y>>8) y>>=8; else r |= 8;
311 if (y>>4) y>>=4; else r |= 4;
312 if (y>>2) y>>=2; else r |= 2;
319 #define a_clz_32 a_clz_32
320 static inline int a_clz_32(uint32_t x)
329 return 31-a_ctz_32(x);