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 jint Atomic::cmpxchg(jint exchange_value, 77 // volatile jint* dest, 78 // jint compare_value) 79 // 80 // Arguments: 81 // exchange_value: O0 82 // dest: O1 83 // compare_value: O2 84 // 85 // Results: 86 // O0: the value previously stored in dest 87 88 .inline _Atomic_cas32, 3 89 .volatile 90 cas [%o1], %o2, %o0 91 .nonvolatile 92 .end 93 94 95 // Support for intptr_t Atomic::cmpxchg_ptr(intptr_t exchange_value, 96 // volatile intptr_t* dest, 97 // intptr_t compare_value) 98 // 99 // 64-bit 100 // 101 // Arguments: 102 // exchange_value: O0 103 // dest: O1 104 // compare_value: O2 105 // 106 // Results: 107 // O0: the value previously stored in dest 108 109 .inline _Atomic_cas64, 3 110 .volatile 111 casx [%o1], %o2, %o0 112 .nonvolatile 113 .end 114 115 116 // Support for jlong Atomic::cmpxchg(jlong exchange_value, 117 // volatile jlong* dest, 118 // jlong compare_value) 119 // 120 // 32-bit calling conventions 121 // 122 // Arguments: 123 // exchange_value: O1:O0 124 // dest: O2 125 // compare_value: O4:O3 126 // 127 // Results: 128 // O1:O0: the value previously stored in dest 129 130 .inline _Atomic_casl, 3 131 .volatile 132 sllx %o0, 32, %o0 133 srl %o1, 0, %o1 134 or %o0,%o1,%o0 135 sllx %o3, 32, %o3 136 srl %o4, 0, %o4 137 or %o3,%o4,%o3 138 casx [%o2], %o3, %o0 139 srl %o0, 0, %o1 140 srlx %o0, 32, %o0 141 .nonvolatile 142 .end 143 144 // Support for jlong Atomic::load and Atomic::store on v9. 145 // 146 // void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst) 147 // 148 // Arguments: 149 // src: O0 150 // dest: O1 151 // 152 // Overwrites O2 153 154 .inline _Atomic_move_long_v9,2 155 .volatile 156 ldx [%o0], %o2 157 stx %o2, [%o1] 158 .nonvolatile 159 .end 160 161 // Support for jint Atomic::add(jint add_value, volatile jint* dest). 162 // 163 // Arguments: 164 // add_value: O0 (e.g., +1 or -1) 165 // dest: O1 166 // 167 // Results: 168 // O0: the new value stored in dest 169 // 170 // Overwrites O3 171 172 .inline _Atomic_add32, 2 173 .volatile 174 2: 175 ld [%o1], %o2 176 add %o0, %o2, %o3 177 cas [%o1], %o2, %o3 178 cmp %o2, %o3 179 bne 2b 180 nop 181 add %o0, %o2, %o0 182 .nonvolatile 183 .end 184 185 186 // Support for intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest) 187 // 188 // 64-bit 189 // 190 // Arguments: 191 // add_value: O0 (e.g., +1 or -1) 192 // dest: O1 193 // 194 // Results: 195 // O0: the new value stored in dest 196 // 197 // Overwrites O3 198 199 .inline _Atomic_add64, 2 200 .volatile 201 3: 202 ldx [%o1], %o2 203 add %o0, %o2, %o3 204 casx [%o1], %o2, %o3 205 cmp %o2, %o3 206 bne %xcc, 3b 207 nop 208 add %o0, %o2, %o0 209 .nonvolatile 210 .end 211 212 213 // Support for void Prefetch::read(void *loc, intx interval) 214 // 215 // Prefetch for several reads. 216 217 .inline _Prefetch_read, 2 218 .volatile 219 prefetch [%o0+%o1], 0 220 .nonvolatile 221 .end 222 223 224 // Support for void Prefetch::write(void *loc, intx interval) 225 // 226 // Prefetch for several writes. 227 228 .inline _Prefetch_write, 2 229 .volatile 230 prefetch [%o0+%o1], 2 231 .nonvolatile 232 .end 233 234 235 // Support for void Copy::conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count) 236 // 237 // 32-bit 238 // 239 // Arguments: 240 // from: O0 241 // to: O1 242 // count: O2 treated as signed 243 // 244 // Clobbers: 245 // long_value: O2, O3 246 // count: O4 247 // 248 // if (from > to) { 249 // while (--count >= 0) { 250 // *to++ = *from++; 251 // } 252 // } else { 253 // while (--count >= 0) { 254 // to[count] = from[count]; 255 // } 256 // } 257 .inline _Copy_conjoint_jlongs_atomic, 3 258 .volatile 259 cmp %o0, %o1 260 bleu 4f 261 sll %o2, 3, %o4 262 ba 2f 263 1: 264 subcc %o4, 8, %o4 265 std %o2, [%o1] 266 add %o0, 8, %o0 267 add %o1, 8, %o1 268 2: 269 bge,a 1b 270 ldd [%o0], %o2 271 ba 5f 272 nop 273 3: 274 std %o2, [%o1+%o4] 275 4: 276 subcc %o4, 8, %o4 277 bge,a 3b 278 ldd [%o0+%o4], %o2 279 5: 280 .nonvolatile 281 .end