~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/nsprpub/pr/src/md/unix/os_SunOS_ultrasparc.s

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
! -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 
2
 
3
! The contents of this file are subject to the Mozilla Public
 
4
! License Version 1.1 (the "License"); you may not use this file
 
5
! except in compliance with the License. You may obtain a copy of
 
6
! the License at http://www.mozilla.org/MPL/
 
7
 
8
! Software distributed under the License is distributed on an "AS
 
9
! IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 
10
! implied. See the License for the specific language governing
 
11
! rights and limitations under the License.
 
12
 
13
! The Original Code is the Netscape Portable Runtime (NSPR).
 
14
 
15
! The Initial Developer of the Original Code is Netscape
 
16
! Communications Corporation.  Portions created by Netscape are 
 
17
! Copyright (C) 1998-2000 Netscape Communications Corporation.  All
 
18
! Rights Reserved.
 
19
 
20
! Contributor(s):
 
21
 
22
! Alternatively, the contents of this file may be used under the
 
23
! terms of the GNU General Public License Version 2 or later (the
 
24
! "GPL"), in which case the provisions of the GPL are applicable 
 
25
! instead of those above.  If you wish to allow use of your 
 
26
! version of this file only under the terms of the GPL and not to
 
27
! allow others to use your version of this file under the MPL,
 
28
! indicate your decision by deleting the provisions above and
 
29
! replace them with the notice and other provisions required by
 
30
! the GPL.  If you do not delete the provisions above, a recipient
 
31
! may use your version of this file under either the MPL or the
 
32
! GPL.
 
33
 
34
 
 
35
!
 
36
!  atomic increment, decrement and swap routines for V8+ sparc (ultrasparc)
 
37
!  using CAS (compare-and-swap) atomic instructions
 
38
!
 
39
!  this MUST be compiled with an ultrasparc-aware assembler
 
40
!
 
41
!  standard asm linkage macros; this module must be compiled
 
42
!  with the -P option (use C preprocessor)
 
43
 
 
44
#include <sys/asm_linkage.h>
 
45
 
 
46
!  ======================================================================
 
47
!
 
48
!  Perform the sequence a = a + 1 atomically with respect to other
 
49
!  fetch-and-adds to location a in a wait-free fashion.
 
50
!
 
51
!  usage : val = PR_AtomicIncrement(address)
 
52
!  return: current value (you'd think this would be old val)
 
53
!
 
54
!  -----------------------
 
55
!  Note on REGISTER USAGE:
 
56
!  as this is a LEAF procedure, a new stack frame is not created;
 
57
!  we use the caller's stack frame so what would normally be %i (input)
 
58
!  registers are actually %o (output registers).  Also, we must not
 
59
!  overwrite the contents of %l (local) registers as they are not
 
60
!  assumed to be volatile during calls.
 
61
!
 
62
!  So, the registers used are:
 
63
!     %o0  [input]   - the address of the value to increment
 
64
!     %o1  [local]   - work register
 
65
!     %o2  [local]   - work register
 
66
!     %o3  [local]   - work register
 
67
!  -----------------------
 
68
 
 
69
        ENTRY(PR_AtomicIncrement)       ! standard assembler/ELF prologue
 
70
 
 
71
retryAI:
 
72
        ld      [%o0], %o2              ! set o2 to the current value
 
73
        add     %o2, 0x1, %o3           ! calc the new value
 
74
        mov     %o3, %o1                ! save the return value
 
75
        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
 
76
        cmp     %o2, %o3                ! see if we set the value
 
77
        bne     retryAI                 ! if not, try again
 
78
        nop                             ! empty out the branch pipeline
 
79
        retl                            ! return back to the caller
 
80
        mov     %o1, %o0                ! set the return code to the new value
 
81
 
 
82
        SET_SIZE(PR_AtomicIncrement)    ! standard assembler/ELF epilogue
 
83
 
 
84
!
 
85
!  end
 
86
!
 
87
!  ======================================================================
 
88
!
 
89
 
 
90
!  ======================================================================
 
91
!
 
92
!  Perform the sequence a = a - 1 atomically with respect to other
 
93
!  fetch-and-decs to location a in a wait-free fashion.
 
94
!
 
95
!  usage : val = PR_AtomicDecrement(address)
 
96
!  return: current value (you'd think this would be old val)
 
97
!
 
98
!  -----------------------
 
99
!  Note on REGISTER USAGE:
 
100
!  as this is a LEAF procedure, a new stack frame is not created;
 
101
!  we use the caller's stack frame so what would normally be %i (input)
 
102
!  registers are actually %o (output registers).  Also, we must not
 
103
!  overwrite the contents of %l (local) registers as they are not
 
104
!  assumed to be volatile during calls.
 
105
!
 
106
!  So, the registers used are:
 
107
!     %o0  [input]   - the address of the value to increment
 
108
!     %o1  [local]   - work register
 
109
!     %o2  [local]   - work register
 
110
!     %o3  [local]   - work register
 
111
!  -----------------------
 
112
 
 
113
        ENTRY(PR_AtomicDecrement)       ! standard assembler/ELF prologue
 
114
 
 
115
retryAD:
 
116
        ld      [%o0], %o2              ! set o2 to the current value
 
117
        sub     %o2, 0x1, %o3           ! calc the new value
 
118
        mov     %o3, %o1                ! save the return value
 
119
        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
 
120
        cmp     %o2, %o3                ! see if we set the value
 
121
        bne     retryAD                 ! if not, try again
 
122
        nop                             ! empty out the branch pipeline
 
123
        retl                            ! return back to the caller
 
124
        mov     %o1, %o0                ! set the return code to the new value
 
125
 
 
126
        SET_SIZE(PR_AtomicDecrement)    ! standard assembler/ELF epilogue
 
127
 
 
128
!
 
129
!  end
 
130
!
 
131
!  ======================================================================
 
132
!
 
133
 
 
134
!  ======================================================================
 
135
!
 
136
!  Perform the sequence a = b atomically with respect to other
 
137
!  fetch-and-stores to location a in a wait-free fashion.
 
138
!
 
139
!  usage : old_val = PR_AtomicSet(address, newval)
 
140
!
 
141
!  -----------------------
 
142
!  Note on REGISTER USAGE:
 
143
!  as this is a LEAF procedure, a new stack frame is not created;
 
144
!  we use the caller's stack frame so what would normally be %i (input)
 
145
!  registers are actually %o (output registers).  Also, we must not
 
146
!  overwrite the contents of %l (local) registers as they are not
 
147
!  assumed to be volatile during calls.
 
148
!
 
149
!  So, the registers used are:
 
150
!     %o0  [input]   - the address of the value to increment
 
151
!     %o1  [input]   - the new value to set for [%o0]
 
152
!     %o2  [local]   - work register
 
153
!     %o3  [local]   - work register
 
154
!  -----------------------
 
155
 
 
156
        ENTRY(PR_AtomicSet)             ! standard assembler/ELF prologue
 
157
 
 
158
retryAS:
 
159
        ld      [%o0], %o2              ! set o2 to the current value
 
160
        mov     %o1, %o3                ! set up the new value
 
161
        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
 
162
        cmp     %o2, %o3                ! see if we set the value
 
163
        bne     retryAS                 ! if not, try again
 
164
        nop                             ! empty out the branch pipeline
 
165
        retl                            ! return back to the caller
 
166
        mov     %o3, %o0                ! set the return code to the prev value
 
167
 
 
168
        SET_SIZE(PR_AtomicSet)          ! standard assembler/ELF epilogue
 
169
 
 
170
!
 
171
!  end
 
172
!
 
173
!  ======================================================================
 
174
!
 
175
 
 
176
!  ======================================================================
 
177
!
 
178
!  Perform the sequence a = a + b atomically with respect to other
 
179
!  fetch-and-adds to location a in a wait-free fashion.
 
180
!
 
181
!  usage : newval = PR_AtomicAdd(address, val)
 
182
!  return: the value after addition
 
183
!
 
184
        ENTRY(PR_AtomicAdd)       ! standard assembler/ELF prologue
 
185
 
 
186
retryAA:
 
187
        ld      [%o0], %o2              ! set o2 to the current value
 
188
        add     %o2, %o1, %o3           ! calc the new value
 
189
        mov     %o3, %o4                ! save the return value
 
190
        cas     [%o0], %o2, %o3         ! atomically set if o0 hasn't changed
 
191
        cmp     %o2, %o3                ! see if we set the value
 
192
        bne     retryAA                 ! if not, try again
 
193
        nop                             ! empty out the branch pipeline
 
194
        retl                            ! return back to the caller
 
195
        mov     %o4, %o0                ! set the return code to the new value
 
196
 
 
197
        SET_SIZE(PR_AtomicAdd)                  ! standard assembler/ELF epilogue
 
198
 
 
199
!
 
200
!  end
 
201
!