src/os_cpu/linux_sparc/vm/atomic_linux_sparc.inline.hpp

Tue, 29 Apr 2014 22:05:10 -0700

author
mikael
date
Tue, 29 Apr 2014 22:05:10 -0700
changeset 6683
7f77d17d0f13
parent 5283
46c544b8fbfc
child 6876
710a3c8b516e
permissions
-rw-r--r--

8042059: Various fixes to linux/sparc
Reviewed-by: twisti, kvn

phh@568 1 /*
simonis@4675 2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
phh@568 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
phh@568 4 *
phh@568 5 * This code is free software; you can redistribute it and/or modify it
phh@568 6 * under the terms of the GNU General Public License version 2 only, as
phh@568 7 * published by the Free Software Foundation.
phh@568 8 *
phh@568 9 * This code is distributed in the hope that it will be useful, but WITHOUT
phh@568 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
phh@568 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
phh@568 12 * version 2 for more details (a copy is included in the LICENSE file that
phh@568 13 * accompanied this code).
phh@568 14 *
phh@568 15 * You should have received a copy of the GNU General Public License version
phh@568 16 * 2 along with this work; if not, write to the Free Software Foundation,
phh@568 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
phh@568 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
phh@568 22 *
phh@568 23 */
phh@568 24
stefank@2314 25 #ifndef OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP
stefank@2314 26 #define OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP
stefank@2314 27
stefank@2314 28 #include "runtime/atomic.hpp"
stefank@2314 29 #include "runtime/os.hpp"
stefank@2314 30 #include "vm_version_sparc.hpp"
stefank@2314 31
phh@568 32 // Implementation of class atomic
phh@568 33
phh@568 34 inline void Atomic::store (jbyte store_value, jbyte* dest) { *dest = store_value; }
phh@568 35 inline void Atomic::store (jshort store_value, jshort* dest) { *dest = store_value; }
phh@568 36 inline void Atomic::store (jint store_value, jint* dest) { *dest = store_value; }
phh@568 37 inline void Atomic::store (jlong store_value, jlong* dest) { *dest = store_value; }
phh@568 38 inline void Atomic::store_ptr(intptr_t store_value, intptr_t* dest) { *dest = store_value; }
phh@568 39 inline void Atomic::store_ptr(void* store_value, void* dest) { *(void**)dest = store_value; }
phh@568 40
phh@568 41 inline void Atomic::store (jbyte store_value, volatile jbyte* dest) { *dest = store_value; }
phh@568 42 inline void Atomic::store (jshort store_value, volatile jshort* dest) { *dest = store_value; }
phh@568 43 inline void Atomic::store (jint store_value, volatile jint* dest) { *dest = store_value; }
phh@568 44 inline void Atomic::store (jlong store_value, volatile jlong* dest) { *dest = store_value; }
phh@568 45 inline void Atomic::store_ptr(intptr_t store_value, volatile intptr_t* dest) { *dest = store_value; }
phh@568 46 inline void Atomic::store_ptr(void* store_value, volatile void* dest) { *(void* volatile *)dest = store_value; }
phh@568 47
phh@568 48 inline void Atomic::inc (volatile jint* dest) { (void)add (1, dest); }
phh@568 49 inline void Atomic::inc_ptr(volatile intptr_t* dest) { (void)add_ptr(1, dest); }
phh@568 50 inline void Atomic::inc_ptr(volatile void* dest) { (void)add_ptr(1, dest); }
phh@568 51
phh@568 52 inline void Atomic::dec (volatile jint* dest) { (void)add (-1, dest); }
phh@568 53 inline void Atomic::dec_ptr(volatile intptr_t* dest) { (void)add_ptr(-1, dest); }
phh@568 54 inline void Atomic::dec_ptr(volatile void* dest) { (void)add_ptr(-1, dest); }
phh@568 55
kvn@2434 56 inline jlong Atomic::load(volatile jlong* src) { return *src; }
kvn@2434 57
phh@568 58 inline jint Atomic::add (jint add_value, volatile jint* dest) {
phh@568 59 intptr_t rv;
phh@568 60 __asm__ volatile(
phh@568 61 "1: \n\t"
phh@568 62 " ld [%2], %%o2\n\t"
phh@568 63 " add %1, %%o2, %%o3\n\t"
phh@568 64 " cas [%2], %%o2, %%o3\n\t"
phh@568 65 " cmp %%o2, %%o3\n\t"
phh@568 66 " bne 1b\n\t"
phh@568 67 " nop\n\t"
phh@568 68 " add %1, %%o2, %0\n\t"
phh@568 69 : "=r" (rv)
phh@568 70 : "r" (add_value), "r" (dest)
phh@568 71 : "memory", "o2", "o3");
phh@568 72 return rv;
phh@568 73 }
phh@568 74
phh@568 75 inline intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) {
phh@568 76 intptr_t rv;
phh@568 77 #ifdef _LP64
phh@568 78 __asm__ volatile(
phh@568 79 "1: \n\t"
phh@568 80 " ldx [%2], %%o2\n\t"
mikael@6683 81 " add %1, %%o2, %%o3\n\t"
phh@568 82 " casx [%2], %%o2, %%o3\n\t"
phh@568 83 " cmp %%o2, %%o3\n\t"
phh@568 84 " bne %%xcc, 1b\n\t"
phh@568 85 " nop\n\t"
mikael@6683 86 " add %1, %%o2, %0\n\t"
phh@568 87 : "=r" (rv)
phh@568 88 : "r" (add_value), "r" (dest)
phh@568 89 : "memory", "o2", "o3");
phh@568 90 #else
phh@568 91 __asm__ volatile(
phh@568 92 "1: \n\t"
phh@568 93 " ld [%2], %%o2\n\t"
phh@568 94 " add %1, %%o2, %%o3\n\t"
phh@568 95 " cas [%2], %%o2, %%o3\n\t"
phh@568 96 " cmp %%o2, %%o3\n\t"
phh@568 97 " bne 1b\n\t"
phh@568 98 " nop\n\t"
phh@568 99 " add %1, %%o2, %0\n\t"
phh@568 100 : "=r" (rv)
phh@568 101 : "r" (add_value), "r" (dest)
phh@568 102 : "memory", "o2", "o3");
phh@568 103 #endif // _LP64
phh@568 104 return rv;
phh@568 105 }
phh@568 106
phh@568 107 inline void* Atomic::add_ptr(intptr_t add_value, volatile void* dest) {
phh@568 108 return (void*)add_ptr((intptr_t)add_value, (volatile intptr_t*)dest);
phh@568 109 }
phh@568 110
phh@568 111
phh@568 112 inline jint Atomic::xchg (jint exchange_value, volatile jint* dest) {
phh@568 113 intptr_t rv = exchange_value;
phh@568 114 __asm__ volatile(
phh@568 115 " swap [%2],%1\n\t"
phh@568 116 : "=r" (rv)
phh@568 117 : "0" (exchange_value) /* we use same register as for return value */, "r" (dest)
phh@568 118 : "memory");
phh@568 119 return rv;
phh@568 120 }
phh@568 121
phh@568 122 inline intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t* dest) {
phh@568 123 intptr_t rv = exchange_value;
phh@568 124 #ifdef _LP64
phh@568 125 __asm__ volatile(
phh@568 126 "1:\n\t"
phh@568 127 " mov %1, %%o3\n\t"
phh@568 128 " ldx [%2], %%o2\n\t"
phh@568 129 " casx [%2], %%o2, %%o3\n\t"
phh@568 130 " cmp %%o2, %%o3\n\t"
phh@568 131 " bne %%xcc, 1b\n\t"
phh@568 132 " nop\n\t"
phh@568 133 " mov %%o2, %0\n\t"
phh@568 134 : "=r" (rv)
phh@568 135 : "r" (exchange_value), "r" (dest)
phh@568 136 : "memory", "o2", "o3");
phh@568 137 #else
phh@568 138 __asm__ volatile(
phh@568 139 "swap [%2],%1\n\t"
phh@568 140 : "=r" (rv)
phh@568 141 : "0" (exchange_value) /* we use same register as for return value */, "r" (dest)
phh@568 142 : "memory");
phh@568 143 #endif // _LP64
phh@568 144 return rv;
phh@568 145 }
phh@568 146
phh@568 147 inline void* Atomic::xchg_ptr(void* exchange_value, volatile void* dest) {
phh@568 148 return (void*)xchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest);
phh@568 149 }
phh@568 150
phh@568 151
phh@568 152 inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) {
phh@568 153 jint rv;
phh@568 154 __asm__ volatile(
phh@568 155 " cas [%2], %3, %0"
phh@568 156 : "=r" (rv)
phh@568 157 : "0" (exchange_value), "r" (dest), "r" (compare_value)
phh@568 158 : "memory");
phh@568 159 return rv;
phh@568 160 }
phh@568 161
phh@568 162 inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {
phh@568 163 #ifdef _LP64
phh@568 164 jlong rv;
phh@568 165 __asm__ volatile(
phh@568 166 " casx [%2], %3, %0"
phh@568 167 : "=r" (rv)
phh@568 168 : "0" (exchange_value), "r" (dest), "r" (compare_value)
phh@568 169 : "memory");
phh@568 170 return rv;
phh@568 171 #else
phh@568 172 volatile jlong_accessor evl, cvl, rv;
phh@568 173 evl.long_value = exchange_value;
phh@568 174 cvl.long_value = compare_value;
phh@568 175
phh@568 176 __asm__ volatile(
phh@568 177 " sllx %2, 32, %2\n\t"
phh@568 178 " srl %3, 0, %3\n\t"
phh@568 179 " or %2, %3, %2\n\t"
phh@568 180 " sllx %5, 32, %5\n\t"
phh@568 181 " srl %6, 0, %6\n\t"
phh@568 182 " or %5, %6, %5\n\t"
phh@568 183 " casx [%4], %5, %2\n\t"
phh@568 184 " srl %2, 0, %1\n\t"
phh@568 185 " srlx %2, 32, %0\n\t"
phh@568 186 : "=r" (rv.words[0]), "=r" (rv.words[1])
phh@568 187 : "r" (evl.words[0]), "r" (evl.words[1]), "r" (dest), "r" (cvl.words[0]), "r" (cvl.words[1])
phh@568 188 : "memory");
phh@568 189
phh@568 190 return rv.long_value;
phh@568 191 #endif
phh@568 192 }
phh@568 193
phh@568 194 inline intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, volatile intptr_t* dest, intptr_t compare_value) {
phh@568 195 intptr_t rv;
phh@568 196 #ifdef _LP64
phh@568 197 __asm__ volatile(
phh@568 198 " casx [%2], %3, %0"
phh@568 199 : "=r" (rv)
phh@568 200 : "0" (exchange_value), "r" (dest), "r" (compare_value)
phh@568 201 : "memory");
phh@568 202 #else
phh@568 203 __asm__ volatile(
phh@568 204 " cas [%2], %3, %0"
phh@568 205 : "=r" (rv)
phh@568 206 : "0" (exchange_value), "r" (dest), "r" (compare_value)
phh@568 207 : "memory");
phh@568 208 #endif // _LP64
phh@568 209 return rv;
phh@568 210 }
phh@568 211
phh@568 212 inline void* Atomic::cmpxchg_ptr(void* exchange_value, volatile void* dest, void* compare_value) {
phh@568 213 return (void*)cmpxchg_ptr((intptr_t)exchange_value, (volatile intptr_t*)dest, (intptr_t)compare_value);
phh@568 214 }
stefank@2314 215
stefank@2314 216 #endif // OS_CPU_LINUX_SPARC_VM_ATOMIC_LINUX_SPARC_INLINE_HPP

mercurial