Mercurial > hg > graal-compiler
comparison src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp @ 14451:b858620b0081
8031319: PPC64: Some fixes in ppc and aix coding.
Reviewed-by: kvn
author | goetz |
---|---|
date | Tue, 07 Jan 2014 17:24:59 +0100 |
parents | 666e6ce3976c |
children | ce8f6bb717c9 |
comparison
equal
deleted
inserted
replaced
14450:c3efa8868779 | 14451:b858620b0081 |
---|---|
51 inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } | 51 inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } |
52 inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } | 52 inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } |
53 | 53 |
54 inline jlong Atomic::load(volatile jlong* src) { return *src; } | 54 inline jlong Atomic::load(volatile jlong* src) { return *src; } |
55 | 55 |
56 /* | 56 // |
57 machine barrier instructions: | 57 // machine barrier instructions: |
58 | 58 // |
59 - ppc_sync two-way memory barrier, aka fence | 59 // - ppc_sync two-way memory barrier, aka fence |
60 - ppc_lwsync orders Store|Store, | 60 // - ppc_lwsync orders Store|Store, |
61 Load|Store, | 61 // Load|Store, |
62 Load|Load, | 62 // Load|Load, |
63 but not Store|Load | 63 // but not Store|Load |
64 - ppc_eieio orders memory accesses for device memory (only) | 64 // - ppc_eieio orders memory accesses for device memory (only) |
65 - ppc_isync invalidates speculatively executed instructions | 65 // - ppc_isync invalidates speculatively executed instructions |
66 From the POWER ISA 2.06 documentation: | 66 // From the POWER ISA 2.06 documentation: |
67 "[...] an isync instruction prevents the execution of | 67 // "[...] an isync instruction prevents the execution of |
68 instructions following the isync until instructions | 68 // instructions following the isync until instructions |
69 preceding the isync have completed, [...]" | 69 // preceding the isync have completed, [...]" |
70 From IBM's AIX assembler reference: | 70 // From IBM's AIX assembler reference: |
71 "The isync [...] instructions causes the processor to | 71 // "The isync [...] instructions causes the processor to |
72 refetch any instructions that might have been fetched | 72 // refetch any instructions that might have been fetched |
73 prior to the isync instruction. The instruction isync | 73 // prior to the isync instruction. The instruction isync |
74 causes the processor to wait for all previous instructions | 74 // causes the processor to wait for all previous instructions |
75 to complete. Then any instructions already fetched are | 75 // to complete. Then any instructions already fetched are |
76 discarded and instruction processing continues in the | 76 // discarded and instruction processing continues in the |
77 environment established by the previous instructions." | 77 // environment established by the previous instructions." |
78 | 78 // |
79 semantic barrier instructions: | 79 // semantic barrier instructions: |
80 (as defined in orderAccess.hpp) | 80 // (as defined in orderAccess.hpp) |
81 | 81 // |
82 - ppc_release orders Store|Store, (maps to ppc_lwsync) | 82 // - ppc_release orders Store|Store, (maps to ppc_lwsync) |
83 Load|Store | 83 // Load|Store |
84 - ppc_acquire orders Load|Store, (maps to ppc_lwsync) | 84 // - ppc_acquire orders Load|Store, (maps to ppc_lwsync) |
85 Load|Load | 85 // Load|Load |
86 - ppc_fence orders Store|Store, (maps to ppc_sync) | 86 // - ppc_fence orders Store|Store, (maps to ppc_sync) |
87 Load|Store, | 87 // Load|Store, |
88 Load|Load, | 88 // Load|Load, |
89 Store|Load | 89 // Store|Load |
90 */ | 90 // |
91 | 91 |
92 #define strasm_ppc_sync "\n sync \n" | 92 #define strasm_sync "\n sync \n" |
93 #define strasm_ppc_lwsync "\n lwsync \n" | 93 #define strasm_lwsync "\n lwsync \n" |
94 #define strasm_ppc_isync "\n isync \n" | 94 #define strasm_isync "\n isync \n" |
95 #define strasm_ppc_release strasm_ppc_lwsync | 95 #define strasm_release strasm_lwsync |
96 #define strasm_ppc_acquire strasm_ppc_lwsync | 96 #define strasm_acquire strasm_lwsync |
97 #define strasm_ppc_fence strasm_ppc_sync | 97 #define strasm_fence strasm_sync |
98 #define strasm_ppc_nobarrier "" | 98 #define strasm_nobarrier "" |
99 #define strasm_ppc_nobarrier_clobber_memory "" | 99 #define strasm_nobarrier_clobber_memory "" |
100 | 100 |
101 inline jint Atomic::add (jint add_value, volatile jint* dest) { | 101 inline jint Atomic::add (jint add_value, volatile jint* dest) { |
102 | 102 |
103 unsigned int result; | 103 unsigned int result; |
104 | 104 |
105 __asm__ __volatile__ ( | 105 __asm__ __volatile__ ( |
106 strasm_ppc_lwsync | 106 strasm_lwsync |
107 "1: lwarx %0, 0, %2 \n" | 107 "1: lwarx %0, 0, %2 \n" |
108 " add %0, %0, %1 \n" | 108 " add %0, %0, %1 \n" |
109 " stwcx. %0, 0, %2 \n" | 109 " stwcx. %0, 0, %2 \n" |
110 " bne- 1b \n" | 110 " bne- 1b \n" |
111 strasm_ppc_isync | 111 strasm_isync |
112 : /*%0*/"=&r" (result) | 112 : /*%0*/"=&r" (result) |
113 : /*%1*/"r" (add_value), /*%2*/"r" (dest) | 113 : /*%1*/"r" (add_value), /*%2*/"r" (dest) |
114 : "cc", "memory" ); | 114 : "cc", "memory" ); |
115 | 115 |
116 return (jint) result; | 116 return (jint) result; |
120 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { | 120 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { |
121 | 121 |
122 long result; | 122 long result; |
123 | 123 |
124 __asm__ __volatile__ ( | 124 __asm__ __volatile__ ( |
125 strasm_ppc_lwsync | 125 strasm_lwsync |
126 "1: ldarx %0, 0, %2 \n" | 126 "1: ldarx %0, 0, %2 \n" |
127 " add %0, %0, %1 \n" | 127 " add %0, %0, %1 \n" |
128 " stdcx. %0, 0, %2 \n" | 128 " stdcx. %0, 0, %2 \n" |
129 " bne- 1b \n" | 129 " bne- 1b \n" |
130 strasm_ppc_isync | 130 strasm_isync |
131 : /*%0*/"=&r" (result) | 131 : /*%0*/"=&r" (result) |
132 : /*%1*/"r" (add_value), /*%2*/"r" (dest) | 132 : /*%1*/"r" (add_value), /*%2*/"r" (dest) |
133 : "cc", "memory" ); | 133 : "cc", "memory" ); |
134 | 134 |
135 return (intptr_t) result; | 135 return (intptr_t) result; |
143 inline void Atomic::inc (volatile jint* dest) { | 143 inline void Atomic::inc (volatile jint* dest) { |
144 | 144 |
145 unsigned int temp; | 145 unsigned int temp; |
146 | 146 |
147 __asm__ __volatile__ ( | 147 __asm__ __volatile__ ( |
148 strasm_ppc_nobarrier | 148 strasm_nobarrier |
149 "1: lwarx %0, 0, %2 \n" | 149 "1: lwarx %0, 0, %2 \n" |
150 " addic %0, %0, 1 \n" | 150 " addic %0, %0, 1 \n" |
151 " stwcx. %0, 0, %2 \n" | 151 " stwcx. %0, 0, %2 \n" |
152 " bne- 1b \n" | 152 " bne- 1b \n" |
153 strasm_ppc_nobarrier | 153 strasm_nobarrier |
154 : /*%0*/"=&r" (temp), "=m" (*dest) | 154 : /*%0*/"=&r" (temp), "=m" (*dest) |
155 : /*%2*/"r" (dest), "m" (*dest) | 155 : /*%2*/"r" (dest), "m" (*dest) |
156 : "cc" strasm_ppc_nobarrier_clobber_memory); | 156 : "cc" strasm_nobarrier_clobber_memory); |
157 | 157 |
158 } | 158 } |
159 | 159 |
160 inline void Atomic::inc_ptr(volatile intptr_t* dest) { | 160 inline void Atomic::inc_ptr(volatile intptr_t* dest) { |
161 | 161 |
162 long temp; | 162 long temp; |
163 | 163 |
164 __asm__ __volatile__ ( | 164 __asm__ __volatile__ ( |
165 strasm_ppc_nobarrier | 165 strasm_nobarrier |
166 "1: ldarx %0, 0, %2 \n" | 166 "1: ldarx %0, 0, %2 \n" |
167 " addic %0, %0, 1 \n" | 167 " addic %0, %0, 1 \n" |
168 " stdcx. %0, 0, %2 \n" | 168 " stdcx. %0, 0, %2 \n" |
169 " bne- 1b \n" | 169 " bne- 1b \n" |
170 strasm_ppc_nobarrier | 170 strasm_nobarrier |
171 : /*%0*/"=&r" (temp), "=m" (*dest) | 171 : /*%0*/"=&r" (temp), "=m" (*dest) |
172 : /*%2*/"r" (dest), "m" (*dest) | 172 : /*%2*/"r" (dest), "m" (*dest) |
173 : "cc" strasm_ppc_nobarrier_clobber_memory); | 173 : "cc" strasm_nobarrier_clobber_memory); |
174 | 174 |
175 } | 175 } |
176 | 176 |
177 inline void Atomic::inc_ptr(volatile void* dest) { | 177 inline void Atomic::inc_ptr(volatile void* dest) { |
178 inc_ptr((volatile intptr_t*)dest); | 178 inc_ptr((volatile intptr_t*)dest); |
182 inline void Atomic::dec (volatile jint* dest) { | 182 inline void Atomic::dec (volatile jint* dest) { |
183 | 183 |
184 unsigned int temp; | 184 unsigned int temp; |
185 | 185 |
186 __asm__ __volatile__ ( | 186 __asm__ __volatile__ ( |
187 strasm_ppc_nobarrier | 187 strasm_nobarrier |
188 "1: lwarx %0, 0, %2 \n" | 188 "1: lwarx %0, 0, %2 \n" |
189 " addic %0, %0, -1 \n" | 189 " addic %0, %0, -1 \n" |
190 " stwcx. %0, 0, %2 \n" | 190 " stwcx. %0, 0, %2 \n" |
191 " bne- 1b \n" | 191 " bne- 1b \n" |
192 strasm_ppc_nobarrier | 192 strasm_nobarrier |
193 : /*%0*/"=&r" (temp), "=m" (*dest) | 193 : /*%0*/"=&r" (temp), "=m" (*dest) |
194 : /*%2*/"r" (dest), "m" (*dest) | 194 : /*%2*/"r" (dest), "m" (*dest) |
195 : "cc" strasm_ppc_nobarrier_clobber_memory); | 195 : "cc" strasm_nobarrier_clobber_memory); |
196 | 196 |
197 } | 197 } |
198 | 198 |
199 inline void Atomic::dec_ptr(volatile intptr_t* dest) { | 199 inline void Atomic::dec_ptr(volatile intptr_t* dest) { |
200 | 200 |
201 long temp; | 201 long temp; |
202 | 202 |
203 __asm__ __volatile__ ( | 203 __asm__ __volatile__ ( |
204 strasm_ppc_nobarrier | 204 strasm_nobarrier |
205 "1: ldarx %0, 0, %2 \n" | 205 "1: ldarx %0, 0, %2 \n" |
206 " addic %0, %0, -1 \n" | 206 " addic %0, %0, -1 \n" |
207 " stdcx. %0, 0, %2 \n" | 207 " stdcx. %0, 0, %2 \n" |
208 " bne- 1b \n" | 208 " bne- 1b \n" |
209 strasm_ppc_nobarrier | 209 strasm_nobarrier |
210 : /*%0*/"=&r" (temp), "=m" (*dest) | 210 : /*%0*/"=&r" (temp), "=m" (*dest) |
211 : /*%2*/"r" (dest), "m" (*dest) | 211 : /*%2*/"r" (dest), "m" (*dest) |
212 : "cc" strasm_ppc_nobarrier_clobber_memory); | 212 : "cc" strasm_nobarrier_clobber_memory); |
213 | 213 |
214 } | 214 } |
215 | 215 |
216 inline void Atomic::dec_ptr(volatile void* dest) { | 216 inline void Atomic::dec_ptr(volatile void* dest) { |
217 dec_ptr((volatile intptr_t*)dest); | 217 dec_ptr((volatile intptr_t*)dest); |
225 unsigned int old_value; | 225 unsigned int old_value; |
226 const uint64_t zero = 0; | 226 const uint64_t zero = 0; |
227 | 227 |
228 __asm__ __volatile__ ( | 228 __asm__ __volatile__ ( |
229 /* lwsync */ | 229 /* lwsync */ |
230 strasm_ppc_lwsync | 230 strasm_lwsync |
231 /* atomic loop */ | 231 /* atomic loop */ |
232 "1: \n" | 232 "1: \n" |
233 " lwarx %[old_value], %[dest], %[zero] \n" | 233 " lwarx %[old_value], %[dest], %[zero] \n" |
234 " stwcx. %[exchange_value], %[dest], %[zero] \n" | 234 " stwcx. %[exchange_value], %[dest], %[zero] \n" |
235 " bne- 1b \n" | 235 " bne- 1b \n" |
236 /* isync */ | 236 /* isync */ |
237 strasm_ppc_sync | 237 strasm_sync |
238 /* exit */ | 238 /* exit */ |
239 "2: \n" | 239 "2: \n" |
240 /* out */ | 240 /* out */ |
241 : [old_value] "=&r" (old_value), | 241 : [old_value] "=&r" (old_value), |
242 "=m" (*dest) | 242 "=m" (*dest) |
261 long old_value; | 261 long old_value; |
262 const uint64_t zero = 0; | 262 const uint64_t zero = 0; |
263 | 263 |
264 __asm__ __volatile__ ( | 264 __asm__ __volatile__ ( |
265 /* lwsync */ | 265 /* lwsync */ |
266 strasm_ppc_lwsync | 266 strasm_lwsync |
267 /* atomic loop */ | 267 /* atomic loop */ |
268 "1: \n" | 268 "1: \n" |
269 " ldarx %[old_value], %[dest], %[zero] \n" | 269 " ldarx %[old_value], %[dest], %[zero] \n" |
270 " stdcx. %[exchange_value], %[dest], %[zero] \n" | 270 " stdcx. %[exchange_value], %[dest], %[zero] \n" |
271 " bne- 1b \n" | 271 " bne- 1b \n" |
272 /* isync */ | 272 /* isync */ |
273 strasm_ppc_sync | 273 strasm_sync |
274 /* exit */ | 274 /* exit */ |
275 "2: \n" | 275 "2: \n" |
276 /* out */ | 276 /* out */ |
277 : [old_value] "=&r" (old_value), | 277 : [old_value] "=&r" (old_value), |
278 "=m" (*dest) | 278 "=m" (*dest) |
302 unsigned int old_value; | 302 unsigned int old_value; |
303 const uint64_t zero = 0; | 303 const uint64_t zero = 0; |
304 | 304 |
305 __asm__ __volatile__ ( | 305 __asm__ __volatile__ ( |
306 /* fence */ | 306 /* fence */ |
307 strasm_ppc_sync | 307 strasm_sync |
308 /* simple guard */ | 308 /* simple guard */ |
309 " lwz %[old_value], 0(%[dest]) \n" | 309 " lwz %[old_value], 0(%[dest]) \n" |
310 " cmpw %[compare_value], %[old_value] \n" | 310 " cmpw %[compare_value], %[old_value] \n" |
311 " bne- 2f \n" | 311 " bne- 2f \n" |
312 /* atomic loop */ | 312 /* atomic loop */ |
315 " cmpw %[compare_value], %[old_value] \n" | 315 " cmpw %[compare_value], %[old_value] \n" |
316 " bne- 2f \n" | 316 " bne- 2f \n" |
317 " stwcx. %[exchange_value], %[dest], %[zero] \n" | 317 " stwcx. %[exchange_value], %[dest], %[zero] \n" |
318 " bne- 1b \n" | 318 " bne- 1b \n" |
319 /* acquire */ | 319 /* acquire */ |
320 strasm_ppc_sync | 320 strasm_sync |
321 /* exit */ | 321 /* exit */ |
322 "2: \n" | 322 "2: \n" |
323 /* out */ | 323 /* out */ |
324 : [old_value] "=&r" (old_value), | 324 : [old_value] "=&r" (old_value), |
325 "=m" (*dest) | 325 "=m" (*dest) |
346 long old_value; | 346 long old_value; |
347 const uint64_t zero = 0; | 347 const uint64_t zero = 0; |
348 | 348 |
349 __asm__ __volatile__ ( | 349 __asm__ __volatile__ ( |
350 /* fence */ | 350 /* fence */ |
351 strasm_ppc_sync | 351 strasm_sync |
352 /* simple guard */ | 352 /* simple guard */ |
353 " ld %[old_value], 0(%[dest]) \n" | 353 " ld %[old_value], 0(%[dest]) \n" |
354 " cmpd %[compare_value], %[old_value] \n" | 354 " cmpd %[compare_value], %[old_value] \n" |
355 " bne- 2f \n" | 355 " bne- 2f \n" |
356 /* atomic loop */ | 356 /* atomic loop */ |
359 " cmpd %[compare_value], %[old_value] \n" | 359 " cmpd %[compare_value], %[old_value] \n" |
360 " bne- 2f \n" | 360 " bne- 2f \n" |
361 " stdcx. %[exchange_value], %[dest], %[zero] \n" | 361 " stdcx. %[exchange_value], %[dest], %[zero] \n" |
362 " bne- 1b \n" | 362 " bne- 1b \n" |
363 /* acquire */ | 363 /* acquire */ |
364 strasm_ppc_sync | 364 strasm_sync |
365 /* exit */ | 365 /* exit */ |
366 "2: \n" | 366 "2: \n" |
367 /* out */ | 367 /* out */ |
368 : [old_value] "=&r" (old_value), | 368 : [old_value] "=&r" (old_value), |
369 "=m" (*dest) | 369 "=m" (*dest) |
387 | 387 |
388 inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { | 388 inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { |
389 return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); | 389 return (void*)cmpxchg((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value); |
390 } | 390 } |
391 | 391 |
392 #undef strasm_ppc_sync | 392 #undef strasm_sync |
393 #undef strasm_ppc_lwsync | 393 #undef strasm_lwsync |
394 #undef strasm_ppc_isync | 394 #undef strasm_isync |
395 #undef strasm_ppc_release | 395 #undef strasm_release |
396 #undef strasm_ppc_acquire | 396 #undef strasm_acquire |
397 #undef strasm_ppc_fence | 397 #undef strasm_fence |
398 #undef strasm_ppc_nobarrier | 398 #undef strasm_nobarrier |
399 #undef strasm_ppc_nobarrier_clobber_memory | 399 #undef strasm_nobarrier_clobber_memory |
400 | 400 |
401 #endif // OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP | 401 #endif // OS_CPU_AIX_OJDKPPC_VM_ATOMIC_AIX_PPC_INLINE_HPP |