Mercurial > sdl-ios-xcode
comparison include/SDL_atomic.h @ 3187:e041d2c603fe
indent is really bad at handling assembly
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 10 Jun 2009 13:38:19 +0000 |
parents | 51750b7a966f |
children | 3e1bf2b8bd81 |
comparison
equal
deleted
inserted
replaced
3186:51750b7a966f | 3187:e041d2c603fe |
---|---|
40 /* *INDENT-OFF* */ | 40 /* *INDENT-OFF* */ |
41 extern "C" { | 41 extern "C" { |
42 /* *INDENT-ON* */ | 42 /* *INDENT-ON* */ |
43 #endif | 43 #endif |
44 | 44 |
45 /* indent is really bad at handling assembly */ | |
46 /* *INDENT-OFF* */ | |
47 | |
45 #if defined(__GNUC__) && (defined(i386) || defined(__i386__) || defined(__x86_64__)) | 48 #if defined(__GNUC__) && (defined(i386) || defined(__i386__) || defined(__x86_64__)) |
46 static __inline__ void | 49 static __inline__ void |
47 SDL_atomic_int_add(volatile int *atomic, int value) | 50 SDL_atomic_int_add(volatile int* atomic, int value) |
48 { | 51 { |
49 __asm__ __volatile__("lock;" "addl %1, %0":"=m"(*atomic) | 52 __asm__ __volatile__("lock;" |
50 :"ir"(value), "m"(*atomic)); | 53 "addl %1, %0" |
54 : "=m" (*atomic) | |
55 : "ir" (value), | |
56 "m" (*atomic)); | |
51 } | 57 } |
52 | 58 |
53 static __inline__ int | 59 static __inline__ int |
54 SDL_atomic_int_xchg_add(volatile int *atomic, int value) | 60 SDL_atomic_int_xchg_add(volatile int* atomic, int value) |
55 { | 61 { |
56 int rv; | 62 int rv; |
57 __asm__ __volatile__("lock;" "xaddl %0, %1":"=r"(rv), "=m"(*atomic) | 63 __asm__ __volatile__("lock;" |
58 :"0"(value), "m"(*atomic)); | 64 "xaddl %0, %1" |
59 return rv; | 65 : "=r" (rv), |
60 } | 66 "=m" (*atomic) |
61 | 67 : "0" (value), |
62 static __inline__ SDL_bool | 68 "m" (*atomic)); |
63 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 69 return rv; |
64 { | 70 } |
65 int rv; | 71 |
66 __asm__ __volatile__("lock;" "cmpxchgl %2, %1":"=a"(rv), "=m"(*atomic) | 72 static __inline__ SDL_bool |
67 :"r"(newvalue), "m"(*atomic), "0"(oldvalue)); | 73 SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue) |
68 return (SDL_bool) (rv == oldvalue); | 74 { |
69 } | 75 int rv; |
70 | 76 __asm__ __volatile__("lock;" |
71 static __inline__ SDL_bool | 77 "cmpxchgl %2, %1" |
72 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 78 : "=a" (rv), |
73 void *newvalue) | 79 "=m" (*atomic) |
74 { | 80 : "r" (newvalue), |
75 void *rv; | 81 "m" (*atomic), |
76 __asm__ __volatile__("lock;" | 82 "0" (oldvalue)); |
77 # if defined(__x86_64__) | 83 return (SDL_bool)(rv == oldvalue); |
78 "cmpxchgq %q2, %1" | 84 } |
85 | |
86 static __inline__ SDL_bool | |
87 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) | |
88 { | |
89 void* rv; | |
90 __asm__ __volatile__("lock;" | |
91 # if defined(__x86_64__) | |
92 "cmpxchgq %q2, %1" | |
79 # else | 93 # else |
80 "cmpxchgl %2, %1" | 94 "cmpxchgl %2, %1" |
81 # endif | 95 # endif |
82 :"=a"(rv), "=m"(*atomic) | 96 : "=a" (rv), |
83 :"r"(newvalue), "m"(*atomic), "0"(oldvalue)); | 97 "=m" (*atomic) |
84 return (SDL_bool) (rv == oldvalue); | 98 : "r" (newvalue), |
99 "m" (*atomic), | |
100 "0" (oldvalue)); | |
101 return (SDL_bool)(rv == oldvalue); | |
85 } | 102 } |
86 #elif defined(__GNUC__) && defined(__alpha__) | 103 #elif defined(__GNUC__) && defined(__alpha__) |
87 # define ATOMIC_MEMORY_BARRIER (__asm__ __volatile__ ("mb" : : : "memory")) | 104 # define ATOMIC_MEMORY_BARRIER (__asm__ __volatile__ ("mb" : : : "memory")) |
88 # define ATOMIC_INT_CMP_XCHG(atomic,value) \ | 105 # define ATOMIC_INT_CMP_XCHG(atomic,value) \ |
89 ({ \ | 106 ({ \ |
106 (rv != 0); \ | 123 (rv != 0); \ |
107 }) | 124 }) |
108 | 125 |
109 # if (SIZEOF_VOIDP == 4) | 126 # if (SIZEOF_VOIDP == 4) |
110 static __inline__ SDL_bool | 127 static __inline__ SDL_bool |
111 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 128 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
112 void *newvalue) | 129 { |
113 { | 130 int rv; |
114 int rv; | 131 void* prev; |
115 void *prev; | 132 __asm__ __volatile__(" mb\n" |
116 __asm__ __volatile__(" mb\n" | 133 "1: ldl_l %0,%2\n" |
117 "1: ldl_l %0,%2\n" | 134 " cmpeq %0,%3,%1\n" |
118 " cmpeq %0,%3,%1\n" | 135 " beq $1,2f\n" |
119 " beq $1,2f\n" | 136 " mov %4,%1\n" |
120 " mov %4,%1\n" | 137 " stl_c %1,%2\n" |
121 " stl_c %1,%2\n" | 138 " beq %1,1b\n" |
122 " beq %1,1b\n" | 139 " mb\n" |
123 " mb\n" "2:":"=&r"(prev), "=&r"(rv) | 140 "2:" |
124 :"m"(*atomic), "Ir"(oldvalue), "Ir"(newvalue) | 141 : "=&r" (prev), |
125 :"memory"); | 142 "=&r" (rv) |
126 return (SDL_bool) (rv != 0); | 143 : "m" (*atomic), |
144 "Ir" (oldvalue), | |
145 "Ir" (newvalue) | |
146 : "memory"); | |
147 return (SDL_bool)(rv != 0); | |
127 } | 148 } |
128 # elif (SIZEOF_VOIDP == 8) | 149 # elif (SIZEOF_VOIDP == 8) |
129 static __inline__ SDL_bool | 150 static __inline__ SDL_bool |
130 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 151 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
131 void *newvalue) | 152 { |
132 { | 153 int rv; |
133 int rv; | 154 void* prev; |
134 void *prev; | 155 __asm__ __volatile__(" mb\n" |
135 __asm__ __volatile__(" mb\n" | 156 "1: ldq_l %0,%2\n" |
136 "1: ldq_l %0,%2\n" | 157 " cmpeq %0,%3,%1\n" |
137 " cmpeq %0,%3,%1\n" | 158 " beq %1,2f\n" |
138 " beq %1,2f\n" | 159 " mov %4,%1\n" |
139 " mov %4,%1\n" | 160 " stq_c %1,%2\n" |
140 " stq_c %1,%2\n" | 161 " beq %1,1b\n" |
141 " beq %1,1b\n" | 162 " mb\n" |
142 " mb\n" "2:":"=&r"(prev), "=&r"(rv) | 163 "2:" |
143 :"m"(*atomic), "Ir"(oldvalue), "Ir"(newvalue) | 164 : "=&r" (prev), |
144 :"memory"); | 165 "=&r" (rv) |
145 return (SDL_bool) (rv != 0); | 166 : "m" (*atomic), |
167 "Ir" (oldvalue), | |
168 "Ir" (newvalue) | |
169 : "memory"); | |
170 return (SDL_bool)(rv != 0); | |
146 } | 171 } |
147 # else | 172 # else |
148 # error "Your system has an unsupported pointer size" | 173 # error "Your system has an unsupported pointer size" |
149 # endif /* SIZEOF_VOIDP */ | 174 # endif /* SIZEOF_VOIDP */ |
150 #elif defined(__GNUC__) && defined(__sparc__) | 175 #elif defined(__GNUC__) && defined(__sparc__) |
151 # define ATOMIC_MEMORY_BARRIER \ | 176 # define ATOMIC_MEMORY_BARRIER \ |
152 (__asm__ __volatile__("membar #LoadLoad | #LoadStore" \ | 177 (__asm__ __volatile__("membar #LoadLoad | #LoadStore" \ |
153 " | #StoreLoad | #StoreStore" : : : "memory")) | 178 " | #StoreLoad | #StoreStore" : : : "memory")) |
154 # define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue) \ | 179 # define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue) \ |
161 rv == oldvalue; \ | 186 rv == oldvalue; \ |
162 }) | 187 }) |
163 | 188 |
164 # if (SIZEOF_VOIDP == 4) | 189 # if (SIZEOF_VOIDP == 4) |
165 static __inline__ SDL_bool | 190 static __inline__ SDL_bool |
166 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 191 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
167 void *newvalue) | 192 { |
168 { | 193 void* rv; |
169 void *rv; | 194 __asm__ __volatile__("cas [%4], %2, %0" |
170 __asm__ __volatile__("cas [%4], %2, %0":"=r"(rv), "=m"(*atomic) | 195 : "=r" (rv), |
171 :"r"(oldvalue), | 196 "=m" (*atomic) |
172 "m"(*atomic), "r"(atomic), "0"(newvalue)); | 197 : "r" (oldvalue), |
173 return (SDL_bool) (rv == oldvalue); | 198 "m" (*atomic), |
199 "r" (atomic), | |
200 "0" (newvalue)); | |
201 return (SDL_bool)(rv == oldvalue); | |
174 } | 202 } |
175 # elif (SIZEOF_VOIDP == 8) | 203 # elif (SIZEOF_VOIDP == 8) |
176 static __inline__ SDL_bool | 204 static __inline__ SDL_bool |
177 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 205 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
178 void *newvalue) | 206 { |
179 { | 207 void* rv; |
180 void *rv; | 208 void** a = atomic; |
181 void **a = atomic; | 209 __asm__ __volatile__("casx [%4], %2, %0" |
182 __asm__ __volatile__("casx [%4], %2, %0":"=r"(rv), "=m"(*a) | 210 : "=r" (rv), |
183 :"r"(oldvalue), "m"(*a), "r"(a), "0"(newvalue)); | 211 "=m" (*a) |
184 return (SDL_bool) (rv == oldvalue); | 212 : "r" (oldvalue), |
213 "m" (*a), | |
214 "r" (a), | |
215 "0" (newvalue)); | |
216 return (SDL_bool)(rv == oldvalue); | |
185 } | 217 } |
186 # else | 218 # else |
187 # error "Your system has an unsupported pointer size" | 219 # error "Your system has an unsupported pointer size" |
188 # endif /* SIZEOF_VOIDP */ | 220 # endif /* SIZEOF_VOIDP */ |
189 #elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)) | 221 #elif defined(__GNUC__) && (defined(__POWERPC__) || defined(__powerpc__) || defined(__ppc__) || defined(_M_PPC)) |
190 # define ATOMIC_MEMORY_BARRIER \ | 222 # define ATOMIC_MEMORY_BARRIER \ |
191 (__asm__ __volatile__ ("sync" : : : "memory")) | 223 (__asm__ __volatile__ ("sync" : : : "memory")) |
192 static __inline__ void | 224 static __inline__ void |
193 SDL_atomic_int_add(volatile int *atomic, int value) | 225 SDL_atomic_int_add(volatile int* atomic, int value) |
194 { | 226 { |
195 int rv, tmp; | 227 int rv,tmp; |
196 __asm__ __volatile__("1: lwarx %0, 0, %3\n" | 228 __asm__ __volatile__("1: lwarx %0, 0, %3\n" |
197 " add %1, %0, %4\n" | 229 " add %1, %0, %4\n" |
198 " stwcx. %1, 0, %3\n" | 230 " stwcx. %1, 0, %3\n" |
199 " bne- 1b":"=&b"(rv), "=&r"(tmp), "=m"(*atomic) | 231 " bne- 1b" |
200 :"b"(atomic), "r"(value), "m"(*atomic) | 232 : "=&b" (rv), |
201 :"cr0", "memory"); | 233 "=&r" (tmp), |
234 "=m" (*atomic) | |
235 : "b" (atomic), | |
236 "r" (value), | |
237 "m" (*atomic) | |
238 : "cr0", | |
239 "memory"); | |
202 } | 240 } |
203 | 241 |
204 static __inline__ int | 242 static __inline__ int |
205 SDL_atomic_int_xchg_add(volatile int *atomic, int value) | 243 SDL_atomic_int_xchg_add(volatile int* atomic, int value) |
206 { | 244 { |
207 int rv, tmp; | 245 int rv,tmp; |
208 __asm__ __volatile__("1: lwarx %0, 0, %3\n" | 246 __asm__ __volatile__("1: lwarx %0, 0, %3\n" |
209 " add %1, %0, %4\n" | 247 " add %1, %0, %4\n" |
210 " stwcx. %1, 0, %3\n" | 248 " stwcx. %1, 0, %3\n" |
211 " bne- 1b":"=&b"(rv), "=&r"(tmp), "=m"(*atomic) | 249 " bne- 1b" |
212 :"b"(atomic), "r"(value), "m"(*atomic) | 250 : "=&b" (rv), |
213 :"cr0", "memory"); | 251 "=&r" (tmp), |
214 return rv; | 252 "=m" (*atomic) |
253 : "b" (atomic), | |
254 "r" (value), | |
255 "m" (*atomic) | |
256 : "cr0", | |
257 "memory"); | |
258 return rv; | |
215 } | 259 } |
216 | 260 |
217 # if (SIZEOF_VOIDP == 4) | 261 # if (SIZEOF_VOIDP == 4) |
218 static __inline__ SDL_bool | 262 static __inline__ SDL_bool |
219 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 263 SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue) |
220 { | 264 { |
221 int rv; | 265 int rv; |
222 __asm__ __volatile__(" sync\n" | 266 __asm__ __volatile__(" sync\n" |
223 "1: lwarx %0, 0, %1\n" | 267 "1: lwarx %0, 0, %1\n" |
224 " subf. %0, %2, %0\n" | 268 " subf. %0, %2, %0\n" |
225 " bne 2f\n" | 269 " bne 2f\n" |
226 " stwcx. %3, 0, %1\n" | 270 " stwcx. %3, 0, %1\n" |
227 " bne- 1b\n" "2: isync":"=&r"(rv) | 271 " bne- 1b\n" |
228 :"b"(atomic), "r"(oldvalue), "r":"cr0", "memory"); | 272 "2: isync" |
229 return (SDL_bool) (rv == 0); | 273 : "=&r" (rv) |
230 } | 274 : "b" (atomic), |
231 | 275 "r" (oldvalue), |
232 static __inline__ SDL_bool | 276 "r" |
233 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 277 : "cr0", |
234 void *newvalue) | 278 "memory"); |
235 { | 279 return (SDL_bool)(rv == 0); |
236 void *rv; | 280 } |
237 __asm__ __volatile__("sync\n" | 281 |
238 "1: lwarx %0, 0, %1\n" | 282 static __inline__ SDL_bool |
239 " subf. %0, %2, %0\n" | 283 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
240 " bne 2f\n" | 284 { |
241 " stwcx. %3, 0, %1\n" | 285 void* rv; |
242 " bne- 1b\n" "2: isync":"=&r"(rv) | 286 __asm__ __volatile__("sync\n" |
243 :"b"(atomic), "r"(oldvalue), "r"(newvalue) | 287 "1: lwarx %0, 0, %1\n" |
244 :"cr0", "memory"); | 288 " subf. %0, %2, %0\n" |
245 return (SDL_bool) (rv == 0); | 289 " bne 2f\n" |
290 " stwcx. %3, 0, %1\n" | |
291 " bne- 1b\n" | |
292 "2: isync" | |
293 : "=&r" (rv) | |
294 : "b" (atomic), | |
295 "r" (oldvalue), | |
296 "r" (newvalue) | |
297 : "cr0", | |
298 "memory"); | |
299 return (SDL_bool)(rv == 0); | |
246 } | 300 } |
247 # elif (SIZEOF_VOIDP == 8) | 301 # elif (SIZEOF_VOIDP == 8) |
248 static __inline__ SDL_bool | 302 static __inline__ SDL_bool |
249 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 303 SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue) |
250 { | 304 { |
251 int rv; | 305 int rv; |
252 __asm__ __volatile__(" sync\n" | 306 __asm__ __volatile__(" sync\n" |
253 "1: lwarx %0, 0, %1\n" | 307 "1: lwarx %0, 0, %1\n" |
254 " extsw %0, %0\n" | 308 " extsw %0, %0\n" |
255 " subf. %0, %2, %0\n" | 309 " subf. %0, %2, %0\n" |
256 " bne 2f\n" | 310 " bne 2f\n" |
257 " stwcx. %3, 0, %1\n" | 311 " stwcx. %3, 0, %1\n" |
258 " bne- 1b\n" "2: isync":"=&r"(rv) | 312 " bne- 1b\n" |
259 :"b"(atomic), "r"(oldvalue), "r":"cr0", "memory"); | 313 "2: isync" |
260 return (SDL_bool) (rv == 0); | 314 : "=&r" (rv) |
261 } | 315 : "b" (atomic), |
262 | 316 "r" (oldvalue), |
263 static __inline__ SDL_bool | 317 "r" |
264 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 318 : "cr0", |
265 void *newvalue) | 319 "memory"); |
266 { | 320 return (SDL_bool)(rv == 0); |
267 void *rv; | 321 } |
268 __asm__ __volatile__("sync\n" | 322 |
269 "1: ldarx %0, 0, %1\n" | 323 static __inline__ SDL_bool |
270 " subf. %0, %2, %0\n" | 324 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
271 " bne 2f\n" | 325 { |
272 " stdcx. %3, 0, %1\n" | 326 void* rv; |
273 " bne- 1b\n" "2: isync":"=&r"(rv) | 327 __asm__ __volatile__("sync\n" |
274 :"b"(atomic), "r"(oldvalue), "r"(newvalue) | 328 "1: ldarx %0, 0, %1\n" |
275 :"cr0", "memory"); | 329 " subf. %0, %2, %0\n" |
276 return (SDL_bool) (rv == 0); | 330 " bne 2f\n" |
331 " stdcx. %3, 0, %1\n" | |
332 " bne- 1b\n" | |
333 "2: isync" | |
334 : "=&r" (rv) | |
335 : "b" (atomic), | |
336 "r" (oldvalue), | |
337 "r" (newvalue) | |
338 : "cr0", | |
339 "memory"); | |
340 return (SDL_bool)(rv == 0); | |
277 } | 341 } |
278 # else | 342 # else |
279 # error "Your system has an unsupported pointer size" | 343 # error "Your system has an unsupported pointer size" |
280 # endif /* SIZEOF_VOIDP */ | 344 # endif /* SIZEOF_VOIDP */ |
281 #elif defined(__GNUC__) && (defined(__IA64__) || defined(__ia64__)) | 345 #elif defined(__GNUC__) && (defined(__IA64__) || defined(__ia64__)) |
288 (__sync_bool_compare_and_swap((atomic),(oldvalue),(newvalue))) | 352 (__sync_bool_compare_and_swap((atomic),(oldvalue),(newvalue))) |
289 # define SDL_atomic_ptr_cmp_xchg(atomic,oldvalue,newvalue) \ | 353 # define SDL_atomic_ptr_cmp_xchg(atomic,oldvalue,newvalue) \ |
290 (__sync_bool_compare_and_swap((long*)(atomic),(long)(oldvalue),(long)(newvalue))) | 354 (__sync_bool_compare_and_swap((long*)(atomic),(long)(oldvalue),(long)(newvalue))) |
291 #elif defined(__GNUC__) && defined(__LINUX__) && (defined(__mips__) || defined(__MIPS__)) | 355 #elif defined(__GNUC__) && defined(__LINUX__) && (defined(__mips__) || defined(__MIPS__)) |
292 static __inline__ int | 356 static __inline__ int |
293 SDL_atomic_int_xchg_add(volatile int *atomic, int value) | 357 SDL_atomic_int_xchg_add(volatile int* atomic, int value) |
294 { | 358 { |
295 int rv, tmp; | 359 int rv,tmp; |
296 __asm__ __volatile__("1: \n" | 360 __asm__ __volatile__("1: \n" |
297 ".set push \n" | 361 ".set push \n" |
298 ".set mips2 \n" | 362 ".set mips2 \n" |
299 "ll %0,%3 \n" | 363 "ll %0,%3 \n" |
300 "addu %1,%4,%0 \n" | 364 "addu %1,%4,%0 \n" |
301 "sc %1,%2 \n" | 365 "sc %1,%2 \n" |
302 ".set pop \n" | 366 ".set pop \n" |
303 "beqz %1,1b \n":"=&r"(rv), | 367 "beqz %1,1b \n" |
304 "=&r"(tmp), "=m"(*atomic) | 368 : "=&r" (rv), |
305 :"m"(*atomic), "r"(value) | 369 "=&r" (tmp), |
306 :"memory"); | 370 "=m" (*atomic) |
307 return rv; | 371 : "m" (*atomic), |
372 "r" (value) | |
373 : "memory"); | |
374 return rv; | |
308 } | 375 } |
309 | 376 |
310 static __inline__ void | 377 static __inline__ void |
311 SDL_atomic_int_add(volatile int *atomic, int value) | 378 SDL_atomic_int_add(volatile int* atomic, int value) |
312 { | 379 { |
313 int rv; | 380 int rv; |
314 __asm__ __volatile__("1: \n" | 381 __asm__ __volatile__("1: \n" |
315 ".set push \n" | 382 ".set push \n" |
316 ".set mips2 \n" | 383 ".set mips2 \n" |
317 "ll %0,%2 \n" | 384 "ll %0,%2 \n" |
318 "addu %0,%3,%0 \n" | 385 "addu %0,%3,%0 \n" |
319 "sc %0,%1 \n" | 386 "sc %0,%1 \n" |
320 ".set pop \n" | 387 ".set pop \n" |
321 "beqz %0,1b \n":"=&r"(rv), "=m"(*atomic) | 388 "beqz %0,1b \n" |
322 :"m"(*atomic), "r"(value) | 389 : "=&r" (rv), |
323 :"memory"); | 390 "=m" (*atomic) |
324 } | 391 : "m" (*atomic), |
325 | 392 "r" (value) |
326 static __inline__ SDL_bool | 393 : "memory"); |
327 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 394 } |
328 { | 395 |
329 int rv; | 396 static __inline__ SDL_bool |
330 __asm__ __volatile__(" .set push \n" | 397 SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue) |
331 " .set noat \n" | 398 { |
332 " .set mips3 \n" | 399 int rv; |
333 "1: ll %0, %2 \n" | 400 __asm__ __volatile__(" .set push \n" |
334 " bne %0, %z3, 2f \n" | 401 " .set noat \n" |
335 " .set mips0 \n" | 402 " .set mips3 \n" |
336 " move $1, %z4 \n" | 403 "1: ll %0, %2 \n" |
337 " .set mips3 \n" | 404 " bne %0, %z3, 2f \n" |
338 " sc $1, %1 \n" | 405 " .set mips0 \n" |
339 " beqz $1, 1b \n" | 406 " move $1, %z4 \n" |
340 " sync \n" | 407 " .set mips3 \n" |
341 "2: \n" | 408 " sc $1, %1 \n" |
342 " .set pop \n":"=&r"(rv), "=R"(*atomic) | 409 " beqz $1, 1b \n" |
343 :"R"(*atomic), "Jr"(oldvalue), "Jr"(newvalue) | 410 " sync \n" |
344 :"memory"); | 411 "2: \n" |
345 return (SDL_bool) rv; | 412 " .set pop \n" |
346 } | 413 : "=&r" (rv), |
347 | 414 "=R" (*atomic) |
348 static __inline__ SDL_bool | 415 : "R" (*atomic), |
349 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 416 "Jr" (oldvalue), |
350 void *newvalue) | 417 "Jr" (newvalue) |
351 { | 418 : "memory"); |
352 int rv; | 419 return (SDL_bool)rv; |
353 __asm__ __volatile__(" .set push \n" | 420 } |
354 " .set noat \n" " .set mips3 \n" | 421 |
422 static __inline__ SDL_bool | |
423 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) | |
424 { | |
425 int rv; | |
426 __asm__ __volatile__(" .set push \n" | |
427 " .set noat \n" | |
428 " .set mips3 \n" | |
355 # if defined(__mips64) | 429 # if defined(__mips64) |
356 "1: lld %0, %2 \n" | 430 "1: lld %0, %2 \n" |
357 # else | 431 # else |
358 "1: ll %0, %2 \n" | 432 "1: ll %0, %2 \n" |
359 # endif | 433 # endif |
360 " bne %0, %z3, 2f \n" " move $1, %z4 \n" | 434 " bne %0, %z3, 2f \n" |
435 " move $1, %z4 \n" | |
361 # if defined(__mips64) | 436 # if defined(__mips64) |
362 " sc $1, %1 \n" | 437 " sc $1, %1 \n" |
363 # else | 438 # else |
364 " scd $1, %1 \n" | 439 " scd $1, %1 \n" |
365 # endif | 440 # endif |
366 " beqz $1, 1b \n" | 441 " beqz $1, 1b \n" |
367 " sync \n" | 442 " sync \n" |
368 "2: \n" | 443 "2: \n" |
369 " .set pop \n":"=&r"(rv), "=R"(*atomic) | 444 " .set pop \n" |
370 :"R"(*atomic), "Jr"(oldvalue), "Jr"(newvalue) | 445 : "=&r" (rv), |
371 :"memory"); | 446 "=R" (*atomic) |
372 return (SDL_bool) rv; | 447 : "R" (*atomic), |
448 "Jr" (oldvalue), | |
449 "Jr" (newvalue) | |
450 : "memory"); | |
451 return (SDL_bool)rv; | |
373 } | 452 } |
374 #elif defined(__GNUC__) && defined(__m68k__) | 453 #elif defined(__GNUC__) && defined(__m68k__) |
375 static __inline__ int | 454 static __inline__ int |
376 SDL_atomic_int_xchg_add(volatile int *atomic, int value) | 455 SDL_atomic_int_xchg_add(volatile int* atomic, int value) |
377 { | 456 { |
378 int rv = *atomic; | 457 int rv = *atomic; |
379 int tmp; | 458 int tmp; |
380 __asm__ __volatile__("1: move%.l %0,%1 \n" | 459 __asm__ __volatile__("1: move%.l %0,%1 \n" |
381 " add%.l %2,%1 \n" | 460 " add%.l %2,%1 \n" |
382 " cas%.l %0,%1,%3 \n" | 461 " cas%.l %0,%1,%3 \n" |
383 " jbne 1b \n":"=d"(rv), "=&d"(tmp) | 462 " jbne 1b \n" |
384 :"d"(value), "m"(*atomic), "0"(rv) | 463 : "=d" (rv), |
385 :"memory"); | 464 "=&d" (tmp) |
386 return (SDL_bool) rv; | 465 : "d" (value), |
466 "m" (*atomic), | |
467 "0" (rv) | |
468 : "memory"); | |
469 return (SDL_bool)rv; | |
387 } | 470 } |
388 | 471 |
389 static __inline__ void | 472 static __inline__ void |
390 SDL_atomic_int_add(volatile int *atomic, int value) | 473 SDL_atomic_int_add(volatile int* atomic, int value) |
391 { | 474 { |
392 __asm__ __volatile__("add%.l %0,%1"::"id"(value), "m"(*atomic) | 475 __asm__ __volatile__("add%.l %0,%1" |
393 :"memory"); | 476 : |
394 } | 477 : "id" (value), |
395 | 478 "m" (*atomic) |
396 static __inline__ SDL_bool | 479 : "memory"); |
397 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 480 } |
398 { | 481 |
399 char rv; | 482 static __inline__ SDL_bool |
400 int readvalue; | 483 SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue) |
401 __asm__ __volatile__("cas%.l %2,%3,%1\n" | 484 { |
402 "seq %0":"=dm"(rv), "=m"(*atomic), "=d"(readvalue) | 485 char rv; |
403 :"d"(newvalue), "m"(*atomic), "2"(oldvalue)); | 486 int readvalue; |
404 return (SDL_bool) rv; | 487 __asm__ __volatile__("cas%.l %2,%3,%1\n" |
405 } | 488 "seq %0" |
406 | 489 : "=dm" (rv), |
407 static __inline__ SDL_bool | 490 "=m" (*atomic), |
408 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 491 "=d" (readvalue) |
409 void *newvalue) | 492 : "d" (newvalue), |
410 { | 493 "m" (*atomic), |
411 char rv; | 494 "2" (oldvalue)); |
412 int readvalue; | 495 return (SDL_bool)rv; |
413 __asm__ __volatile__("cas%.l %2,%3,%1\n" | 496 } |
414 "seq %0":"=dm"(rv), "=m"(*atomic), "=d"(readvalue) | 497 |
415 :"d"(newvalue), "m"(*atomic), "2"(oldvalue)); | 498 static __inline__ SDL_bool |
416 return (SDL_bool) rv; | 499 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
500 { | |
501 char rv; | |
502 int readvalue; | |
503 __asm__ __volatile__("cas%.l %2,%3,%1\n" | |
504 "seq %0" | |
505 : "=dm" (rv), | |
506 "=m" (*atomic), | |
507 "=d" (readvalue) | |
508 : "d" (newvalue), | |
509 "m" (*atomic), | |
510 "2" (oldvalue)); | |
511 return (SDL_bool)rv; | |
417 } | 512 } |
418 #elif defined(__GNUC__) && defined(__s390__) | 513 #elif defined(__GNUC__) && defined(__s390__) |
419 # define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue) \ | 514 # define ATOMIC_INT_CMP_XCHG(atomic,oldvalue,newvalue) \ |
420 ({ \ | 515 ({ \ |
421 int rv = oldvalue; \ | 516 int rv = oldvalue; \ |
427 : "cc"); \ | 522 : "cc"); \ |
428 rv == oldvalue; \ | 523 rv == oldvalue; \ |
429 }) | 524 }) |
430 # if (SIZEOF_VOIDP == 4) | 525 # if (SIZEOF_VOIDP == 4) |
431 static __inline__ SDL_bool | 526 static __inline__ SDL_bool |
432 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 527 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
433 void *newvalue) | 528 { |
434 { | 529 void* rv = oldvalue; |
435 void *rv = oldvalue; | 530 __asm__ __volatile__("cs %0, %2, %1" |
436 __asm__ __volatile__("cs %0, %2, %1":"+d"(rv), "=Q"(*atomic) | 531 : "+d" (rv), |
437 :"d"(newvalue), "m"(*atomic) | 532 "=Q" (*atomic) |
438 :"cc"); | 533 : "d" (newvalue), |
439 return (SDL_bool) (rv == oldvalue); | 534 "m" (*atomic) |
535 : "cc"); | |
536 return (SDL_bool)(rv == oldvalue); | |
440 } | 537 } |
441 # elif (SIZEOF_VOIDP == 8) | 538 # elif (SIZEOF_VOIDP == 8) |
442 static __inline__ SDL_bool | 539 static __inline__ SDL_bool |
443 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 540 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
444 void *newvalue) | 541 { |
445 { | 542 void* rv = oldvalue; |
446 void *rv = oldvalue; | 543 void** a = atomic; |
447 void **a = atomic; | 544 __asm__ __volatile__("csg %0, %2, %1" |
448 __asm__ __volatile__("csg %0, %2, %1":"+d"(rv), "=Q"(*a) | 545 : "+d" (rv), |
449 :"d"((long) (newvalue)), "m"(*a) | 546 "=Q" (*a) |
450 :"cc"); | 547 : "d" ((long)(newvalue)), |
451 return (SDL_bool) (rv == oldvalue); | 548 "m" (*a) |
549 : "cc"); | |
550 return (SDL_bool)(rv == oldvalue); | |
452 } | 551 } |
453 # else | 552 # else |
454 # error "Your system has an unsupported pointer size" | 553 # error "Your system has an unsupported pointer size" |
455 # endif /* SIZEOF_VOIDP */ | 554 # endif /* SIZEOF_VOIDP */ |
456 #elif defined(__WIN32__) | 555 #elif defined(__WIN32__) |
457 # include <windows.h> | 556 # include <windows.h> |
458 static __inline__ int | 557 static __inline__ int |
459 SDL_atomic_int_xchg_add(volatile int *atomic, int value) | 558 SDL_atomic_int_xchg_add(volatile int* atomic, int value) |
460 { | 559 { |
461 return InterlockedExchangeAdd(atomic, value); | 560 return InterlockedExchangeAdd(atomic, value); |
462 } | 561 } |
463 | 562 |
464 static __inline__ void | 563 static __inline__ void |
465 SDL_atomic_int_add(volatile int *atomic, int value) | 564 SDL_atomic_int_add(volatile int* atomic, int value) |
466 { | 565 { |
467 InterlockedExchangeAdd(atomic, value); | 566 InterlockedExchangeAdd(atomic, value); |
468 } | 567 } |
469 | 568 |
470 # if (WINVER > 0X0400) | 569 # if (WINVER > 0X0400) |
471 static __inline__ SDL_bool | 570 static __inline__ SDL_bool |
472 SDL_atmoic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 571 SDL_atmoic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue) |
473 { | 572 { |
474 return (SDL_bool) (InterlockedCompareExchangePointer((PVOID *) atomic, | 573 return (SDL_bool)(InterlockedCompareExchangePointer((PVOID*)atomic, |
475 (PVOID) newvalue, | 574 (PVOID)newvalue, |
476 (PVOID) oldvalue) == | 575 (PVOID)oldvalue) == oldvalue); |
477 oldvalue); | 576 } |
478 } | 577 |
479 | 578 |
480 | 579 static __inline__ SDL_bool |
481 static __inline__ SDL_bool | 580 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
482 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 581 { |
483 void *newvalue) | 582 return (InterlockedCompareExchangePointer(atomic, newvalue, oldvalue) == oldvalue); |
484 { | |
485 return (InterlockedCompareExchangePointer(atomic, newvalue, oldvalue) == | |
486 oldvalue); | |
487 } | 583 } |
488 # else /* WINVER <= 0x0400 */ | 584 # else /* WINVER <= 0x0400 */ |
489 # if (SIZEOF_VOIDP != 4) | 585 # if (SIZEOF_VOIDP != 4) |
490 # error "InterlockedCompareExchangePointer needed" | 586 # error "InterlockedCompareExchangePointer needed" |
491 # endif | 587 # endif |
492 | 588 |
493 static __inline__ SDL_bool | 589 static __inline__ SDL_bool |
494 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 590 SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue) |
495 { | 591 { |
496 return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == | 592 return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == oldvalue); |
497 oldvalue); | 593 } |
498 } | 594 |
499 | 595 static __inline__ SDL_bool |
500 static __inline__ SDL_bool | 596 SDL_atomic_ptr_cmp_xchg(volatile void** atomic, void* oldvalue, void* newvalue) |
501 SDL_atomic_ptr_cmp_xchg(volatile void **atomic, void *oldvalue, | 597 { |
502 void *newvalue) | 598 return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == oldvalue); |
503 { | |
504 return (InterlockedCompareExchange(atomic, newvalue, oldvalue) == | |
505 oldvalue); | |
506 } | 599 } |
507 # endif | 600 # endif |
508 #else /* when all else fails */ | 601 #else /* when all else fails */ |
509 # define SDL_ATOMIC_OPS_NOT_SUPPORTED | 602 # define SDL_ATOMIC_OPS_NOT_SUPPORTED |
510 # warning "Atomic Ops for this platform not supported!" | 603 # warning "Atomic Ops for this platform not supported!" |
511 static __inline__ int | 604 static __inline__ int |
512 SDL_atomic_int_xchg_add(volatile int *atomic, int value) | 605 SDL_atomic_int_xchg_add(volatile int* atomic, int value) |
513 { | 606 { |
514 int rv = *atomic; | 607 int rv = *atomic; |
515 *(atomic) += value; | 608 *(atomic) += value; |
516 return rv; | 609 return rv; |
517 } | 610 } |
518 | 611 |
519 static __inline__ SDL_bool | 612 static __inline__ SDL_bool |
520 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 613 SDL_atomic_int_cmp_xchg(volatile int* atomic, int oldvalue, int newvalue) |
521 { | 614 { |
522 return (*atomic == oldvalue) ? | 615 return (*atomic == oldvalue) ? |
523 ((*atomic = newvalue), SDL_TRUE) : SDL_FALSE; | 616 ((*atomic = newvalue), SDL_TRUE) : SDL_FALSE; |
524 } | 617 } |
525 | 618 |
526 static __inline__ void | 619 static __inline__ void |
527 SDL_atomic_int_add(volatile int *atomic, int value) | 620 SDL_atomic_int_add(volatile int* atomic, int value) |
528 { | 621 { |
529 *atomic += value; | 622 *atomic += value; |
530 } | 623 } |
531 #endif /* arch & platforms */ | 624 #endif /* arch & platforms */ |
625 | |
626 /* *INDENT-ON* */ | |
532 | 627 |
533 #ifdef ATOMIC_INT_CMP_XCHG | 628 #ifdef ATOMIC_INT_CMP_XCHG |
534 static __inline__ SDL_bool | 629 static __inline__ SDL_bool |
535 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) | 630 SDL_atomic_int_cmp_xchg(volatile int *atomic, int oldvalue, int newvalue) |
536 { | 631 { |