00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef _atomic_sparc64_h
00043 #define _atomic_sparc64_h
00044
00045 #define HAVE_ASM_INLINE_ATOMIC_OPS
00046 #define HAVE_ASM_INLINE_MEMBAR
00047
00048
00049
00050
00051 #if ! defined SPARC64_MODE && \
00052 (defined __LP64__ || defined _LP64 || defined __arch64__)
00053 #define SPARC64_MODE
00054 #endif
00055
00056
00057 #ifdef NOSMP
00058 #define membar() asm volatile ("" : : : "memory")
00059 #define membar_read() membar()
00060 #define membar_write() membar()
00061 #define membar_depends() do {} while(0)
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 #define membar_enter_lock() do {} while(0)
00075 #define membar_leave_lock() do {} while(0)
00076
00077
00078
00079
00080
00081 #define membar_atomic_op() membar()
00082 #define membar_atomic_setget() membar()
00083 #define membar_write_atomic_op() membar_write()
00084 #define membar_write_atomic_setget() membar_write()
00085 #define membar_read_atomic_op() membar_read()
00086 #define membar_read_atomic_setget() membar_read()
00087 #else
00088 #define membar() \
00089 asm volatile ( \
00090 "membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad \n\t" \
00091 : : : "memory")
00092
00093 #define membar_read() asm volatile ("membar #LoadLoad \n\t" : : : "memory")
00094 #define membar_write() asm volatile ("membar #StoreStore \n\t" : : : "memory")
00095 #define membar_depends() do {} while(0)
00096 #define membar_enter_lock() \
00097 asm volatile ("membar #StoreStore | #StoreLoad \n\t" : : : "memory");
00098 #define membar_leave_lock() \
00099 asm volatile ("membar #LoadStore | #StoreStore \n\t" : : : "memory");
00100
00101
00102
00103
00104
00105 #define membar_atomic_op() membar()
00106 #define membar_atomic_setget() membar()
00107 #define membar_write_atomic_op() membar_write()
00108 #define membar_write_atomic_setget() membar_write()
00109 #define membar_read_atomic_op() membar_read()
00110 #define membar_read_atomic_setget() membar_read()
00111 #endif
00112
00113
00114
00115
00116
00117 #define ATOMIC_ASM_OP_int(op)\
00118 " ldsw [%3], %0 \n\t" \
00119 "1: " op " \n\t" \
00120 " cas [%3], %0, %1 \n\t" \
00121 " cmp %0, %1 \n\t" \
00122 " bne,a,pn %%icc, 1b \n\t" \
00123 " mov %1, %0\n\t"
00124
00125 #ifdef SPARC64_MODE
00126
00127 #define ATOMIC_ASM_OP_long(op)\
00128 " ldx [%3], %0 \n\t" \
00129 "1: " op " \n\t" \
00130 " casx [%3], %0, %1 \n\t" \
00131 " cmp %0, %1 \n\t" \
00132 " bne,a,pn %%xcc, 1b \n\t" \
00133 " mov %1, %0\n\t"
00134
00135 #else
00136 #define ATOMIC_ASM_OP_long(op) ATOMIC_ASM_OP_int(op)
00137 #endif
00138
00139 #define ATOMIC_FUNC_DECL(NAME, OP, P_TYPE, RET_TYPE, RET_EXPR) \
00140 inline static RET_TYPE atomic_##NAME##_##P_TYPE (volatile P_TYPE *var) \
00141 { \
00142 P_TYPE ret, tmp; \
00143 asm volatile( \
00144 ATOMIC_ASM_OP_##P_TYPE(OP) \
00145 : "=&r"(ret), "=&r"(tmp), "=m"(*var) : "r"(var) : "cc" \
00146 ); \
00147 return RET_EXPR; \
00148 }
00149
00150
00151
00152 #define ATOMIC_FUNC_DECL1(NAME, OP, P_TYPE, RET_TYPE, RET_EXPR) \
00153 inline static RET_TYPE atomic_##NAME##_##P_TYPE (volatile P_TYPE *var, \
00154 P_TYPE v) \
00155 { \
00156 P_TYPE ret, tmp; \
00157 asm volatile( \
00158 ATOMIC_ASM_OP_##P_TYPE(OP) \
00159 : "=&r"(ret), "=&r"(tmp), "=m"(*var) : "r"(var), "r"(v) : "cc" \
00160 ); \
00161 return RET_EXPR; \
00162 }
00163
00164
00165
00166 #define ATOMIC_FUNC_DECL1_RAW(NAME, OP, P_TYPE, RET_TYPE, RET_EXPR) \
00167 inline static RET_TYPE atomic_##NAME##_##P_TYPE (volatile P_TYPE *var, \
00168 P_TYPE v) \
00169 { \
00170 P_TYPE ret; \
00171 asm volatile( \
00172 OP "\n\t" \
00173 : "=&r"(ret), "=m"(*var) : "r"(var), "0"(v) : "cc" \
00174 ); \
00175 return RET_EXPR; \
00176 }
00177
00178
00179
00180
00181 #define ATOMIC_FUNC_DECL2_CAS(NAME, OP, P_TYPE, RET_TYPE, RET_EXPR) \
00182 inline static RET_TYPE atomic_##NAME##_##P_TYPE (volatile P_TYPE *var, \
00183 P_TYPE v1, P_TYPE v2) \
00184 { \
00185 P_TYPE ret; \
00186 asm volatile( \
00187 OP "\n\t" \
00188 : "=&r"(ret), "=m"(*var) : "r"(var), "r"(v1), "0"(v2) : "cc" \
00189 ); \
00190 return RET_EXPR; \
00191 }
00192
00193
00194
00195 ATOMIC_FUNC_DECL(inc, "add %0, 1, %1", int, void, )
00196 ATOMIC_FUNC_DECL(dec, "sub %0, 1, %1", int, void, )
00197 ATOMIC_FUNC_DECL1(and, "and %0, %4, %1", int, void, )
00198 ATOMIC_FUNC_DECL1(or, "or %0, %4, %1", int, void, )
00199 ATOMIC_FUNC_DECL(inc_and_test, "add %0, 1, %1", int, int, ((ret+1)==0) )
00200 ATOMIC_FUNC_DECL(dec_and_test, "sub %0, 1, %1", int, int, ((ret-1)==0) )
00201
00202 ATOMIC_FUNC_DECL1_RAW(get_and_set, "swap [%2], %0", int, int, ret)
00203
00204 ATOMIC_FUNC_DECL1(add, "add %0, %4, %1", int, int, ret+v)
00205 ATOMIC_FUNC_DECL2_CAS(cmpxchg, "cas [%2], %3, %0", int, int, ret)
00206
00207
00208 ATOMIC_FUNC_DECL(inc, "add %0, 1, %1", long, void, )
00209 ATOMIC_FUNC_DECL(dec, "sub %0, 1, %1", long, void, )
00210 ATOMIC_FUNC_DECL1(and, "and %0, %4, %1", long, void, )
00211 ATOMIC_FUNC_DECL1(or, "or %0, %4, %1", long, void, )
00212 ATOMIC_FUNC_DECL(inc_and_test, "add %0, 1, %1", long, long, ((ret+1)==0) )
00213 ATOMIC_FUNC_DECL(dec_and_test, "sub %0, 1, %1", long, long, ((ret-1)==0) )
00214 ATOMIC_FUNC_DECL1(get_and_set, "mov %4, %1" , long, long, ret)
00215 ATOMIC_FUNC_DECL1(add, "add %0, %4, %1", long, long, ret+v)
00216 #ifdef SPARC64_MODE
00217 ATOMIC_FUNC_DECL2_CAS(cmpxchg, "casx [%2], %3, %0", long, long, ret)
00218 #else
00219 ATOMIC_FUNC_DECL2_CAS(cmpxchg, "cas [%2], %3, %0", long, long, ret)
00220 #endif
00221
00222
00223 #define atomic_inc(var) atomic_inc_int(&(var)->val)
00224 #define atomic_dec(var) atomic_dec_int(&(var)->val)
00225 #define atomic_and(var, mask) atomic_and_int(&(var)->val, (mask))
00226 #define atomic_or(var, mask) atomic_or_int(&(var)->val, (mask))
00227 #define atomic_dec_and_test(var) atomic_dec_and_test_int(&(var)->val)
00228 #define atomic_inc_and_test(var) atomic_inc_and_test_int(&(var)->val)
00229 #define atomic_get_and_set(var, i) atomic_get_and_set_int(&(var)->val, i)
00230 #define atomic_add(var, i) atomic_add_int(&(var)->val, i)
00231 #define atomic_cmpxchg(var, old, new_v) \
00232 atomic_cmpxchg_int(&(var)->val, old, new_v)
00233
00234
00235
00236
00237
00238 #define mb_atomic_set_int(v, i) \
00239 do{ \
00240 membar(); \
00241 atomic_set_int(v, i); \
00242 }while(0)
00243
00244
00245
00246 inline static int mb_atomic_get_int(volatile int* v)
00247 {
00248 membar();
00249 return atomic_get_int(v);
00250 }
00251
00252
00253 #define mb_atomic_inc_int(v) \
00254 do{ \
00255 membar(); \
00256 atomic_inc_int(v); \
00257 }while(0)
00258
00259 #define mb_atomic_dec_int(v) \
00260 do{ \
00261 membar(); \
00262 atomic_dec_int(v); \
00263 }while(0)
00264
00265 #define mb_atomic_or_int(v, m) \
00266 do{ \
00267 membar(); \
00268 atomic_or_int(v, m); \
00269 }while(0)
00270
00271 #define mb_atomic_and_int(v, m) \
00272 do{ \
00273 membar(); \
00274 atomic_and_int(v, m); \
00275 }while(0)
00276
00277 inline static int mb_atomic_inc_and_test_int(volatile int* v)
00278 {
00279 membar();
00280 return atomic_inc_and_test_int(v);
00281 }
00282
00283 inline static int mb_atomic_dec_and_test_int(volatile int* v)
00284 {
00285 membar();
00286 return atomic_dec_and_test_int(v);
00287 }
00288
00289
00290 inline static int mb_atomic_get_and_set_int(volatile int* v, int i)
00291 {
00292 membar();
00293 return atomic_get_and_set_int(v, i);
00294 }
00295
00296 inline static int mb_atomic_cmpxchg_int(volatile int* v, int o, int n)
00297 {
00298 membar();
00299 return atomic_cmpxchg_int(v, o, n);
00300 }
00301
00302 inline static int mb_atomic_add_int(volatile int* v, int i)
00303 {
00304 membar();
00305 return atomic_add_int(v, i);
00306 }
00307
00308
00309
00310 #define mb_atomic_set_long(v, i) \
00311 do{ \
00312 membar(); \
00313 atomic_set_long(v, i); \
00314 }while(0)
00315
00316
00317
00318 inline static long mb_atomic_get_long(volatile long* v)
00319 {
00320 membar();
00321 return atomic_get_long(v);
00322 }
00323
00324
00325 #define mb_atomic_inc_long(v) \
00326 do{ \
00327 membar(); \
00328 atomic_inc_long(v); \
00329 }while(0)
00330
00331
00332 #define mb_atomic_dec_long(v) \
00333 do{ \
00334 membar(); \
00335 atomic_dec_long(v); \
00336 }while(0)
00337
00338 #define mb_atomic_or_long(v, m) \
00339 do{ \
00340 membar(); \
00341 atomic_or_long(v, m); \
00342 }while(0)
00343
00344 #define mb_atomic_and_long(v, m) \
00345 do{ \
00346 membar(); \
00347 atomic_and_long(v, m); \
00348 }while(0)
00349
00350 inline static long mb_atomic_inc_and_test_long(volatile long* v)
00351 {
00352 membar();
00353 return atomic_inc_and_test_long(v);
00354 }
00355
00356 inline static long mb_atomic_dec_and_test_long(volatile long* v)
00357 {
00358 membar();
00359 return atomic_dec_and_test_long(v);
00360 }
00361
00362
00363 inline static long mb_atomic_get_and_set_long(volatile long* v, long l)
00364 {
00365 membar();
00366 return atomic_get_and_set_long(v, l);
00367 }
00368
00369 inline static long mb_atomic_cmpxchg_long(volatile long* v, long o, long n)
00370 {
00371 membar();
00372 return atomic_cmpxchg_long(v, o, n);
00373 }
00374
00375 inline static long mb_atomic_add_long(volatile long* v, long i)
00376 {
00377 membar();
00378 return atomic_add_long(v, i);
00379 }
00380
00381
00382 #define mb_atomic_inc(var) mb_atomic_inc_int(&(var)->val)
00383 #define mb_atomic_dec(var) mb_atomic_dec_int(&(var)->val)
00384 #define mb_atomic_and(var, mask) mb_atomic_and_int(&(var)->val, (mask))
00385 #define mb_atomic_or(var, mask) mb_atomic_or_int(&(var)->val, (mask))
00386 #define mb_atomic_dec_and_test(var) mb_atomic_dec_and_test_int(&(var)->val)
00387 #define mb_atomic_inc_and_test(var) mb_atomic_inc_and_test_int(&(var)->val)
00388 #define mb_atomic_get(var) mb_atomic_get_int(&(var)->val)
00389 #define mb_atomic_set(var, i) mb_atomic_set_int(&(var)->val, i)
00390 #define mb_atomic_get_and_set(var, i) mb_atomic_get_and_set_int(&(var)->val, i)
00391 #define mb_atomic_cmpxchg(var, o, n) mb_atomic_cmpxchg_int(&(var)->val, o, n)
00392 #define mb_atomic_add(var, i) mb_atomic_add_int(&(var)->val, i)
00393
00394
00395 #endif