1 //
   2 // Copyright (c) 2002, 2013, 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   // Clear SPARC fprs.FEF DU and DL bits --
  36   // allows the kernel to avoid saving FPU state at context-switch time.
  37   // Use for state-transition points (into _thread_blocked) or when
  38   // parking.
  39 
  40        .inline _mark_fpu_nosave, 0
  41        .volatile
  42        wr   %g0, 0, %fprs
  43        .nonvolatile
  44        .end
  45 
  46   // Support for jint Atomic::xchg(jint exchange_value, volatile jint* dest).
  47   //
  48   // Arguments:
  49   //      exchange_value: O0
  50   //      dest:           O1
  51   //
  52   // Results:
  53   //     O0: the value previously stored in dest
  54 
  55         .inline _Atomic_swap32, 2
  56         .volatile
  57         swap    [%o1],%o0
  58         .nonvolatile
  59         .end
  60 
  61 
  62   // Support for intptr_t Atomic::xchg_ptr(intptr_t exchange_value, volatile intptr_t * dest).
  63   //
  64   // 64-bit
  65   //
  66   // Arguments:
  67   //      exchange_value: O0
  68   //      dest:           O1
  69   //
  70   // Results:
  71   //     O0: the value previously stored in dest
  72 
  73         .inline _Atomic_swap64, 2
  74         .volatile
  75     1:
  76         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   // Support for jlong Atomic::load and Atomic::store on v9.
 156   //
 157   // void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst)
 158   //
 159   // Arguments:
 160   //      src:  O0
 161   //      dest: O1
 162   //
 163   // Overwrites O2
 164 
 165         .inline _Atomic_move_long_v9,2
 166         .volatile
 167         ldx     [%o0], %o2
 168         stx     %o2, [%o1]
 169         .nonvolatile
 170         .end
 171 
 172   // Support for jint Atomic::add(jint add_value, volatile jint* dest).
 173   //
 174   // Arguments:
 175   //      add_value: O0   (e.g., +1 or -1)
 176   //      dest:      O1
 177   //
 178   // Results:
 179   //     O0: the new value stored in dest
 180   //
 181   // Overwrites O3
 182 
 183         .inline _Atomic_add32, 2
 184         .volatile
 185     2:
 186         ld      [%o1], %o2
 187         add     %o0, %o2, %o3
 188         cas     [%o1], %o2, %o3
 189         cmp     %o2, %o3
 190         bne     2b
 191          nop
 192         add     %o0, %o2, %o0
 193         .nonvolatile
 194         .end
 195 
 196 
 197   // Support for intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
 198   //
 199   // 64-bit
 200   //
 201   // Arguments:
 202   //      add_value: O0   (e.g., +1 or -1)
 203   //      dest:      O1
 204   //
 205   // Results:
 206   //     O0: the new value stored in dest
 207   //
 208   // Overwrites O3
 209 
 210         .inline _Atomic_add64, 2
 211         .volatile
 212     3:
 213         ldx     [%o1], %o2
 214         add     %o0, %o2, %o3
 215         casx    [%o1], %o2, %o3
 216         cmp     %o2, %o3
 217         bne     %xcc, 3b
 218          nop
 219         add     %o0, %o2, %o0
 220         .nonvolatile
 221         .end
 222 
 223 
 224   // Support for void Prefetch::read(void *loc, intx interval)
 225   //
 226   // Prefetch for several reads.
 227 
 228         .inline _Prefetch_read, 2
 229         .volatile
 230         prefetch [%o0+%o1], 0
 231         .nonvolatile
 232         .end
 233 
 234 
 235   // Support for void Prefetch::write(void *loc, intx interval)
 236   //
 237   // Prefetch for several writes.
 238 
 239         .inline _Prefetch_write, 2
 240         .volatile
 241         prefetch [%o0+%o1], 2
 242         .nonvolatile
 243         .end
 244 
 245 
 246   // Support for void Copy::conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count)
 247   //
 248   // 32-bit
 249   //
 250   // Arguments:
 251   //      from:  O0
 252   //      to:    O1
 253   //      count: O2 treated as signed
 254   //
 255   // Clobbers:
 256   //      long_value: O2, O3
 257   //      count:      O4
 258   //
 259   // if (from > to) {
 260   //   while (--count >= 0) {
 261   //     *to++ = *from++;
 262   //   }
 263   // } else {
 264   //   while (--count >= 0) {
 265   //     to[count] = from[count];
 266   //   }
 267   // }
 268         .inline _Copy_conjoint_jlongs_atomic, 3
 269         .volatile
 270         cmp     %o0, %o1
 271         bleu    4f
 272         sll     %o2, 3, %o4
 273         ba      2f
 274     1:
 275         subcc   %o4, 8, %o4
 276         std     %o2, [%o1]
 277         add     %o0, 8, %o0
 278         add     %o1, 8, %o1
 279     2:
 280         bge,a   1b
 281         ldd     [%o0], %o2
 282         ba      5f
 283         nop
 284     3:
 285         std     %o2, [%o1+%o4]
 286     4:
 287         subcc   %o4, 8, %o4
 288         bge,a   3b
 289         ldd     [%o0+%o4], %o2
 290     5:
 291         .nonvolatile
 292         .end