1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: interlck_sparc.s,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
33 * Implements osl_[increment|decrement]InterlockedCount in two ways:
34 * sparcv8 architecture: use the "swap" instruction
35 * sparcv9/sparcv8plus architecture: use the "cas" instruction
37 * 32 bit mode with v8 and v8plus support:
38 * Initialize once with osl_InterlockedCountSetV9(int bv9) if you want to
39 * use the "cas" instruction, which is faster (no spinlock needed)
40 * Default is to use the "swap" instruction, which works on all supported
43 * osl_InterlockedCountSetV9(int bv9)
44 * bv9 = 0 use sparcv8 "swap" (spinlock)
45 * bv9 = 1 use sparcv9/sparcv8plus "cas" (no spinlock)
47 * 32 bit mode without v8 support (implies v8plus) or 64 bit mode:
48 * No need (nor the possibilty) to call osl_InterlockedCountSetV9(),
49 * sparcv9 mode is implied. Assemble with -xarch=v8plus (32 bit) or
54 #if !defined(__sparcv8plus) && !defined(__sparcv9) && !defined(__sparc_v9__)
58 osl_incrementInterLockCountFuncPtr
:
59 .word osl_incrementInterlockedCountV8
60 .type osl_incrementInterLockCountFuncPtr,#object
61 .size osl_incrementInterLockCountFuncPtr,4
64 osl_decrementInterLockCountFuncPtr
:
65 .word osl_decrementInterlockedCountV8
66 .type osl_decrementInterLockCountFuncPtr,#object
67 .size osl_decrementInterLockCountFuncPtr,4
71 #if defined(NETBSD) || defined(LINUX)
72 /* add the address of the calling "call" instruction (stored in %o7) to
73 * %o5 which contains _GLOBAL_OFFSET_TABLE_
80 .global osl_incrementInterlockedCount
83 osl_incrementInterlockedCount
:
85 #if defined(NETBSD) || defined(LINUX)
87 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
89 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
92 set osl_incrementInterLockCountFuncPtr
, %o1
99 .type osl_incrementInterlockedCount,#function
100 .size osl_incrementInterlockedCount,.-osl_incrementInterlockedCount
103 .global osl_decrementInterlockedCount
106 osl_decrementInterlockedCount
:
108 #if defined(NETBSD) || defined(LINUX)
110 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
112 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
115 set osl_decrementInterLockCountFuncPtr
, %o1
116 #if defined(NETBSD) || defined(LINUX)
122 .type osl_decrementInterlockedCount,#function
123 .size osl_decrementInterlockedCount,.-osl_decrementInterlockedCount
126 .global osl_InterlockedCountSetV9
129 osl_InterlockedCountSetV9
:
131 #if defined(NETBSD) || defined(LINUX)
133 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
135 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
138 set osl_incrementInterLockCountFuncPtr
, %o1
139 set osl_decrementInterLockCountFuncPtr
, %o2
143 set osl_incrementInterlockedCountV8
, %o0
144 set osl_decrementInterlockedCountV8
, %o3
145 #if defined(NETBSD) || defined(LINUX)
154 1: set osl_incrementInterlockedCountV9
, %o0
155 set osl_decrementInterlockedCountV9
, %o3
156 #if defined(NETBSD) || defined(LINUX)
166 .type osl_InterlockedCountSetV9,#function
167 .size osl_InterlockedCountSetV9,.-osl_InterlockedCountSetV9
171 .local osl_incrementInterlockedCountV8
174 ! Implements osl_
[increment|decrement
]InterlockedCount with sparcv8
"swap" instruction.
175 ! Uses
-4096 as lock value for spinlock to allow for small negative counts.
177 osl_incrementInterlockedCountV8
:
180 cmp %o1
, -4096 ! test spinlock
182 mov
-4096, %o1
! delay slot
186 inc
%o1
! delay slot
, if we got spinlock
, increment count
189 mov
%o1
, %o0
! delay slot
191 .type osl_incrementInterlockedCountV8,#function
192 .size osl_incrementInterlockedCountV8,.-osl_incrementInterlockedCountV8
196 .local osl_decrementInterlockedCountV8
199 osl_decrementInterlockedCountV8
:
202 cmp %o1
, -4096 ! test spinlock
204 mov
-4096, %o1
! delay slot
208 dec %o1
! delay slot
, if we got spinlock
, decrement count
209 st %o1
, [%o0
] ! delay slot
211 mov
%o1
, %o0
! delay slot
213 .type osl_decrementInterlockedCountV8,#function
214 .size osl_decrementInterlockedCountV8,.-osl_decrementInterlockedCountV8
216 #endif /* !__sparcv8plus && !__sparcv9 && !_sparcv9__ */
219 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
220 #define osl_incrementInterlockedCountV9 osl_incrementInterlockedCount
221 .global osl_incrementInterlockedCountV9
223 .local osl_incrementInterlockedCountV9
227 ! Implements osl_
[increment|decrement
]InterlockedCount with sparcv9
(sparcv8plus
) "cas"
230 osl_incrementInterlockedCountV9
:
234 ! allow linux to build for v8
236 ! cas
[%o0
], %o1
, %o2
241 add %o2
, 1, %o0
! delay slot
243 .type osl_incrementInterlockedCountV9,#function
244 .size osl_incrementInterlockedCountV9,.-osl_incrementInterlockedCountV9
248 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
249 #define osl_decrementInterlockedCountV9 osl_decrementInterlockedCount
250 .global osl_decrementInterlockedCountV9
252 .local osl_decrementInterlockedCountV9
256 osl_decrementInterlockedCountV9
:
260 ! allow linux to build for v8
262 ! cas
[%o0
], %o1
, %o2
267 sub %o2
, 1, %o0
! delay slot
269 .type osl_decrementInterlockedCountV9,#function
270 .size osl_decrementInterlockedCountV9,.-osl_decrementInterlockedCountV9