annotate src/os_cpu/solaris_x86/vm/atomic_solaris_x86.inline.hpp @ 795:215f81b4d9b3

6841831: G1: assert(contains_reference(from),"We just added it!") fires Summary: During parallel rset updating we have to make sure that the worker ids of the refinement threads do not intersect with the worker ids that can be claimed by the mutator threads. Reviewed-by: tonyp
author iveresov
date Mon, 18 May 2009 11:52:46 -0700
parents a61af66fc99e
children 665be97e8704
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2 * Copyright 1999-2007 Sun Microsystems, Inc. All Rights Reserved.
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
26 inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
27 inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29
a61af66fc99e Initial load
duke
parents:
diff changeset
30 inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
31 inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
32
a61af66fc99e Initial load
duke
parents:
diff changeset
33 inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
34 inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
35 inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
36 inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
37 inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 inline void Atomic::inc (volatile jint* dest) { (void)add (1, dest); }
a61af66fc99e Initial load
duke
parents:
diff changeset
40 inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); }
a61af66fc99e Initial load
duke
parents:
diff changeset
41 inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); }
a61af66fc99e Initial load
duke
parents:
diff changeset
42
a61af66fc99e Initial load
duke
parents:
diff changeset
43 inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); }
a61af66fc99e Initial load
duke
parents:
diff changeset
44 inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); }
a61af66fc99e Initial load
duke
parents:
diff changeset
45 inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); }
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // For Sun Studio - implementation is in solaris_x86_[32/64].il.
a61af66fc99e Initial load
duke
parents:
diff changeset
48 // For gcc - implementation is just below.
a61af66fc99e Initial load
duke
parents:
diff changeset
49
a61af66fc99e Initial load
duke
parents:
diff changeset
50 extern "C" jint _Atomic_add(jint add_value, volatile jint* dest, int mp);
a61af66fc99e Initial load
duke
parents:
diff changeset
51 extern "C" jint _Atomic_xchg(jint exchange_value, volatile jint* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
52 extern "C" jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, int mp);
a61af66fc99e Initial load
duke
parents:
diff changeset
53 extern "C" jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp);
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 inline jint Atomic::add (jint add_value, volatile jint* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
56 return _Atomic_add(add_value, dest, (int) os::is_MP());
a61af66fc99e Initial load
duke
parents:
diff changeset
57 }
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
60 return _Atomic_cmpxchg(exchange_value, dest, compare_value, (int) os::is_MP());
a61af66fc99e Initial load
duke
parents:
diff changeset
61 }
a61af66fc99e Initial load
duke
parents:
diff changeset
62
a61af66fc99e Initial load
duke
parents:
diff changeset
63 inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, (int) os::is_MP());
a61af66fc99e Initial load
duke
parents:
diff changeset
65 }
a61af66fc99e Initial load
duke
parents:
diff changeset
66
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
69 inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
70 inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
a61af66fc99e Initial load
duke
parents:
diff changeset
71 extern "C" jlong _Atomic_add_long(jlong add_value, volatile jlong* dest, int mp);
a61af66fc99e Initial load
duke
parents:
diff changeset
72 extern "C" jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
75 return (intptr_t)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest, (int) os::is_MP());
a61af66fc99e Initial load
duke
parents:
diff changeset
76 }
a61af66fc99e Initial load
duke
parents:
diff changeset
77
a61af66fc99e Initial load
duke
parents:
diff changeset
78 inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
79 return (void*)_Atomic_add_long((jlong)add_value, (volatile jlong*)dest, (int) os::is_MP());
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82 inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 return _Atomic_xchg(exchange_value, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
84 }
a61af66fc99e Initial load
duke
parents:
diff changeset
85
a61af66fc99e Initial load
duke
parents:
diff changeset
86 inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
87 return (intptr_t)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
88 }
a61af66fc99e Initial load
duke
parents:
diff changeset
89
a61af66fc99e Initial load
duke
parents:
diff changeset
90 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 return (void*)_Atomic_xchg_long((jlong)exchange_value, (volatile jlong*)dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93
a61af66fc99e Initial load
duke
parents:
diff changeset
94 inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
95 return (intptr_t)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, (int) os::is_MP());
a61af66fc99e Initial load
duke
parents:
diff changeset
96 }
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 return (void*)_Atomic_cmpxchg_long((jlong)exchange_value, (volatile jlong*)dest, (jlong)compare_value, (int) os::is_MP());
a61af66fc99e Initial load
duke
parents:
diff changeset
100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
101
a61af66fc99e Initial load
duke
parents:
diff changeset
102 #else // !AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
103
a61af66fc99e Initial load
duke
parents:
diff changeset
104 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
105 return (intptr_t)add((jint)add_value, (volatile jint*)dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
107
a61af66fc99e Initial load
duke
parents:
diff changeset
108 inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
109 return (void*)add((jint)add_value, (volatile jint*)dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111
a61af66fc99e Initial load
duke
parents:
diff changeset
112 inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 // We noticed a CC5.5 bug (4894807), so keep calling the stub just to be safe.
a61af66fc99e Initial load
duke
parents:
diff changeset
114 // Will use the inline template version after 4894807 is fixed.
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // return _Atomic_xchg(exchange_value, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
116 return (*os::atomic_xchg_func)(exchange_value, dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 return (void*)xchg((jint)exchange_value, (volatile jint*)dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
126
a61af66fc99e Initial load
duke
parents:
diff changeset
127 inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
128 return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
130
a61af66fc99e Initial load
duke
parents:
diff changeset
131 inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
134 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
135
a61af66fc99e Initial load
duke
parents:
diff changeset
136 #ifdef _GNU_SOURCE
a61af66fc99e Initial load
duke
parents:
diff changeset
137 // Add a lock prefix to an instruction on an MP machine
a61af66fc99e Initial load
duke
parents:
diff changeset
138 #define LOCK_IF_MP(mp) "cmp $0, " #mp "; je 1f; lock; 1: "
a61af66fc99e Initial load
duke
parents:
diff changeset
139
a61af66fc99e Initial load
duke
parents:
diff changeset
140 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 inline jint _Atomic_add(jint add_value, volatile jint* dest, int mp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
142 jint addend = add_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
143 __asm__ volatile ( LOCK_IF_MP(%3) "xaddl %0,(%2)"
a61af66fc99e Initial load
duke
parents:
diff changeset
144 : "=r" (addend)
a61af66fc99e Initial load
duke
parents:
diff changeset
145 : "0" (addend), "r" (dest), "r" (mp)
a61af66fc99e Initial load
duke
parents:
diff changeset
146 : "cc", "memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
147 return addend + add_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
149
a61af66fc99e Initial load
duke
parents:
diff changeset
150 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
151 inline jlong _Atomic_add_long(jlong add_value, volatile jlong* dest, int mp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
152 intptr_t addend = add_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 __asm__ __volatile__ (LOCK_IF_MP(%3) "xaddq %0,(%2)"
a61af66fc99e Initial load
duke
parents:
diff changeset
154 : "=r" (addend)
a61af66fc99e Initial load
duke
parents:
diff changeset
155 : "0" (addend), "r" (dest), "r" (mp)
a61af66fc99e Initial load
duke
parents:
diff changeset
156 : "cc", "memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
157 return addend + add_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 inline jlong _Atomic_xchg_long(jlong exchange_value, volatile jlong* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 __asm__ __volatile__ ("xchgq (%2),%0"
a61af66fc99e Initial load
duke
parents:
diff changeset
162 : "=r" (exchange_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
163 : "0" (exchange_value), "r" (dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
164 : "memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
165 return exchange_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
169
a61af66fc99e Initial load
duke
parents:
diff changeset
170 inline jint _Atomic_xchg(jint exchange_value, volatile jint* dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // 32bit version originally did nothing!!
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174 __asm__ __volatile__ ("xchgl (%2),%0"
a61af66fc99e Initial load
duke
parents:
diff changeset
175 : "=r" (exchange_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
176 : "0" (exchange_value), "r" (dest)
a61af66fc99e Initial load
duke
parents:
diff changeset
177 : "memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
178 return exchange_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 inline jint _Atomic_cmpxchg(jint exchange_value, volatile jint* dest, jint compare_value, int mp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
182 __asm__ volatile (LOCK_IF_MP(%4) "cmpxchgl %1,(%3)"
a61af66fc99e Initial load
duke
parents:
diff changeset
183 : "=a" (exchange_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
184 : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
a61af66fc99e Initial load
duke
parents:
diff changeset
185 : "cc", "memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
186 return exchange_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // This is the interface to the atomic instruction in solaris_i486.s.
a61af66fc99e Initial load
duke
parents:
diff changeset
190 jlong _Atomic_cmpxchg_long_gcc(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp);
a61af66fc99e Initial load
duke
parents:
diff changeset
191
a61af66fc99e Initial load
duke
parents:
diff changeset
192 inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
194 __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)"
a61af66fc99e Initial load
duke
parents:
diff changeset
195 : "=a" (exchange_value)
a61af66fc99e Initial load
duke
parents:
diff changeset
196 : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp)
a61af66fc99e Initial load
duke
parents:
diff changeset
197 : "cc", "memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
198 return exchange_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
199 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
200 return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value, os::is_MP());
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
203 // The code below does not work presumably because of the bug in gcc
a61af66fc99e Initial load
duke
parents:
diff changeset
204 // The error message says:
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // can't find a register in class BREG while reloading asm
a61af66fc99e Initial load
duke
parents:
diff changeset
206 // However I want to save this code and later replace _Atomic_cmpxchg_long_gcc
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // with such inline asm code:
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 volatile jlong_accessor evl, cvl, rv;
a61af66fc99e Initial load
duke
parents:
diff changeset
210 evl.long_value = exchange_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
211 cvl.long_value = compare_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
212 int mp = os::is_MP();
a61af66fc99e Initial load
duke
parents:
diff changeset
213
a61af66fc99e Initial load
duke
parents:
diff changeset
214 __asm__ volatile ("cmp $0, %%esi\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
215 "je 1f \n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
216 "lock\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
217 "1: cmpxchg8b (%%edi)\n\t"
a61af66fc99e Initial load
duke
parents:
diff changeset
218 : "=a"(cvl.words[0]), "=d"(cvl.words[1])
a61af66fc99e Initial load
duke
parents:
diff changeset
219 : "a"(cvl.words[0]), "d"(cvl.words[1]),
a61af66fc99e Initial load
duke
parents:
diff changeset
220 "b"(evl.words[0]), "c"(evl.words[1]),
a61af66fc99e Initial load
duke
parents:
diff changeset
221 "D"(dest), "S"(mp)
a61af66fc99e Initial load
duke
parents:
diff changeset
222 : "cc", "memory");
a61af66fc99e Initial load
duke
parents:
diff changeset
223 return cvl.long_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
224 #endif // if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
225 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
228 #undef LOCK_IF_MP
a61af66fc99e Initial load
duke
parents:
diff changeset
229
a61af66fc99e Initial load
duke
parents:
diff changeset
230 #endif // _GNU_SOURCE