0
|
1 //
|
|
2 // Copyright 2002-2005 Sun Microsystems, Inc. All Rights Reserved.
|
|
3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 //
|
|
5 // This code is free software; you can redistribute it and/or modify it
|
|
6 // under the terms of the GNU General Public License version 2 only, as
|
|
7 // published by the Free Software Foundation.
|
|
8 //
|
|
9 // This code is distributed in the hope that it will be useful, but WITHOUT
|
|
10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
11 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
12 // version 2 for more details (a copy is included in the LICENSE file that
|
|
13 // accompanied this code).
|
|
14 //
|
|
15 // You should have received a copy of the GNU General Public License version
|
|
16 // 2 along with this work; if not, write to the Free Software Foundation,
|
|
17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
18 //
|
|
19 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
|
20 // CA 95054 USA or visit www.sun.com if you need additional information or
|
|
21 // have any questions.
|
|
22 //
|
|
23 //
|
|
24
|
|
25 // Get the raw thread ID from %g7
|
|
26
|
|
27 .inline _raw_thread_id, 0
|
|
28 .register %g7,#scratch
|
|
29 .volatile
|
|
30 mov %g7, %o0
|
|
31 .nonvolatile
|
|
32 .end
|
|
33
|
|
34
|
|
35 // Clear SPARC fprs.FEF DU and DL bits --
|
|
36 // allows the kernel to avoid saving FPU state at context-switch time.
|
|
37 // Use for state-transition points (into _thread_blocked) or when
|
|
38 // parking.
|
|
39
|
|
40 .inline _mark_fpu_nosave, 0
|
|
41 .volatile
|
|
42 wr %g0, 0, %fprs
|
|
43 .nonvolatile
|
|
44 .end
|
|
45
|
|
46 // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
|
|
47 //
|
|
48 // Arguments:
|
|
49 // exchange_value: O0
|
|
50 // dest: O1
|
|
51 //
|
|
52 // Results:
|
|
53 // O0: the value previously stored in dest
|
|
54
|
|
55 .inline _Atomic_swap32, 2
|
|
56 .volatile
|
|
57 swap [%o1],%o0
|
|
58 .nonvolatile
|
|
59 .end
|
|
60
|
|
61
|
|
62 // Support for intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t * dest).
|
|
63 //
|
|
64 // 64-bit
|
|
65 //
|
|
66 // Arguments:
|
|
67 // exchange_value: O0
|
|
68 // dest: O1
|
|
69 //
|
|
70 // Results:
|
|
71 // O0: the value previously stored in dest
|
|
72
|
|
73 .inline _Atomic_swap64, 2
|
|
74 .volatile
|
|
75 1:
|
|
76 mov %o0, %o3
|
|
77 ldx [%o1], %o2
|
|
78 casx [%o1], %o2, %o3
|
|
79 cmp %o2, %o3
|
|
80 bne %xcc, 1b
|
|
81 nop
|
|
82 mov %o2, %o0
|
|
83 .nonvolatile
|
|
84 .end
|
|
85
|
|
86
|
|
87 // Support for jint Atomic::cmpxchg(jint exchange_value,
|
|
88 // volatile jint* dest,
|
|
89 // jint compare_value)
|
|
90 //
|
|
91 // Arguments:
|
|
92 // exchange_value: O0
|
|
93 // dest: O1
|
|
94 // compare_value: O2
|
|
95 //
|
|
96 // Results:
|
|
97 // O0: the value previously stored in dest
|
|
98
|
|
99 .inline _Atomic_cas32, 3
|
|
100 .volatile
|
|
101 cas [%o1], %o2, %o0
|
|
102 .nonvolatile
|
|
103 .end
|
|
104
|
|
105
|
|
106 // Support for intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value,
|
|
107 // volatile intptr_t* dest,
|
|
108 // intptr_t compare_value)
|
|
109 //
|
|
110 // 64-bit
|
|
111 //
|
|
112 // Arguments:
|
|
113 // exchange_value: O0
|
|
114 // dest: O1
|
|
115 // compare_value: O2
|
|
116 //
|
|
117 // Results:
|
|
118 // O0: the value previously stored in dest
|
|
119
|
|
120 .inline _Atomic_cas64, 3
|
|
121 .volatile
|
|
122 casx [%o1], %o2, %o0
|
|
123 .nonvolatile
|
|
124 .end
|
|
125
|
|
126
|
|
127 // Support for jlong Atomic::cmpxchg(jlong exchange_value,
|
|
128 // volatile jlong* dest,
|
|
129 // jlong compare_value)
|
|
130 //
|
|
131 // 32-bit calling conventions
|
|
132 //
|
|
133 // Arguments:
|
|
134 // exchange_value: O1:O0
|
|
135 // dest: O2
|
|
136 // compare_value: O4:O3
|
|
137 //
|
|
138 // Results:
|
|
139 // O1:O0: the value previously stored in dest
|
|
140
|
|
141 .inline _Atomic_casl, 3
|
|
142 .volatile
|
|
143 sllx %o0, 32, %o0
|
|
144 srl %o1, 0, %o1
|
|
145 or %o0,%o1,%o0
|
|
146 sllx %o3, 32, %o3
|
|
147 srl %o4, 0, %o4
|
|
148 or %o3,%o4,%o3
|
|
149 casx [%o2], %o3, %o0
|
|
150 srl %o0, 0, %o1
|
|
151 srlx %o0, 32, %o0
|
|
152 .nonvolatile
|
|
153 .end
|
|
154
|
|
155
|
|
156 // Support for jint Atomic::add(jint add_value, volatile jint* dest).
|
|
157 //
|
|
158 // Arguments:
|
|
159 // add_value: O0 (e.g., +1 or -1)
|
|
160 // dest: O1
|
|
161 //
|
|
162 // Results:
|
|
163 // O0: the new value stored in dest
|
|
164 //
|
|
165 // Overwrites O3
|
|
166
|
|
167 .inline _Atomic_add32, 2
|
|
168 .volatile
|
|
169 2:
|
|
170 ld [%o1], %o2
|
|
171 add %o0, %o2, %o3
|
|
172 cas [%o1], %o2, %o3
|
|
173 cmp %o2, %o3
|
|
174 bne 2b
|
|
175 nop
|
|
176 add %o0, %o2, %o0
|
|
177 .nonvolatile
|
|
178 .end
|
|
179
|
|
180
|
|
181 // Support for intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
|
|
182 //
|
|
183 // 64-bit
|
|
184 //
|
|
185 // Arguments:
|
|
186 // add_value: O0 (e.g., +1 or -1)
|
|
187 // dest: O1
|
|
188 //
|
|
189 // Results:
|
|
190 // O0: the new value stored in dest
|
|
191 //
|
|
192 // Overwrites O3
|
|
193
|
|
194 .inline _Atomic_add64, 2
|
|
195 .volatile
|
|
196 3:
|
|
197 ldx [%o1], %o2
|
|
198 add %o0, %o2, %o3
|
|
199 casx [%o1], %o2, %o3
|
|
200 cmp %o2, %o3
|
|
201 bne %xcc, 3b
|
|
202 nop
|
|
203 add %o0, %o2, %o0
|
|
204 .nonvolatile
|
|
205 .end
|
|
206
|
|
207
|
|
208 // Support for void OrderAccess::acquire()
|
|
209 // The method is intentionally empty.
|
|
210 // It exists for the sole purpose of generating
|
|
211 // a C/C++ sequence point over which the compiler won't
|
|
212 // reorder code.
|
|
213
|
|
214 .inline _OrderAccess_acquire,0
|
|
215 .volatile
|
|
216 .nonvolatile
|
|
217 .end
|
|
218
|
|
219
|
|
220 // Support for void OrderAccess::fence()
|
|
221
|
|
222 .inline _OrderAccess_fence,0
|
|
223 .volatile
|
|
224 membar #StoreLoad
|
|
225 .nonvolatile
|
|
226 .end
|
|
227
|
|
228
|
|
229 // Support for void Prefetch::read(void *loc, intx interval)
|
|
230 //
|
|
231 // Prefetch for several reads.
|
|
232
|
|
233 .inline _Prefetch_read, 2
|
|
234 .volatile
|
|
235 prefetch [%o0+%o1], 0
|
|
236 .nonvolatile
|
|
237 .end
|
|
238
|
|
239
|
|
240 // Support for void Prefetch::write(void *loc, intx interval)
|
|
241 //
|
|
242 // Prefetch for several writes.
|
|
243
|
|
244 .inline _Prefetch_write, 2
|
|
245 .volatile
|
|
246 prefetch [%o0+%o1], 2
|
|
247 .nonvolatile
|
|
248 .end
|
|
249
|
|
250
|
|
251 // Support for void Copy::conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count)
|
|
252 //
|
|
253 // 32-bit
|
|
254 //
|
|
255 // Arguments:
|
|
256 // from: O0
|
|
257 // to: O1
|
|
258 // count: O2 treated as signed
|
|
259 //
|
|
260 // Clobbers:
|
|
261 // long_value: O2, O3
|
|
262 // count: O4
|
|
263 //
|
|
264 // if (from > to) {
|
|
265 // while (--count >= 0) {
|
|
266 // *to++ = *from++;
|
|
267 // }
|
|
268 // } else {
|
|
269 // while (--count >= 0) {
|
|
270 // to[count] = from[count];
|
|
271 // }
|
|
272 // }
|
|
273 .inline _Copy_conjoint_jlongs_atomic, 3
|
|
274 .volatile
|
|
275 cmp %o0, %o1
|
|
276 bleu 4f
|
|
277 sll %o2, 3, %o4
|
|
278 ba 2f
|
|
279 1:
|
|
280 subcc %o4, 8, %o4
|
|
281 std %o2, [%o1]
|
|
282 add %o0, 8, %o0
|
|
283 add %o1, 8, %o1
|
|
284 2:
|
|
285 bge,a 1b
|
|
286 ldd [%o0], %o2
|
|
287 ba 5f
|
|
288 nop
|
|
289 3:
|
|
290 std %o2, [%o1+%o4]
|
|
291 4:
|
|
292 subcc %o4, 8, %o4
|
|
293 bge,a 3b
|
|
294 ldd [%o0+%o4], %o2
|
|
295 5:
|
|
296 .nonvolatile
|
|
297 .end
|