00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "./aligned_atomic_load_store.h"
00024
00025 #include "./all_acquire_release_volatile.h"
00026
00027 #include "./test_and_set_t_is_char.h"
00028
00029 #ifdef _ILP32
00030
00031
00032
00033
00034 # define AO_LEN "4"
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 # define AO_IN_ADDR "1"(addr)
00046 # define AO_OUT_ADDR , "=r"(addr)
00047 # define AO_SWIZZLE "addp4 %1=0,%1;;\n"
00048 # define AO_MASK(ptr) __asm__("zxt4 %1=%1": "=r"(ptr) : "0"(ptr));
00049 #else
00050 # define AO_LEN "8"
00051 # define AO_IN_ADDR "r"(addr)
00052 # define AO_OUT_ADDR
00053 # define AO_SWIZZLE
00054 # define AO_MASK(ptr)
00055 #endif
00056
00057 AO_INLINE void
00058 AO_nop_full(void)
00059 {
00060 __asm__ __volatile__("mf" : : : "memory");
00061 }
00062 #define AO_HAVE_nop_full
00063
00064 AO_INLINE AO_t
00065 AO_fetch_and_add1_acquire (volatile AO_t *addr)
00066 {
00067 AO_t result;
00068
00069 __asm__ __volatile__ (AO_SWIZZLE
00070 "fetchadd" AO_LEN ".acq %0=[%1],1":
00071 "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
00072 return result;
00073 }
00074 #define AO_HAVE_fetch_and_add1_acquire
00075
00076 AO_INLINE AO_t
00077 AO_fetch_and_add1_release (volatile AO_t *addr)
00078 {
00079 AO_t result;
00080
00081 __asm__ __volatile__ (AO_SWIZZLE
00082 "fetchadd" AO_LEN ".rel %0=[%1],1":
00083 "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
00084 return result;
00085 }
00086
00087 #define AO_HAVE_fetch_and_add1_release
00088
00089 AO_INLINE AO_t
00090 AO_fetch_and_sub1_acquire (volatile AO_t *addr)
00091 {
00092 AO_t result;
00093
00094 __asm__ __volatile__ (AO_SWIZZLE
00095 "fetchadd" AO_LEN ".acq %0=[%1],-1":
00096 "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
00097 return result;
00098 }
00099
00100 #define AO_HAVE_fetch_and_sub1_acquire
00101
00102 AO_INLINE AO_t
00103 AO_fetch_and_sub1_release (volatile AO_t *addr)
00104 {
00105 AO_t result;
00106
00107 __asm__ __volatile__ (AO_SWIZZLE
00108 "fetchadd" AO_LEN ".rel %0=[%1],-1":
00109 "=r" (result) AO_OUT_ADDR: AO_IN_ADDR :"memory");
00110 return result;
00111 }
00112
00113 #define AO_HAVE_fetch_and_sub1_release
00114
00115 #ifndef _ILP32
00116
00117 AO_INLINE unsigned int
00118 AO_int_fetch_and_add1_acquire (volatile unsigned int *addr)
00119 {
00120 unsigned int result;
00121
00122 __asm__ __volatile__ ("fetchadd4.acq %0=[%1],1":
00123 "=r" (result): AO_IN_ADDR :"memory");
00124 return result;
00125 }
00126 #define AO_HAVE_int_fetch_and_add1_acquire
00127
00128 AO_INLINE unsigned int
00129 AO_int_fetch_and_add1_release (volatile unsigned int *addr)
00130 {
00131 unsigned int result;
00132
00133 __asm__ __volatile__ ("fetchadd4.rel %0=[%1],1":
00134 "=r" (result): AO_IN_ADDR :"memory");
00135 return result;
00136 }
00137
00138 #define AO_HAVE_int_fetch_and_add1_release
00139
00140 AO_INLINE unsigned int
00141 AO_int_fetch_and_sub1_acquire (volatile unsigned int *addr)
00142 {
00143 unsigned int result;
00144
00145 __asm__ __volatile__ ("fetchadd4.acq %0=[%1],-1":
00146 "=r" (result): AO_IN_ADDR :"memory");
00147 return result;
00148 }
00149
00150 #define AO_HAVE_int_fetch_and_sub1_acquire
00151
00152 AO_INLINE unsigned int
00153 AO_int_fetch_and_sub1_release (volatile unsigned int *addr)
00154 {
00155 unsigned int result;
00156
00157 __asm__ __volatile__ ("fetchadd4.rel %0=[%1],-1":
00158 "=r" (result): AO_IN_ADDR :"memory");
00159 return result;
00160 }
00161
00162 #define AO_HAVE_int_fetch_and_sub1_release
00163
00164 #endif
00165
00166 AO_INLINE int
00167 AO_compare_and_swap_acquire(volatile AO_t *addr,
00168 AO_t old, AO_t new_val)
00169 {
00170 AO_t oldval;
00171 AO_MASK(old);
00172 __asm__ __volatile__(AO_SWIZZLE
00173 "mov ar.ccv=%[old] ;; cmpxchg" AO_LEN
00174 ".acq %0=[%1],%[new_val],ar.ccv"
00175 : "=r"(oldval) AO_OUT_ADDR
00176 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"(old)
00177 : "memory");
00178 return (oldval == old);
00179 }
00180
00181 #define AO_HAVE_compare_and_swap_acquire
00182
00183 AO_INLINE int
00184 AO_compare_and_swap_release(volatile AO_t *addr,
00185 AO_t old, AO_t new_val)
00186 {
00187 AO_t oldval;
00188 AO_MASK(old);
00189 __asm__ __volatile__(AO_SWIZZLE
00190 "mov ar.ccv=%[old] ;; cmpxchg" AO_LEN
00191 ".rel %0=[%1],%[new_val],ar.ccv"
00192 : "=r"(oldval) AO_OUT_ADDR
00193 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"(old)
00194 : "memory");
00195 return (oldval == old);
00196 }
00197
00198 #define AO_HAVE_compare_and_swap_release
00199
00200 AO_INLINE int
00201 AO_char_compare_and_swap_acquire(volatile unsigned char *addr,
00202 unsigned char old, unsigned char new_val)
00203 {
00204 unsigned char oldval;
00205 __asm__ __volatile__(AO_SWIZZLE
00206 "mov ar.ccv=%[old] ;; cmpxchg1.acq %0=[%1],%[new_val],ar.ccv"
00207 : "=r"(oldval) AO_OUT_ADDR
00208 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
00209 : "memory");
00210 return (oldval == old);
00211 }
00212
00213 #define AO_HAVE_char_compare_and_swap_acquire
00214
00215 AO_INLINE int
00216 AO_char_compare_and_swap_release(volatile unsigned char *addr,
00217 unsigned char old, unsigned char new_val)
00218 {
00219 unsigned char oldval;
00220 __asm__ __volatile__(AO_SWIZZLE
00221 "mov ar.ccv=%[old] ;; cmpxchg1.rel %0=[%1],%[new_val],ar.ccv"
00222 : "=r"(oldval) AO_OUT_ADDR
00223 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
00224 : "memory");
00225 return (oldval == old);
00226 }
00227
00228 #define AO_HAVE_char_compare_and_swap_release
00229
00230 AO_INLINE int
00231 AO_short_compare_and_swap_acquire(volatile unsigned short *addr,
00232 unsigned short old, unsigned short new_val)
00233 {
00234 unsigned short oldval;
00235 __asm__ __volatile__(AO_SWIZZLE
00236 "mov ar.ccv=%[old] ;; cmpxchg2.acq %0=[%1],%[new_val],ar.ccv"
00237 : "=r"(oldval) AO_OUT_ADDR
00238 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
00239 : "memory");
00240 return (oldval == old);
00241 }
00242
00243 #define AO_HAVE_short_compare_and_swap_acquire
00244
00245 AO_INLINE int
00246 AO_short_compare_and_swap_release(volatile unsigned short *addr,
00247 unsigned short old, unsigned short new_val)
00248 {
00249 unsigned short oldval;
00250 __asm__ __volatile__(AO_SWIZZLE
00251 "mov ar.ccv=%[old] ;; cmpxchg2.rel %0=[%1],%[new_val],ar.ccv"
00252 : "=r"(oldval) AO_OUT_ADDR
00253 : AO_IN_ADDR, [new_val]"r"(new_val), [old]"r"((AO_t)old)
00254 : "memory");
00255 return (oldval == old);
00256 }
00257
00258 #define AO_HAVE_short_compare_and_swap_release
00259
00260 #ifndef _ILP32
00261
00262 AO_INLINE int
00263 AO_int_compare_and_swap_acquire(volatile unsigned int *addr,
00264 unsigned int old, unsigned int new_val)
00265 {
00266 unsigned int oldval;
00267 __asm__ __volatile__("mov ar.ccv=%3 ;; cmpxchg4.acq %0=[%1],%2,ar.ccv"
00268 : "=r"(oldval)
00269 : AO_IN_ADDR, "r"(new_val), "r"((AO_t)old) : "memory");
00270 return (oldval == old);
00271 }
00272
00273 #define AO_HAVE_int_compare_and_swap_acquire
00274
00275 AO_INLINE int
00276 AO_int_compare_and_swap_release(volatile unsigned int *addr,
00277 unsigned int old, unsigned int new_val)
00278 {
00279 unsigned int oldval;
00280 __asm__ __volatile__("mov ar.ccv=%3 ;; cmpxchg4.rel %0=[%1],%2,ar.ccv"
00281 : "=r"(oldval)
00282 : AO_IN_ADDR, "r"(new_val), "r"((AO_t)old) : "memory");
00283 return (oldval == old);
00284 }
00285
00286 #define AO_HAVE_int_compare_and_swap_release
00287
00288 #endif
00289
00290
00291
00292
00293
00294
00295 #ifdef _ILP32
00296 # include "./ao_t_is_int.h"
00297 #endif