comparison src/os_cpu/aix_ppc/vm/atomic_aix_ppc.inline.hpp @ 17793:c668f307a4c0

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
17792:4345c6a92f35 17793:c668f307a4c0
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