1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os_cpu/solaris_sparc/vm/solaris_sparc.il Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,313 @@ 1.4 +// 1.5 +// Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 1.6 +// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 +// 1.8 +// This code is free software; you can redistribute it and/or modify it 1.9 +// under the terms of the GNU General Public License version 2 only, as 1.10 +// published by the Free Software Foundation. 1.11 +// 1.12 +// This code is distributed in the hope that it will be useful, but WITHOUT 1.13 +// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 +// version 2 for more details (a copy is included in the LICENSE file that 1.16 +// accompanied this code). 1.17 +// 1.18 +// You should have received a copy of the GNU General Public License version 1.19 +// 2 along with this work; if not, write to the Free Software Foundation, 1.20 +// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 +// 1.22 +// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 +// or visit www.oracle.com if you need additional information or have any 1.24 +// questions. 1.25 +// 1.26 +// 1.27 + 1.28 + // Get the raw thread ID from %g7 1.29 + 1.30 + .inline _raw_thread_id, 0 1.31 + .register %g7,#scratch 1.32 + .volatile 1.33 + mov %g7, %o0 1.34 + .nonvolatile 1.35 + .end 1.36 + 1.37 + 1.38 + // Clear SPARC fprs.FEF DU and DL bits -- 1.39 + // allows the kernel to avoid saving FPU state at context-switch time. 1.40 + // Use for state-transition points (into _thread_blocked) or when 1.41 + // parking. 1.42 + 1.43 + .inline _mark_fpu_nosave, 0 1.44 + .volatile 1.45 + wr %g0, 0, %fprs 1.46 + .nonvolatile 1.47 + .end 1.48 + 1.49 + // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest). 1.50 + // 1.51 + // Arguments: 1.52 + // exchange_value: O0 1.53 + // dest: O1 1.54 + // 1.55 + // Results: 1.56 + // O0: the value previously stored in dest 1.57 + 1.58 + .inline _Atomic_swap32, 2 1.59 + .volatile 1.60 + swap [%o1],%o0 1.61 + .nonvolatile 1.62 + .end 1.63 + 1.64 + 1.65 + // Support for intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t * dest). 1.66 + // 1.67 + // 64-bit 1.68 + // 1.69 + // Arguments: 1.70 + // exchange_value: O0 1.71 + // dest: O1 1.72 + // 1.73 + // Results: 1.74 + // O0: the value previously stored in dest 1.75 + 1.76 + .inline _Atomic_swap64, 2 1.77 + .volatile 1.78 + 1: 1.79 + mov %o0, %o3 1.80 + ldx [%o1], %o2 1.81 + casx [%o1], %o2, %o3 1.82 + cmp %o2, %o3 1.83 + bne %xcc, 1b 1.84 + nop 1.85 + mov %o2, %o0 1.86 + .nonvolatile 1.87 + .end 1.88 + 1.89 + 1.90 + // Support for jint Atomic::cmpxchg(jint exchange_value, 1.91 + // volatile jint* dest, 1.92 + // jint compare_value) 1.93 + // 1.94 + // Arguments: 1.95 + // exchange_value: O0 1.96 + // dest: O1 1.97 + // compare_value: O2 1.98 + // 1.99 + // Results: 1.100 + // O0: the value previously stored in dest 1.101 + 1.102 + .inline _Atomic_cas32, 3 1.103 + .volatile 1.104 + cas [%o1], %o2, %o0 1.105 + .nonvolatile 1.106 + .end 1.107 + 1.108 + 1.109 + // Support for intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, 1.110 + // volatile intptr_t* dest, 1.111 + // intptr_t compare_value) 1.112 + // 1.113 + // 64-bit 1.114 + // 1.115 + // Arguments: 1.116 + // exchange_value: O0 1.117 + // dest: O1 1.118 + // compare_value: O2 1.119 + // 1.120 + // Results: 1.121 + // O0: the value previously stored in dest 1.122 + 1.123 + .inline _Atomic_cas64, 3 1.124 + .volatile 1.125 + casx [%o1], %o2, %o0 1.126 + .nonvolatile 1.127 + .end 1.128 + 1.129 + 1.130 + // Support for jlong Atomic::cmpxchg(jlong exchange_value, 1.131 + // volatile jlong* dest, 1.132 + // jlong compare_value) 1.133 + // 1.134 + // 32-bit calling conventions 1.135 + // 1.136 + // Arguments: 1.137 + // exchange_value: O1:O0 1.138 + // dest: O2 1.139 + // compare_value: O4:O3 1.140 + // 1.141 + // Results: 1.142 + // O1:O0: the value previously stored in dest 1.143 + 1.144 + .inline _Atomic_casl, 3 1.145 + .volatile 1.146 + sllx %o0, 32, %o0 1.147 + srl %o1, 0, %o1 1.148 + or %o0,%o1,%o0 1.149 + sllx %o3, 32, %o3 1.150 + srl %o4, 0, %o4 1.151 + or %o3,%o4,%o3 1.152 + casx [%o2], %o3, %o0 1.153 + srl %o0, 0, %o1 1.154 + srlx %o0, 32, %o0 1.155 + .nonvolatile 1.156 + .end 1.157 + 1.158 + // Support for jlong Atomic::load and Atomic::store on v9. 1.159 + // 1.160 + // void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst) 1.161 + // 1.162 + // Arguments: 1.163 + // src: O0 1.164 + // dest: O1 1.165 + // 1.166 + // Overwrites O2 1.167 + 1.168 + .inline _Atomic_move_long_v9,2 1.169 + .volatile 1.170 + ldx [%o0], %o2 1.171 + stx %o2, [%o1] 1.172 + .nonvolatile 1.173 + .end 1.174 + 1.175 + // Support for jint Atomic::add(jint add_value, volatile jint* dest). 1.176 + // 1.177 + // Arguments: 1.178 + // add_value: O0 (e.g., +1 or -1) 1.179 + // dest: O1 1.180 + // 1.181 + // Results: 1.182 + // O0: the new value stored in dest 1.183 + // 1.184 + // Overwrites O3 1.185 + 1.186 + .inline _Atomic_add32, 2 1.187 + .volatile 1.188 + 2: 1.189 + ld [%o1], %o2 1.190 + add %o0, %o2, %o3 1.191 + cas [%o1], %o2, %o3 1.192 + cmp %o2, %o3 1.193 + bne 2b 1.194 + nop 1.195 + add %o0, %o2, %o0 1.196 + .nonvolatile 1.197 + .end 1.198 + 1.199 + 1.200 + // Support for intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) 1.201 + // 1.202 + // 64-bit 1.203 + // 1.204 + // Arguments: 1.205 + // add_value: O0 (e.g., +1 or -1) 1.206 + // dest: O1 1.207 + // 1.208 + // Results: 1.209 + // O0: the new value stored in dest 1.210 + // 1.211 + // Overwrites O3 1.212 + 1.213 + .inline _Atomic_add64, 2 1.214 + .volatile 1.215 + 3: 1.216 + ldx [%o1], %o2 1.217 + add %o0, %o2, %o3 1.218 + casx [%o1], %o2, %o3 1.219 + cmp %o2, %o3 1.220 + bne %xcc, 3b 1.221 + nop 1.222 + add %o0, %o2, %o0 1.223 + .nonvolatile 1.224 + .end 1.225 + 1.226 + 1.227 + // Support for void OrderAccess::acquire() 1.228 + // The method is intentionally empty. 1.229 + // It exists for the sole purpose of generating 1.230 + // a C/C++ sequence point over which the compiler won't 1.231 + // reorder code. 1.232 + 1.233 + .inline _OrderAccess_acquire,0 1.234 + .volatile 1.235 + .nonvolatile 1.236 + .end 1.237 + 1.238 + 1.239 + // Support for void OrderAccess::fence() 1.240 + 1.241 + .inline _OrderAccess_fence,0 1.242 + .volatile 1.243 + membar #StoreLoad 1.244 + .nonvolatile 1.245 + .end 1.246 + 1.247 + 1.248 + // Support for void Prefetch::read(void *loc, intx interval) 1.249 + // 1.250 + // Prefetch for several reads. 1.251 + 1.252 + .inline _Prefetch_read, 2 1.253 + .volatile 1.254 + prefetch [%o0+%o1], 0 1.255 + .nonvolatile 1.256 + .end 1.257 + 1.258 + 1.259 + // Support for void Prefetch::write(void *loc, intx interval) 1.260 + // 1.261 + // Prefetch for several writes. 1.262 + 1.263 + .inline _Prefetch_write, 2 1.264 + .volatile 1.265 + prefetch [%o0+%o1], 2 1.266 + .nonvolatile 1.267 + .end 1.268 + 1.269 + 1.270 + // Support for void Copy::conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) 1.271 + // 1.272 + // 32-bit 1.273 + // 1.274 + // Arguments: 1.275 + // from: O0 1.276 + // to: O1 1.277 + // count: O2 treated as signed 1.278 + // 1.279 + // Clobbers: 1.280 + // long_value: O2, O3 1.281 + // count: O4 1.282 + // 1.283 + // if (from > to) { 1.284 + // while (--count >= 0) { 1.285 + // *to++ = *from++; 1.286 + // } 1.287 + // } else { 1.288 + // while (--count >= 0) { 1.289 + // to[count] = from[count]; 1.290 + // } 1.291 + // } 1.292 + .inline _Copy_conjoint_jlongs_atomic, 3 1.293 + .volatile 1.294 + cmp %o0, %o1 1.295 + bleu 4f 1.296 + sll %o2, 3, %o4 1.297 + ba 2f 1.298 + 1: 1.299 + subcc %o4, 8, %o4 1.300 + std %o2, [%o1] 1.301 + add %o0, 8, %o0 1.302 + add %o1, 8, %o1 1.303 + 2: 1.304 + bge,a 1b 1.305 + ldd [%o0], %o2 1.306 + ba 5f 1.307 + nop 1.308 + 3: 1.309 + std %o2, [%o1+%o4] 1.310 + 4: 1.311 + subcc %o4, 8, %o4 1.312 + bge,a 3b 1.313 + ldd [%o0+%o4], %o2 1.314 + 5: 1.315 + .nonvolatile 1.316 + .end