174 } else {
175 __asm__ __volatile__ (
176 " LG %[old],%[mem] \n\t" // get old value
177 "0: LA %[upd],0(%[inc],%[old]) \n\t" // calc result
178 " CSG %[old],%[upd],%[mem] \n\t" // try to xchg res with mem
179 " JNE 0b \n\t" // no success? -> retry
180 //---< outputs >---
181 : [old] "=&a" (old) // write-only, old counter value
182 , [upd] "=&d" (upd) // write-only, updated counter value
183 , [mem] "+Q" (*dest) // read/write, memory to be updated atomically
184 //---< inputs >---
185 : [inc] "a" (inc) // read-only.
186 //---< clobbered >---
187 : "cc"
188 );
189 }
190
191 return upd;
192 }
193
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
|
174 } else {
175 __asm__ __volatile__ (
176 " LG %[old],%[mem] \n\t" // get old value
177 "0: LA %[upd],0(%[inc],%[old]) \n\t" // calc result
178 " CSG %[old],%[upd],%[mem] \n\t" // try to xchg res with mem
179 " JNE 0b \n\t" // no success? -> retry
180 //---< outputs >---
181 : [old] "=&a" (old) // write-only, old counter value
182 , [upd] "=&d" (upd) // write-only, updated counter value
183 , [mem] "+Q" (*dest) // read/write, memory to be updated atomically
184 //---< inputs >---
185 : [inc] "a" (inc) // read-only.
186 //---< clobbered >---
187 : "cc"
188 );
189 }
190
191 return upd;
192 }
193
194 template<>
195 struct Atomic::PlatformAdd<2>: Atomic::AddShortUsingInt {};
196
197 //------------
198 // Atomic::inc
199 //------------
200 // These methods force the value in memory to be incremented (augmented by 1).
201 // Both, memory value and increment, are treated as 32bit signed binary integers.
202 // No overflow exceptions are recognized, and the condition code does not hold
203 // information about the value in memory.
204 //
205 // The value in memory is updated by using a compare-and-swap instruction. The
206 // instruction is retried as often as required.
207
208 inline void Atomic::inc(volatile jint* dest) {
209 unsigned int old, upd;
210
211 if (VM_Version::has_LoadAndALUAtomicV1()) {
212 // tty->print_cr("Atomic::inc called... dest @%p", dest);
213 __asm__ __volatile__ (
214 " LGHI 2,1 \n\t" // load increment
215 " LA 3,%[mem] \n\t" // force data address into ARG2
|