Mercurial > sdl-ios-xcode
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) \ |