solaris_sparc.il revision 13477:4d61110c6046
1//
2// Copyright (c) 2002, 2017, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20// or visit www.oracle.com if you need additional information or have any
21// 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  // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
36  //
37  // Arguments:
38  //      exchange_value: O0
39  //      dest:           O1
40  //
41  // Results:
42  //     O0: the value previously stored in dest
43
44        .inline _Atomic_swap32, 2
45        .volatile
46        swap    [%o1],%o0
47        .nonvolatile
48        .end
49
50
51  // Support for intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t * dest).
52  //
53  // 64-bit
54  //
55  // Arguments:
56  //      exchange_value: O0
57  //      dest:           O1
58  //
59  // Results:
60  //     O0: the value previously stored in dest
61
62        .inline _Atomic_swap64, 2
63        .volatile
64    1:
65        mov     %o0, %o3
66        ldx     [%o1], %o2
67        casx    [%o1], %o2, %o3
68        cmp     %o2, %o3
69        bne     %xcc, 1b
70         nop
71        mov     %o2, %o0
72        .nonvolatile
73        .end
74
75
76  // Support for jlong Atomic::load and Atomic::store on v9.
77  //
78  // void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst)
79  //
80  // Arguments:
81  //      src:  O0
82  //      dest: O1
83  //
84  // Overwrites O2
85
86        .inline _Atomic_move_long_v9,2
87        .volatile
88        ldx     [%o0], %o2
89        stx     %o2, [%o1]
90        .nonvolatile
91        .end
92
93  // Support for jint Atomic::add(jint add_value, volatile jint* dest).
94  //
95  // Arguments:
96  //      add_value: O0   (e.g., +1 or -1)
97  //      dest:      O1
98  //
99  // Results:
100  //     O0: the new value stored in dest
101  //
102  // Overwrites O3
103
104        .inline _Atomic_add32, 2
105        .volatile
106    2:
107        ld      [%o1], %o2
108        add     %o0, %o2, %o3
109        cas     [%o1], %o2, %o3
110        cmp     %o2, %o3
111        bne     2b
112         nop
113        add     %o0, %o2, %o0
114        .nonvolatile
115        .end
116
117
118  // Support for intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
119  //
120  // 64-bit
121  //
122  // Arguments:
123  //      add_value: O0   (e.g., +1 or -1)
124  //      dest:      O1
125  //
126  // Results:
127  //     O0: the new value stored in dest
128  //
129  // Overwrites O3
130
131        .inline _Atomic_add64, 2
132        .volatile
133    3:
134        ldx     [%o1], %o2
135        add     %o0, %o2, %o3
136        casx    [%o1], %o2, %o3
137        cmp     %o2, %o3
138        bne     %xcc, 3b
139         nop
140        add     %o0, %o2, %o0
141        .nonvolatile
142        .end
143
144
145  // Support for void Prefetch::read(void *loc, intx interval)
146  //
147  // Prefetch for several reads.
148
149        .inline _Prefetch_read, 2
150        .volatile
151        prefetch [%o0+%o1], 0
152        .nonvolatile
153        .end
154
155
156  // Support for void Prefetch::write(void *loc, intx interval)
157  //
158  // Prefetch for several writes.
159
160        .inline _Prefetch_write, 2
161        .volatile
162        prefetch [%o0+%o1], 2
163        .nonvolatile
164        .end
165
166
167  // Support for void Copy::conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count)
168  //
169  // 32-bit
170  //
171  // Arguments:
172  //      from:  O0
173  //      to:    O1
174  //      count: O2 treated as signed
175  //
176  // Clobbers:
177  //      long_value: O2, O3
178  //      count:      O4
179  //
180  // if (from > to) {
181  //   while (--count >= 0) {
182  //     *to++ = *from++;
183  //   }
184  // } else {
185  //   while (--count >= 0) {
186  //     to[count] = from[count];
187  //   }
188  // }
189        .inline _Copy_conjoint_jlongs_atomic, 3
190        .volatile
191        cmp     %o0, %o1
192        bleu    4f
193        sll     %o2, 3, %o4
194        ba      2f
195    1:
196        subcc   %o4, 8, %o4
197        std     %o2, [%o1]
198        add     %o0, 8, %o0
199        add     %o1, 8, %o1
200    2:
201        bge,a   1b
202        ldd     [%o0], %o2
203        ba      5f
204        nop
205    3:
206        std     %o2, [%o1+%o4]
207    4:
208        subcc   %o4, 8, %o4
209        bge,a   3b
210        ldd     [%o0+%o4], %o2
211    5:
212        .nonvolatile
213        .end
214