47 inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); }
48 inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); }
49
50 inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); }
51 inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); }
52 inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); }
53
54
55 #ifdef _LP64
56
57 inline void Atomic::store(jlong store_value, jlong* dest) { *dest = store_value; }
58 inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; }
59 inline jlong Atomic::load(volatile jlong* src) { return *src; }
60
61 #else
62
63 extern "C" void _Atomic_move_long_v8(volatile jlong* src, volatile jlong* dst);
64 extern "C" void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst);
65
66 inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) {
67 #ifdef COMPILER2
68 // Compiler2 does not support v8, it is used only for v9.
69 _Atomic_move_long_v9(src, dst);
70 #else
71 // The branch is cheaper then emulated LDD.
72 if (VM_Version::v9_instructions_work()) {
73 _Atomic_move_long_v9(src, dst);
74 } else {
75 _Atomic_move_long_v8(src, dst);
76 }
77 #endif
78 }
79
80 inline jlong Atomic::load(volatile jlong* src) {
81 volatile jlong dest;
82 Atomic_move_long(src, &dest);
83 return dest;
84 }
85
86 inline void Atomic::store(jlong store_value, jlong* dest) {
87 Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest);
88 }
89
90 inline void Atomic::store(jlong store_value, volatile jlong* dest) {
91 Atomic_move_long((volatile jlong*)&store_value, dest);
92 }
93
94 #endif
95
96 #ifdef _GNU_SOURCE
97
192 inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
193 jint rv;
194 __asm__ volatile(
195 " cas [%2], %3, %0"
196 : "=r" (rv)
197 : "0" (exchange_value), "r" (dest), "r" (compare_value)
198 : "memory");
199 return rv;
200 }
201
202 inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
203 #ifdef _LP64
204 jlong rv;
205 __asm__ volatile(
206 " casx [%2], %3, %0"
207 : "=r" (rv)
208 : "0" (exchange_value), "r" (dest), "r" (compare_value)
209 : "memory");
210 return rv;
211 #else //_LP64
212 assert(VM_Version::v9_instructions_work(), "cas only supported on v9");
213 volatile jlong_accessor evl, cvl, rv;
214 evl.long_value = exchange_value;
215 cvl.long_value = compare_value;
216
217 __asm__ volatile(
218 " sllx %2, 32, %2\n\t"
219 " srl %3, 0, %3\n\t"
220 " or %2, %3, %2\n\t"
221 " sllx %5, 32, %5\n\t"
222 " srl %6, 0, %6\n\t"
223 " or %5, %6, %5\n\t"
224 " casx [%4], %5, %2\n\t"
225 " srl %2, 0, %1\n\t"
226 " srlx %2, 32, %0\n\t"
227 : "=r" (rv.words[0]), "=r" (rv.words[1])
228 : "r" (evl.words[0]), "r" (evl.words[1]), "r" (dest), "r" (cvl.words[0]), "r" (cvl.words[1])
229 : "memory");
230
231 return rv.long_value;
232 #endif //_LP64
301 return _Atomic_swap64(exchange_value, dest);
302 #else // _LP64
303 return _Atomic_swap32(exchange_value, dest);
304 #endif // _LP64
305 }
306
307 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
308 return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
309 }
310
311
312 inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
313 return _Atomic_cas32(exchange_value, dest, compare_value);
314 }
315
316 inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
317 #ifdef _LP64
318 // Return 64 bit value in %o0
319 return _Atomic_cas64((intptr_t)exchange_value, (intptr_t *)dest, (intptr_t)compare_value);
320 #else // _LP64
321 assert (VM_Version::v9_instructions_work(), "only supported on v9");
322 // Return 64 bit value in %o0,%o1 by hand
323 return _Atomic_casl(exchange_value, dest, compare_value);
324 #endif // _LP64
325 }
326
327 inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
328 #ifdef _LP64
329 return _Atomic_cas64(exchange_value, dest, compare_value);
330 #else // _LP64
331 return _Atomic_cas32(exchange_value, dest, compare_value);
332 #endif // _LP64
333 }
334
335 inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
336 return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value);
337 }
338
339
340 #else // _LP64 || COMPILER2
341
|
47 inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); }
48 inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); }
49
50 inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); }
51 inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); }
52 inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); }
53
54
55 #ifdef _LP64
56
57 inline void Atomic::store(jlong store_value, jlong* dest) { *dest = store_value; }
58 inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; }
59 inline jlong Atomic::load(volatile jlong* src) { return *src; }
60
61 #else
62
63 extern "C" void _Atomic_move_long_v8(volatile jlong* src, volatile jlong* dst);
64 extern "C" void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst);
65
66 inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) {
67 _Atomic_move_long_v9(src, dst);
68 }
69
70 inline jlong Atomic::load(volatile jlong* src) {
71 volatile jlong dest;
72 Atomic_move_long(src, &dest);
73 return dest;
74 }
75
76 inline void Atomic::store(jlong store_value, jlong* dest) {
77 Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest);
78 }
79
80 inline void Atomic::store(jlong store_value, volatile jlong* dest) {
81 Atomic_move_long((volatile jlong*)&store_value, dest);
82 }
83
84 #endif
85
86 #ifdef _GNU_SOURCE
87
182 inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
183 jint rv;
184 __asm__ volatile(
185 " cas [%2], %3, %0"
186 : "=r" (rv)
187 : "0" (exchange_value), "r" (dest), "r" (compare_value)
188 : "memory");
189 return rv;
190 }
191
192 inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
193 #ifdef _LP64
194 jlong rv;
195 __asm__ volatile(
196 " casx [%2], %3, %0"
197 : "=r" (rv)
198 : "0" (exchange_value), "r" (dest), "r" (compare_value)
199 : "memory");
200 return rv;
201 #else //_LP64
202 volatile jlong_accessor evl, cvl, rv;
203 evl.long_value = exchange_value;
204 cvl.long_value = compare_value;
205
206 __asm__ volatile(
207 " sllx %2, 32, %2\n\t"
208 " srl %3, 0, %3\n\t"
209 " or %2, %3, %2\n\t"
210 " sllx %5, 32, %5\n\t"
211 " srl %6, 0, %6\n\t"
212 " or %5, %6, %5\n\t"
213 " casx [%4], %5, %2\n\t"
214 " srl %2, 0, %1\n\t"
215 " srlx %2, 32, %0\n\t"
216 : "=r" (rv.words[0]), "=r" (rv.words[1])
217 : "r" (evl.words[0]), "r" (evl.words[1]), "r" (dest), "r" (cvl.words[0]), "r" (cvl.words[1])
218 : "memory");
219
220 return rv.long_value;
221 #endif //_LP64
290 return _Atomic_swap64(exchange_value, dest);
291 #else // _LP64
292 return _Atomic_swap32(exchange_value, dest);
293 #endif // _LP64
294 }
295
296 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
297 return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
298 }
299
300
301 inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
302 return _Atomic_cas32(exchange_value, dest, compare_value);
303 }
304
305 inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
306 #ifdef _LP64
307 // Return 64 bit value in %o0
308 return _Atomic_cas64((intptr_t)exchange_value, (intptr_t *)dest, (intptr_t)compare_value);
309 #else // _LP64
310 // Return 64 bit value in %o0,%o1 by hand
311 return _Atomic_casl(exchange_value, dest, compare_value);
312 #endif // _LP64
313 }
314
315 inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
316 #ifdef _LP64
317 return _Atomic_cas64(exchange_value, dest, compare_value);
318 #else // _LP64
319 return _Atomic_cas32(exchange_value, dest, compare_value);
320 #endif // _LP64
321 }
322
323 inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
324 return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value);
325 }
326
327
328 #else // _LP64 || COMPILER2
329
|