src/hotspot/os_cpu/linux_s390/atomic_linux_s390.hpp
changeset 47552 8a3599d60996
parent 47216 71c04702a3d5
child 47578 09c41c4913d9
equal deleted inserted replaced
47551:4d034d861e13 47552:8a3599d60996
   190 
   190 
   191   return upd;
   191   return upd;
   192 }
   192 }
   193 
   193 
   194 
   194 
   195 //------------
       
   196 // Atomic::inc
       
   197 //------------
       
   198 // These methods force the value in memory to be incremented (augmented by 1).
       
   199 // Both, memory value and increment, are treated as 32bit signed binary integers.
       
   200 // No overflow exceptions are recognized, and the condition code does not hold
       
   201 // information about the value in memory.
       
   202 //
       
   203 // The value in memory is updated by using a compare-and-swap instruction. The
       
   204 // instruction is retried as often as required.
       
   205 
       
   206 inline void Atomic::inc(volatile jint* dest) {
       
   207   unsigned int old, upd;
       
   208 
       
   209   if (VM_Version::has_LoadAndALUAtomicV1()) {
       
   210 //  tty->print_cr("Atomic::inc     called... dest @%p", dest);
       
   211     __asm__ __volatile__ (
       
   212       "   LGHI     2,1                     \n\t" // load increment
       
   213       "   LA       3,%[mem]                \n\t" // force data address into ARG2
       
   214 //    "   LAA      %[upd],%[inc],%[mem]    \n\t" // increment and get old value
       
   215 //    "   LAA      2,2,0(3)                \n\t" // actually coded instruction
       
   216       "   .byte    0xeb                    \n\t" // LAA main opcode
       
   217       "   .byte    0x22                    \n\t" // R1,R3
       
   218       "   .byte    0x30                    \n\t" // R2,disp1
       
   219       "   .byte    0x00                    \n\t" // disp2,disp3
       
   220       "   .byte    0x00                    \n\t" // disp4,disp5
       
   221       "   .byte    0xf8                    \n\t" // LAA minor opcode
       
   222       "   AGHI     2,1                     \n\t" // calc new value in register
       
   223       "   LR       %[upd],2                \n\t" // move to result register
       
   224       //---<  outputs  >---
       
   225       : [upd]  "=&d" (upd)    // write-only, updated counter value
       
   226       , [mem]  "+Q"  (*dest)  // read/write, memory to be updated atomically
       
   227       //---<  inputs  >---
       
   228       :
       
   229 //    : [inc]  "a"   (inc)    // read-only.
       
   230       //---<  clobbered  >---
       
   231       : "cc", "r2", "r3", "memory"
       
   232     );
       
   233   } else {
       
   234     __asm__ __volatile__ (
       
   235       "   LLGF     %[old],%[mem]           \n\t" // get old value
       
   236       "0: LA       %[upd],1(,%[old])       \n\t" // calc result
       
   237       "   CS       %[old],%[upd],%[mem]    \n\t" // try to xchg res with mem
       
   238       "   JNE      0b                      \n\t" // no success? -> retry
       
   239       //---<  outputs  >---
       
   240       : [old] "=&a" (old)    // write-only, old counter value
       
   241       , [upd] "=&d" (upd)    // write-only, updated counter value
       
   242       , [mem] "+Q"  (*dest)  // read/write, memory to be updated atomically
       
   243       //---<  inputs  >---
       
   244       :
       
   245       //---<  clobbered  >---
       
   246       : "cc", "memory"
       
   247     );
       
   248   }
       
   249 }
       
   250 
       
   251 inline void Atomic::inc_ptr(volatile intptr_t* dest) {
       
   252   unsigned long old, upd;
       
   253 
       
   254   if (VM_Version::has_LoadAndALUAtomicV1()) {
       
   255     __asm__ __volatile__ (
       
   256       "   LGHI     2,1                     \n\t" // load increment
       
   257       "   LA       3,%[mem]                \n\t" // force data address into ARG2
       
   258 //    "   LAAG     %[upd],%[inc],%[mem]    \n\t" // increment and get old value
       
   259 //    "   LAAG     2,2,0(3)                \n\t" // actually coded instruction
       
   260       "   .byte    0xeb                    \n\t" // LAA main opcode
       
   261       "   .byte    0x22                    \n\t" // R1,R3
       
   262       "   .byte    0x30                    \n\t" // R2,disp1
       
   263       "   .byte    0x00                    \n\t" // disp2,disp3
       
   264       "   .byte    0x00                    \n\t" // disp4,disp5
       
   265       "   .byte    0xe8                    \n\t" // LAA minor opcode
       
   266       "   AGHI     2,1                     \n\t" // calc new value in register
       
   267       "   LR       %[upd],2                \n\t" // move to result register
       
   268       //---<  outputs  >---
       
   269       : [upd]  "=&d" (upd)    // write-only, updated counter value
       
   270       , [mem]  "+Q"  (*dest)  // read/write, memory to be updated atomically
       
   271       //---<  inputs  >---
       
   272       :
       
   273 //    : [inc]  "a"   (inc)    // read-only.
       
   274       //---<  clobbered  >---
       
   275       : "cc", "r2", "r3", "memory"
       
   276     );
       
   277   } else {
       
   278     __asm__ __volatile__ (
       
   279       "   LG       %[old],%[mem]           \n\t" // get old value
       
   280       "0: LA       %[upd],1(,%[old])       \n\t" // calc result
       
   281       "   CSG      %[old],%[upd],%[mem]    \n\t" // try to xchg res with mem
       
   282       "   JNE      0b                      \n\t" // no success? -> retry
       
   283       //---<  outputs  >---
       
   284       : [old] "=&a" (old)    // write-only, old counter value
       
   285       , [upd] "=&d" (upd)    // write-only, updated counter value
       
   286       , [mem] "+Q"  (*dest)  // read/write, memory to be updated atomically
       
   287       //---<  inputs  >---
       
   288       :
       
   289       //---<  clobbered  >---
       
   290       : "cc", "memory"
       
   291     );
       
   292   }
       
   293 }
       
   294 
       
   295 inline void Atomic::inc_ptr(volatile void* dest) {
       
   296   inc_ptr((volatile intptr_t*)dest);
       
   297 }
       
   298 
       
   299 //------------
       
   300 // Atomic::dec
       
   301 //------------
       
   302 // These methods force the value in memory to be decremented (augmented by -1).
       
   303 // Both, memory value and decrement, are treated as 32bit signed binary integers.
       
   304 // No overflow exceptions are recognized, and the condition code does not hold
       
   305 // information about the value in memory.
       
   306 //
       
   307 // The value in memory is updated by using a compare-and-swap instruction. The
       
   308 // instruction is retried as often as required.
       
   309 
       
   310 inline void Atomic::dec(volatile jint* dest) {
       
   311   unsigned int old, upd;
       
   312 
       
   313   if (VM_Version::has_LoadAndALUAtomicV1()) {
       
   314     __asm__ __volatile__ (
       
   315       "   LGHI     2,-1                    \n\t" // load increment
       
   316       "   LA       3,%[mem]                \n\t" // force data address into ARG2
       
   317 //    "   LAA      %[upd],%[inc],%[mem]    \n\t" // increment and get old value
       
   318 //    "   LAA      2,2,0(3)                \n\t" // actually coded instruction
       
   319       "   .byte    0xeb                    \n\t" // LAA main opcode
       
   320       "   .byte    0x22                    \n\t" // R1,R3
       
   321       "   .byte    0x30                    \n\t" // R2,disp1
       
   322       "   .byte    0x00                    \n\t" // disp2,disp3
       
   323       "   .byte    0x00                    \n\t" // disp4,disp5
       
   324       "   .byte    0xf8                    \n\t" // LAA minor opcode
       
   325       "   AGHI     2,-1                    \n\t" // calc new value in register
       
   326       "   LR       %[upd],2                \n\t" // move to result register
       
   327       //---<  outputs  >---
       
   328       : [upd]  "=&d" (upd)    // write-only, updated counter value
       
   329       , [mem]  "+Q"  (*dest)  // read/write, memory to be updated atomically
       
   330       //---<  inputs  >---
       
   331       :
       
   332 //    : [inc]  "a"   (inc)    // read-only.
       
   333       //---<  clobbered  >---
       
   334       : "cc", "r2", "r3", "memory"
       
   335     );
       
   336   } else {
       
   337     __asm__ __volatile__ (
       
   338       "   LLGF     %[old],%[mem]           \n\t" // get old value
       
   339   // LAY not supported by inline assembler
       
   340   //  "0: LAY      %[upd],-1(,%[old])      \n\t" // calc result
       
   341       "0: LR       %[upd],%[old]           \n\t" // calc result
       
   342       "   AHI      %[upd],-1               \n\t"
       
   343       "   CS       %[old],%[upd],%[mem]    \n\t" // try to xchg res with mem
       
   344       "   JNE      0b                      \n\t" // no success? -> retry
       
   345       //---<  outputs  >---
       
   346       : [old] "=&a" (old)    // write-only, old counter value
       
   347       , [upd] "=&d" (upd)    // write-only, updated counter value
       
   348       , [mem] "+Q"  (*dest)  // read/write, memory to be updated atomically
       
   349       //---<  inputs  >---
       
   350       :
       
   351       //---<  clobbered  >---
       
   352       : "cc", "memory"
       
   353     );
       
   354   }
       
   355 }
       
   356 
       
   357 inline void Atomic::dec_ptr(volatile intptr_t* dest) {
       
   358   unsigned long old, upd;
       
   359 
       
   360   if (VM_Version::has_LoadAndALUAtomicV1()) {
       
   361     __asm__ __volatile__ (
       
   362       "   LGHI     2,-1                    \n\t" // load increment
       
   363       "   LA       3,%[mem]                \n\t" // force data address into ARG2
       
   364 //    "   LAAG     %[upd],%[inc],%[mem]    \n\t" // increment and get old value
       
   365 //    "   LAAG     2,2,0(3)                \n\t" // actually coded instruction
       
   366       "   .byte    0xeb                    \n\t" // LAA main opcode
       
   367       "   .byte    0x22                    \n\t" // R1,R3
       
   368       "   .byte    0x30                    \n\t" // R2,disp1
       
   369       "   .byte    0x00                    \n\t" // disp2,disp3
       
   370       "   .byte    0x00                    \n\t" // disp4,disp5
       
   371       "   .byte    0xe8                    \n\t" // LAA minor opcode
       
   372       "   AGHI     2,-1                    \n\t" // calc new value in register
       
   373       "   LR       %[upd],2                \n\t" // move to result register
       
   374       //---<  outputs  >---
       
   375       : [upd]  "=&d" (upd)    // write-only, updated counter value
       
   376       , [mem]  "+Q"  (*dest)  // read/write, memory to be updated atomically
       
   377       //---<  inputs  >---
       
   378       :
       
   379 //    : [inc]  "a"   (inc)    // read-only.
       
   380       //---<  clobbered  >---
       
   381       : "cc", "r2", "r3", "memory"
       
   382     );
       
   383   } else {
       
   384     __asm__ __volatile__ (
       
   385       "   LG       %[old],%[mem]           \n\t" // get old value
       
   386 //    LAY not supported by inline assembler
       
   387 //    "0: LAY      %[upd],-1(,%[old])      \n\t" // calc result
       
   388       "0: LGR      %[upd],%[old]           \n\t" // calc result
       
   389       "   AGHI     %[upd],-1               \n\t"
       
   390       "   CSG      %[old],%[upd],%[mem]    \n\t" // try to xchg res with mem
       
   391       "   JNE      0b                      \n\t" // no success? -> retry
       
   392       //---<  outputs  >---
       
   393       : [old] "=&a" (old)    // write-only, old counter value
       
   394       , [upd] "=&d" (upd)    // write-only, updated counter value
       
   395       , [mem] "+Q"  (*dest)  // read/write, memory to be updated atomically
       
   396       //---<  inputs  >---
       
   397       :
       
   398       //---<  clobbered  >---
       
   399       : "cc", "memory"
       
   400     );
       
   401   }
       
   402 }
       
   403 
       
   404 inline void Atomic::dec_ptr(volatile void* dest) {
       
   405   dec_ptr((volatile intptr_t*)dest);
       
   406 }
       
   407 
       
   408 //-------------
   195 //-------------
   409 // Atomic::xchg
   196 // Atomic::xchg
   410 //-------------
   197 //-------------
   411 // These methods force the value in memory to be replaced by the new value passed
   198 // These methods force the value in memory to be replaced by the new value passed
   412 // in as argument.
   199 // in as argument.