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