144 }
145
146 extern "C" void _Atomic_move_long(const volatile jlong* src, volatile jlong* dst);
147
148 inline jlong Atomic::load(const volatile jlong* src) {
149 volatile jlong dest;
150 _Atomic_move_long(src, &dest);
151 return dest;
152 }
153
154 inline void Atomic::store(jlong store_value, jlong* dest) {
155 _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest);
156 }
157
158 inline void Atomic::store(jlong store_value, volatile jlong* dest) {
159 _Atomic_move_long((volatile jlong*)&store_value, dest);
160 }
161
162 #endif // AMD64
163
164 #ifdef _GNU_SOURCE
165
166 extern "C" {
167 inline jint _Atomic_add(jint add_value, volatile jint* dest) {
168 jint addend = add_value;
169 __asm__ volatile ("lock xaddl %0,(%2)"
170 : "=r" (addend)
171 : "0" (addend), "r" (dest)
172 : "cc", "memory");
173 return addend + add_value;
174 }
175
176 #ifdef AMD64
177 inline jlong _Atomic_add_long(jlong add_value, volatile jlong* dest) {
178 intptr_t addend = add_value;
179 __asm__ __volatile__ ("lock xaddq %0,(%2)"
180 : "=r" (addend)
181 : "0" (addend), "r" (dest)
182 : "cc", "memory");
183 return addend + add_value;
184 }
185
186 inline jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest) {
187 __asm__ __volatile__ ("xchgq (%2),%0"
188 : "=r" (exchange_value)
189 : "0" (exchange_value), "r" (dest)
190 : "memory");
191 return exchange_value;
192 }
193
194 #endif // AMD64
195
196 inline jint _Atomic_xchg(jint exchange_value, volatile jint* dest) {
197 __asm__ __volatile__ ("xchgl (%2),%0"
198 : "=r" (exchange_value)
199 : "0" (exchange_value), "r" (dest)
200 : "memory");
201 return exchange_value;
202 }
203
204 inline jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value) {
205 __asm__ volatile ("lock cmpxchgl %1,(%3)"
206 : "=a" (exchange_value)
207 : "r" (exchange_value), "a" (compare_value), "r" (dest)
208 : "cc", "memory");
209 return exchange_value;
210 }
211
212
213 inline jbyte _Atomic_cmpxchg_byte(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
214 __asm__ volatile ("lock cmpxchgb %1,(%3)"
215 : "=a" (exchange_value)
216 : "q" (exchange_value), "a" (compare_value), "r" (dest)
217 : "cc", "memory");
218 return exchange_value;
219 }
220
221 // This is the interface to the atomic instruction in solaris_i486.s.
222 jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value);
223
224 inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value) {
225 #ifdef AMD64
226 __asm__ __volatile__ ("lock cmpxchgq %1,(%3)"
227 : "=a" (exchange_value)
228 : "r" (exchange_value), "a" (compare_value), "r" (dest)
229 : "cc", "memory");
230 return exchange_value;
231 #else
232 return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value);
233
234 #if 0
235 // The code below does not work presumably because of the bug in gcc
236 // The error message says:
237 // can't find a register in class BREG while reloading asm
238 // However I want to save this code and later replace _Atomic_cmpxchg_long_gcc
239 // with such inline asm code:
240
241 volatile jlong_accessor evl, cvl, rv;
242 evl.long_value = exchange_value;
243 cvl.long_value = compare_value;
244
245 __asm__ volatile (
246 "lock cmpxchg8b (%%edi)\n\t"
247 : "=a"(cvl.words[0]), "=d"(cvl.words[1])
248 : "a"(cvl.words[0]), "d"(cvl.words[1]),
249 "b"(evl.words[0]), "c"(evl.words[1]),
250 "D"(dest)
251 : "cc", "memory");
252 return cvl.long_value;
253 #endif // if 0
254 #endif // AMD64
255 }
256 }
257
258 #endif // _GNU_SOURCE
259
260 #endif // OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP
|
144 }
145
146 extern "C" void _Atomic_move_long(const volatile jlong* src, volatile jlong* dst);
147
148 inline jlong Atomic::load(const volatile jlong* src) {
149 volatile jlong dest;
150 _Atomic_move_long(src, &dest);
151 return dest;
152 }
153
154 inline void Atomic::store(jlong store_value, jlong* dest) {
155 _Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest);
156 }
157
158 inline void Atomic::store(jlong store_value, volatile jlong* dest) {
159 _Atomic_move_long((volatile jlong*)&store_value, dest);
160 }
161
162 #endif // AMD64
163
164
165 #endif // OS_CPU_SOLARIS_X86_VM_ATOMIC_SOLARIS_X86_HPP
|