comparison include/SDL_atomic.h @ 3186:51750b7a966f

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