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 jlong Atomic::load and Atomic::store on v9.
  77   //
  78   // void _Atomic_move_long_v9(volatile jlong* src, volatile jlong* dst)
  79   //
  80   // Arguments:
  81   //      src:  O0
  82   //      dest: O1
  83   //
  84   // Overwrites O2
  85 
  86         .inline _Atomic_move_long_v9,2
  87         .volatile
  88         ldx     [%o0], %o2
  89         stx     %o2, [%o1]
  90         .nonvolatile
  91         .end
  92 
  93   // Support for jint Atomic::add(jint add_value, volatile jint* dest).
  94   //
  95   // Arguments:
  96   //      add_value: O0   (e.g., +1 or -1)
  97   //      dest:      O1
  98   //
  99   // Results:
 100   //     O0: the new value stored in dest
 101   //
 102   // Overwrites O3
 103 
 104         .inline _Atomic_add32, 2
 105         .volatile
 106     2:
 107         ld      [%o1], %o2
 108         add     %o0, %o2, %o3
 109         cas     [%o1], %o2, %o3
 110         cmp     %o2, %o3
 111         bne     2b
 112          nop
 113         add     %o0, %o2, %o0
 114         .nonvolatile
 115         .end
 116 
 117 
 118   // Support for intptr_t Atomic::add_ptr(intptr_t add_value, volatile intptr_t* dest)
 119   //
 120   // 64-bit
 121   //
 122   // Arguments:
 123   //      add_value: O0   (e.g., +1 or -1)
 124   //      dest:      O1
 125   //
 126   // Results:
 127   //     O0: the new value stored in dest
 128   //
 129   // Overwrites O3
 130 
 131         .inline _Atomic_add64, 2
 132         .volatile
 133     3:
 134         ldx     [%o1], %o2
 135         add     %o0, %o2, %o3
 136         casx    [%o1], %o2, %o3
 137         cmp     %o2, %o3
 138         bne     %xcc, 3b
 139          nop
 140         add     %o0, %o2, %o0
 141         .nonvolatile
 142         .end
 143 
 144 
 145   // Support for void Prefetch::read(void *loc, intx interval)
 146   //
 147   // Prefetch for several reads.
 148 
 149         .inline _Prefetch_read, 2
 150         .volatile
 151         prefetch [%o0+%o1], 0
 152         .nonvolatile
 153         .end
 154 
 155 
 156   // Support for void Prefetch::write(void *loc, intx interval)
 157   //
 158   // Prefetch for several writes.
 159 
 160         .inline _Prefetch_write, 2
 161         .volatile
 162         prefetch [%o0+%o1], 2
 163         .nonvolatile
 164         .end
 165 
 166 
 167   // Support for void Copy::conjoint_jlongs_atomic(jlong* from, jlong* to, size_t count)
 168   //
 169   // 32-bit
 170   //
 171   // Arguments:
 172   //      from:  O0
 173   //      to:    O1
 174   //      count: O2 treated as signed
 175   //
 176   // Clobbers:
 177   //      long_value: O2, O3
 178   //      count:      O4
 179   //
 180   // if (from > to) {
 181   //   while (--count >= 0) {
 182   //     *to++ = *from++;
 183   //   }
 184   // } else {
 185   //   while (--count >= 0) {
 186   //     to[count] = from[count];
 187   //   }
 188   // }
 189         .inline _Copy_conjoint_jlongs_atomic, 3
 190         .volatile
 191         cmp     %o0, %o1
 192         bleu    4f
 193         sll     %o2, 3, %o4
 194         ba      2f
 195     1:
 196         subcc   %o4, 8, %o4
 197         std     %o2, [%o1]
 198         add     %o0, 8, %o0
 199         add     %o1, 8, %o1
 200     2:
 201         bge,a   1b
 202         ldd     [%o0], %o2
 203         ba      5f
 204         nop
 205     3:
 206         std     %o2, [%o1+%o4]
 207     4:
 208         subcc   %o4, 8, %o4
 209         bge,a   3b
 210         ldd     [%o0+%o4], %o2
 211     5:
 212         .nonvolatile
 213         .end