solaris_sparc.il revision 0:a61af66fc99e
1107571Sgrehan//
2107571Sgrehan// Copyright 2002-2005 Sun Microsystems, Inc.  All Rights Reserved.
3107571Sgrehan// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4107571Sgrehan//
5107571Sgrehan// This code is free software; you can redistribute it and/or modify it
6107571Sgrehan// under the terms of the GNU General Public License version 2 only, as
7107571Sgrehan// published by the Free Software Foundation.
8107571Sgrehan//
9107571Sgrehan// This code is distributed in the hope that it will be useful, but WITHOUT
10107571Sgrehan// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11107571Sgrehan// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12107571Sgrehan// version 2 for more details (a copy is included in the LICENSE file that
13107571Sgrehan// accompanied this code).
14107571Sgrehan//
15107571Sgrehan// You should have received a copy of the GNU General Public License version
16107571Sgrehan// 2 along with this work; if not, write to the Free Software Foundation,
17107571Sgrehan// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18107571Sgrehan//
19107571Sgrehan// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20107571Sgrehan// CA 95054 USA or visit www.sun.com if you need additional information or
21107571Sgrehan// have any questions.
22107571Sgrehan//  
23107571Sgrehan//
24107571Sgrehan
25107571Sgrehan  // Get the raw thread ID from %g7
26107571Sgrehan
27107571Sgrehan       .inline  _raw_thread_id, 0
28107571Sgrehan       .register %g7,#scratch
29107571Sgrehan       .volatile
30107571Sgrehan       mov     %g7, %o0
31107571Sgrehan       .nonvolatile
32107571Sgrehan       .end
33107571Sgrehan
34107571Sgrehan
35107571Sgrehan  // Clear SPARC fprs.FEF DU and DL bits --
36107571Sgrehan  // allows the kernel to avoid saving FPU state at context-switch time.
37107571Sgrehan  // Use for state-transition points (into _thread_blocked) or when
38107571Sgrehan  // parking. 
39107571Sgrehan      
40107571Sgrehan       .inline _mark_fpu_nosave, 0
41107571Sgrehan       .volatile
42107571Sgrehan       wr   %g0, 0, %fprs       
43107571Sgrehan       .nonvolatile
44107571Sgrehan       .end
45107571Sgrehan
46107571Sgrehan  // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
47107571Sgrehan  //
48107571Sgrehan  // Arguments:
49107571Sgrehan  //      exchange_value: O0
50107571Sgrehan  //      dest:           O1
51107571Sgrehan  //
52107571Sgrehan  // Results:
53107571Sgrehan  //     O0: the value previously stored in dest
54107571Sgrehan
55107571Sgrehan        .inline _Atomic_swap32, 2
56107571Sgrehan        .volatile
57107571Sgrehan        swap    [%o1],%o0
58107571Sgrehan        .nonvolatile
59107571Sgrehan        .end
60107571Sgrehan
61107571Sgrehan
62107571Sgrehan  // Support for intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t * dest).
63107571Sgrehan  //
64107571Sgrehan  // 64-bit
65107571Sgrehan  //
66107571Sgrehan  // Arguments:
67107571Sgrehan  //      exchange_value: O0
68107571Sgrehan  //      dest:           O1
69107571Sgrehan  //
70107571Sgrehan  // Results:
71107571Sgrehan  //     O0: the value previously stored in dest
72107571Sgrehan
73107571Sgrehan        .inline _Atomic_swap64, 2
74272362Sbapt        .volatile
75217398Skib    1:
76217398Skib        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
298