1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os_cpu/solaris_sparc/vm/atomic_solaris_sparc.inline.hpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,378 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 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 +#ifndef OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP 1.29 +#define OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP 1.30 + 1.31 +#include "runtime/atomic.hpp" 1.32 +#include "runtime/os.hpp" 1.33 +#include "vm_version_sparc.hpp" 1.34 + 1.35 +// Implementation of class atomic 1.36 + 1.37 +inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; } 1.38 +inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; } 1.39 +inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; } 1.40 +inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; } 1.41 +inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; } 1.42 + 1.43 +inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; } 1.44 +inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; } 1.45 +inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; } 1.46 +inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; } 1.47 +inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; } 1.48 + 1.49 +inline void Atomic::inc (volatile jint* dest) { (void)add (1, dest); } 1.50 +inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); } 1.51 +inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); } 1.52 + 1.53 +inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); } 1.54 +inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); } 1.55 +inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); } 1.56 + 1.57 + 1.58 +#ifdef _LP64 1.59 + 1.60 +inline void Atomic::store(jlong store_value, jlong* dest) { *dest = store_value; } 1.61 +inline void Atomic::store(jlong store_value, volatile jlong* dest) { *dest = store_value; } 1.62 +inline jlong Atomic::load(volatile jlong* src) { return *src; } 1.63 + 1.64 +#else 1.65 + 1.66 +extern "C" void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst); 1.67 + 1.68 +inline void Atomic_move_long(volatile jlong* src, volatile jlong* dst) { 1.69 + _Atomic_move_long_v9(src, dst); 1.70 +} 1.71 + 1.72 +inline jlong Atomic::load(volatile jlong* src) { 1.73 + volatile jlong dest; 1.74 + Atomic_move_long(src, &dest); 1.75 + return dest; 1.76 +} 1.77 + 1.78 +inline void Atomic::store(jlong store_value, jlong* dest) { 1.79 + Atomic_move_long((volatile jlong*)&store_value, (volatile jlong*)dest); 1.80 +} 1.81 + 1.82 +inline void Atomic::store(jlong store_value, volatile jlong* dest) { 1.83 + Atomic_move_long((volatile jlong*)&store_value, dest); 1.84 +} 1.85 + 1.86 +#endif 1.87 + 1.88 +#ifdef _GNU_SOURCE 1.89 + 1.90 +inline jint Atomic::add (jint add_value, volatile jint* dest) { 1.91 + intptr_t rv; 1.92 + __asm__ volatile( 1.93 + "1: \n\t" 1.94 + " ld [%2], %%o2\n\t" 1.95 + " add %1, %%o2, %%o3\n\t" 1.96 + " cas [%2], %%o2, %%o3\n\t" 1.97 + " cmp %%o2, %%o3\n\t" 1.98 + " bne 1b\n\t" 1.99 + " nop\n\t" 1.100 + " add %1, %%o2, %0\n\t" 1.101 + : "=r" (rv) 1.102 + : "r" (add_value), "r" (dest) 1.103 + : "memory", "o2", "o3"); 1.104 + return rv; 1.105 +} 1.106 + 1.107 +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { 1.108 + intptr_t rv; 1.109 +#ifdef _LP64 1.110 + __asm__ volatile( 1.111 + "1: \n\t" 1.112 + " ldx [%2], %%o2\n\t" 1.113 + " add %0, %%o2, %%o3\n\t" 1.114 + " casx [%2], %%o2, %%o3\n\t" 1.115 + " cmp %%o2, %%o3\n\t" 1.116 + " bne %%xcc, 1b\n\t" 1.117 + " nop\n\t" 1.118 + " add %0, %%o2, %0\n\t" 1.119 + : "=r" (rv) 1.120 + : "r" (add_value), "r" (dest) 1.121 + : "memory", "o2", "o3"); 1.122 +#else //_LP64 1.123 + __asm__ volatile( 1.124 + "1: \n\t" 1.125 + " ld [%2], %%o2\n\t" 1.126 + " add %1, %%o2, %%o3\n\t" 1.127 + " cas [%2], %%o2, %%o3\n\t" 1.128 + " cmp %%o2, %%o3\n\t" 1.129 + " bne 1b\n\t" 1.130 + " nop\n\t" 1.131 + " add %1, %%o2, %0\n\t" 1.132 + : "=r" (rv) 1.133 + : "r" (add_value), "r" (dest) 1.134 + : "memory", "o2", "o3"); 1.135 +#endif // _LP64 1.136 + return rv; 1.137 +} 1.138 + 1.139 +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { 1.140 + return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest); 1.141 +} 1.142 + 1.143 + 1.144 +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { 1.145 + intptr_t rv = exchange_value; 1.146 + __asm__ volatile( 1.147 + " swap [%2],%1\n\t" 1.148 + : "=r" (rv) 1.149 + : "0" (exchange_value) /* we use same register as for return value */, "r" (dest) 1.150 + : "memory"); 1.151 + return rv; 1.152 +} 1.153 + 1.154 +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { 1.155 + intptr_t rv = exchange_value; 1.156 +#ifdef _LP64 1.157 + __asm__ volatile( 1.158 + "1:\n\t" 1.159 + " mov %1, %%o3\n\t" 1.160 + " ldx [%2], %%o2\n\t" 1.161 + " casx [%2], %%o2, %%o3\n\t" 1.162 + " cmp %%o2, %%o3\n\t" 1.163 + " bne %%xcc, 1b\n\t" 1.164 + " nop\n\t" 1.165 + " mov %%o2, %0\n\t" 1.166 + : "=r" (rv) 1.167 + : "r" (exchange_value), "r" (dest) 1.168 + : "memory", "o2", "o3"); 1.169 +#else //_LP64 1.170 + __asm__ volatile( 1.171 + "swap [%2],%1\n\t" 1.172 + : "=r" (rv) 1.173 + : "0" (exchange_value) /* we use same register as for return value */, "r" (dest) 1.174 + : "memory"); 1.175 +#endif // _LP64 1.176 + return rv; 1.177 +} 1.178 + 1.179 +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { 1.180 + return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); 1.181 +} 1.182 + 1.183 + 1.184 +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { 1.185 + jint rv; 1.186 + __asm__ volatile( 1.187 + " cas [%2], %3, %0" 1.188 + : "=r" (rv) 1.189 + : "0" (exchange_value), "r" (dest), "r" (compare_value) 1.190 + : "memory"); 1.191 + return rv; 1.192 +} 1.193 + 1.194 +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { 1.195 +#ifdef _LP64 1.196 + jlong rv; 1.197 + __asm__ volatile( 1.198 + " casx [%2], %3, %0" 1.199 + : "=r" (rv) 1.200 + : "0" (exchange_value), "r" (dest), "r" (compare_value) 1.201 + : "memory"); 1.202 + return rv; 1.203 +#else //_LP64 1.204 + volatile jlong_accessor evl, cvl, rv; 1.205 + evl.long_value = exchange_value; 1.206 + cvl.long_value = compare_value; 1.207 + 1.208 + __asm__ volatile( 1.209 + " sllx %2, 32, %2\n\t" 1.210 + " srl %3, 0, %3\n\t" 1.211 + " or %2, %3, %2\n\t" 1.212 + " sllx %5, 32, %5\n\t" 1.213 + " srl %6, 0, %6\n\t" 1.214 + " or %5, %6, %5\n\t" 1.215 + " casx [%4], %5, %2\n\t" 1.216 + " srl %2, 0, %1\n\t" 1.217 + " srlx %2, 32, %0\n\t" 1.218 + : "=r" (rv.words[0]), "=r" (rv.words[1]) 1.219 + : "r" (evl.words[0]), "r" (evl.words[1]), "r" (dest), "r" (cvl.words[0]), "r" (cvl.words[1]) 1.220 + : "memory"); 1.221 + 1.222 + return rv.long_value; 1.223 +#endif //_LP64 1.224 +} 1.225 + 1.226 +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) { 1.227 + intptr_t rv; 1.228 +#ifdef _LP64 1.229 + __asm__ volatile( 1.230 + " casx [%2], %3, %0" 1.231 + : "=r" (rv) 1.232 + : "0" (exchange_value), "r" (dest), "r" (compare_value) 1.233 + : "memory"); 1.234 +#else //_LP64 1.235 + __asm__ volatile( 1.236 + " cas [%2], %3, %0" 1.237 + : "=r" (rv) 1.238 + : "0" (exchange_value), "r" (dest), "r" (compare_value) 1.239 + : "memory"); 1.240 +#endif // _LP64 1.241 + return rv; 1.242 +} 1.243 + 1.244 +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { 1.245 + return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value); 1.246 +} 1.247 + 1.248 +#else // _GNU_SOURCE 1.249 + 1.250 +#if defined(COMPILER2) || defined(_LP64) 1.251 + 1.252 +// This is the interface to the atomic instructions in solaris_sparc.il. 1.253 +// It's very messy because we need to support v8 and these instructions 1.254 +// are illegal there. When sparc v8 is dropped, we can drop out lots of 1.255 +// this code. Also compiler2 does not support v8 so the conditional code 1.256 +// omits the instruction set check. 1.257 + 1.258 +extern "C" jint _Atomic_swap32(jint exchange_value, volatile jint* dest); 1.259 +extern "C" intptr_t _Atomic_swap64(intptr_t exchange_value, volatile intptr_t* dest); 1.260 + 1.261 +extern "C" jint _Atomic_cas32(jint exchange_value, volatile jint* dest, jint compare_value); 1.262 +extern "C" intptr_t _Atomic_cas64(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value); 1.263 +extern "C" jlong _Atomic_casl (jlong exchange_value, volatile jlong* dest, jlong compare_value); 1.264 + 1.265 +extern "C" jint _Atomic_add32(jint inc, volatile jint* dest); 1.266 +extern "C" intptr_t _Atomic_add64(intptr_t add_value, volatile intptr_t* dest); 1.267 + 1.268 + 1.269 +inline jint Atomic::add (jint add_value, volatile jint* dest) { 1.270 + return _Atomic_add32(add_value, dest); 1.271 +} 1.272 + 1.273 +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { 1.274 +#ifdef _LP64 1.275 + return _Atomic_add64(add_value, dest); 1.276 +#else //_LP64 1.277 + return _Atomic_add32(add_value, dest); 1.278 +#endif // _LP64 1.279 +} 1.280 + 1.281 +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { 1.282 + return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest); 1.283 +} 1.284 + 1.285 + 1.286 +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { 1.287 + return _Atomic_swap32(exchange_value, dest); 1.288 +} 1.289 + 1.290 +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { 1.291 +#ifdef _LP64 1.292 + return _Atomic_swap64(exchange_value, dest); 1.293 +#else // _LP64 1.294 + return _Atomic_swap32(exchange_value, dest); 1.295 +#endif // _LP64 1.296 +} 1.297 + 1.298 +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { 1.299 + return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest); 1.300 +} 1.301 + 1.302 + 1.303 +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { 1.304 + return _Atomic_cas32(exchange_value, dest, compare_value); 1.305 +} 1.306 + 1.307 +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { 1.308 +#ifdef _LP64 1.309 + // Return 64 bit value in %o0 1.310 + return _Atomic_cas64((intptr_t)exchange_value, (intptr_t *)dest, (intptr_t)compare_value); 1.311 +#else // _LP64 1.312 + // Return 64 bit value in %o0,%o1 by hand 1.313 + return _Atomic_casl(exchange_value, dest, compare_value); 1.314 +#endif // _LP64 1.315 +} 1.316 + 1.317 +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) { 1.318 +#ifdef _LP64 1.319 + return _Atomic_cas64(exchange_value, dest, compare_value); 1.320 +#else // _LP64 1.321 + return _Atomic_cas32(exchange_value, dest, compare_value); 1.322 +#endif // _LP64 1.323 +} 1.324 + 1.325 +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { 1.326 + return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value); 1.327 +} 1.328 + 1.329 + 1.330 +#else // _LP64 || COMPILER2 1.331 + 1.332 + 1.333 +// 32-bit compiler1 only 1.334 + 1.335 +inline jint Atomic::add (jint add_value, volatile jint* dest) { 1.336 + return (*os::atomic_add_func)(add_value, dest); 1.337 +} 1.338 + 1.339 +inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) { 1.340 + return (intptr_t)add((jint)add_value, (volatile jint*)dest); 1.341 +} 1.342 + 1.343 +inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) { 1.344 + return (void*)add((jint)add_value, (volatile jint*)dest); 1.345 +} 1.346 + 1.347 + 1.348 +inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) { 1.349 + return (*os::atomic_xchg_func)(exchange_value, dest); 1.350 +} 1.351 + 1.352 +inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) { 1.353 + return (intptr_t)xchg((jint)exchange_value, (volatile jint*)dest); 1.354 +} 1.355 + 1.356 +inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) { 1.357 + return (void*)xchg((jint)exchange_value, (volatile jint*)dest); 1.358 +} 1.359 + 1.360 + 1.361 +inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) { 1.362 + return (*os::atomic_cmpxchg_func)(exchange_value, dest, compare_value); 1.363 +} 1.364 + 1.365 +inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) { 1.366 + return (*os::atomic_cmpxchg_long_func)(exchange_value, dest, compare_value); 1.367 +} 1.368 + 1.369 +inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) { 1.370 + return (intptr_t)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value); 1.371 +} 1.372 + 1.373 +inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) { 1.374 + return (void*)cmpxchg((jint)exchange_value, (volatile jint*)dest, (jint)compare_value); 1.375 +} 1.376 + 1.377 +#endif // _LP64 || COMPILER2 1.378 + 1.379 +#endif // _GNU_SOURCE 1.380 + 1.381 +#endif // OS_CPU_SOLARIS_SPARC_VM_ATOMIC_SOLARIS_SPARC_INLINE_HPP