hotspot/src/os_cpu/linux_ppc/vm/atomic_linux_ppc.inline.hpp
changeset 35063 cb24277be2e7
parent 25715 d5a8dbdc5150
child 35594 cc13089c6327
equal deleted inserted replaced
35062:f3e0dee91918 35063:cb24277be2e7
   289 
   289 
   290 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
   290 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
   291   return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
   291   return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
   292 }
   292 }
   293 
   293 
       
   294 #define VM_HAS_SPECIALIZED_CMPXCHG_BYTE
       
   295 inline jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
       
   296 
       
   297   // Note that cmpxchg guarantees a two-way memory barrier across
       
   298   // the cmpxchg, so it's really a a 'fence_cmpxchg_acquire'
       
   299   // (see atomic.hpp).
       
   300 
       
   301   // Using 32 bit internally.
       
   302   volatile int *dest_base = (volatile int*)((uintptr_t)dest & ~3);
       
   303 
       
   304 #ifdef VM_LITTLE_ENDIAN
       
   305   const unsigned int shift_amount        = ((uintptr_t)dest & 3) * 8;
       
   306 #else
       
   307   const unsigned int shift_amount        = ((~(uintptr_t)dest) & 3) * 8;
       
   308 #endif
       
   309   const unsigned int masked_compare_val  = ((unsigned int)(unsigned char)compare_value),
       
   310                      masked_exchange_val = ((unsigned int)(unsigned char)exchange_value),
       
   311                      xor_value           = (masked_compare_val ^ masked_exchange_val) << shift_amount;
       
   312 
       
   313   unsigned int old_value, value32;
       
   314 
       
   315   __asm__ __volatile__ (
       
   316     /* fence */
       
   317     strasm_sync
       
   318     /* simple guard */
       
   319     "   lbz     %[old_value], 0(%[dest])                  \n"
       
   320     "   cmpw    %[masked_compare_val], %[old_value]       \n"
       
   321     "   bne-    2f                                        \n"
       
   322     /* atomic loop */
       
   323     "1:                                                   \n"
       
   324     "   lwarx   %[value32], 0, %[dest_base]               \n"
       
   325     /* extract byte and compare */
       
   326     "   srd     %[old_value], %[value32], %[shift_amount] \n"
       
   327     "   clrldi  %[old_value], %[old_value], 56            \n"
       
   328     "   cmpw    %[masked_compare_val], %[old_value]       \n"
       
   329     "   bne-    2f                                        \n"
       
   330     /* replace byte and try to store */
       
   331     "   xor     %[value32], %[xor_value], %[value32]      \n"
       
   332     "   stwcx.  %[value32], 0, %[dest_base]               \n"
       
   333     "   bne-    1b                                        \n"
       
   334     /* acquire */
       
   335     strasm_sync
       
   336     /* exit */
       
   337     "2:                                                   \n"
       
   338     /* out */
       
   339     : [old_value]           "=&r"   (old_value),
       
   340       [value32]             "=&r"   (value32),
       
   341                             "=m"    (*dest),
       
   342                             "=m"    (*dest_base)
       
   343     /* in */
       
   344     : [dest]                "b"     (dest),
       
   345       [dest_base]           "b"     (dest_base),
       
   346       [shift_amount]        "r"     (shift_amount),
       
   347       [masked_compare_val]  "r"     (masked_compare_val),
       
   348       [xor_value]           "r"     (xor_value),
       
   349                             "m"     (*dest),
       
   350                             "m"     (*dest_base)
       
   351     /* clobber */
       
   352     : "cc",
       
   353       "memory"
       
   354     );
       
   355 
       
   356   return (jbyte)(unsigned char)old_value;
       
   357 }
       
   358 
   294 inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) {
   359 inline jint Atomic::cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) {
   295 
   360 
   296   // Note that cmpxchg guarantees a two-way memory barrier across
   361   // Note that cmpxchg guarantees a two-way memory barrier across
   297   // the cmpxchg, so it's really a a 'fence_cmpxchg_acquire'
   362   // the cmpxchg, so it's really a a 'fence_cmpxchg_acquire'
   298   // (see atomic.hpp).
   363   // (see atomic.hpp).