1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
30 * Implements osl_[increment|decrement]InterlockedCount in two ways:
31 * sparcv8 architecture: use the "swap" instruction
32 * sparcv9/sparcv8plus architecture: use the "cas" instruction
34 * 32 bit mode with v8 and v8plus support:
35 * Initialize once with osl_InterlockedCountSetV9(int bv9) if you want to
36 * use the "cas" instruction, which is faster (no spinlock needed)
37 * Default is to use the "swap" instruction, which works on all supported
40 * osl_InterlockedCountSetV9(int bv9)
41 * bv9 = 0 use sparcv8 "swap" (spinlock)
42 * bv9 = 1 use sparcv9/sparcv8plus "cas" (no spinlock)
44 * 32 bit mode without v8 support (implies v8plus) or 64 bit mode:
45 * No need (nor the possibilty) to call osl_InterlockedCountSetV9(),
46 * sparcv9 mode is implied. Assemble with -xarch=v8plus (32 bit) or
51 #if !defined(__sparcv8plus) && !defined(__sparcv9) && !defined(__sparc_v9__)
55 osl_incrementInterLockCountFuncPtr
:
56 .word osl_incrementInterlockedCountV8
57 .type osl_incrementInterLockCountFuncPtr,#object
58 .size osl_incrementInterLockCountFuncPtr,4
61 osl_decrementInterLockCountFuncPtr
:
62 .word osl_decrementInterlockedCountV8
63 .type osl_decrementInterLockCountFuncPtr,#object
64 .size osl_decrementInterLockCountFuncPtr,4
68 #if defined(NETBSD) || defined(LINUX)
69 /* add the address of the calling "call" instruction (stored in %o7) to
70 * %o5 which contains _GLOBAL_OFFSET_TABLE_
77 .global osl_incrementInterlockedCount
80 osl_incrementInterlockedCount
:
82 #if defined(NETBSD) || defined(LINUX)
84 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
86 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
89 set osl_incrementInterLockCountFuncPtr
, %o1
96 .type osl_incrementInterlockedCount,#function
97 .size osl_incrementInterlockedCount,.-osl_incrementInterlockedCount
100 .global osl_decrementInterlockedCount
103 osl_decrementInterlockedCount
:
105 #if defined(NETBSD) || defined(LINUX)
107 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
109 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
112 set osl_decrementInterLockCountFuncPtr
, %o1
113 #if defined(NETBSD) || defined(LINUX)
119 .type osl_decrementInterlockedCount,#function
120 .size osl_decrementInterlockedCount,.-osl_decrementInterlockedCount
123 .global osl_InterlockedCountSetV9
126 osl_InterlockedCountSetV9
:
128 #if defined(NETBSD) || defined(LINUX)
130 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
132 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
135 set osl_incrementInterLockCountFuncPtr
, %o1
136 set osl_decrementInterLockCountFuncPtr
, %o2
140 set osl_incrementInterlockedCountV8
, %o0
141 set osl_decrementInterlockedCountV8
, %o3
142 #if defined(NETBSD) || defined(LINUX)
151 1: set osl_incrementInterlockedCountV9
, %o0
152 set osl_decrementInterlockedCountV9
, %o3
153 #if defined(NETBSD) || defined(LINUX)
163 .type osl_InterlockedCountSetV9,#function
164 .size osl_InterlockedCountSetV9,.-osl_InterlockedCountSetV9
168 .local osl_incrementInterlockedCountV8
171 ! Implements osl_
[increment|decrement
]InterlockedCount with sparcv8
"swap" instruction.
172 ! Uses
-4096 as lock value for spinlock to allow for small negative counts.
174 osl_incrementInterlockedCountV8
:
177 cmp %o1
, -4096 ! test spinlock
179 mov
-4096, %o1
! delay slot
183 inc
%o1
! delay slot
, if we got spinlock
, increment count
186 mov
%o1
, %o0
! delay slot
188 .type osl_incrementInterlockedCountV8,#function
189 .size osl_incrementInterlockedCountV8,.-osl_incrementInterlockedCountV8
193 .local osl_decrementInterlockedCountV8
196 osl_decrementInterlockedCountV8
:
199 cmp %o1
, -4096 ! test spinlock
201 mov
-4096, %o1
! delay slot
205 dec %o1
! delay slot
, if we got spinlock
, decrement count
206 st %o1
, [%o0
] ! delay slot
208 mov
%o1
, %o0
! delay slot
210 .type osl_decrementInterlockedCountV8,#function
211 .size osl_decrementInterlockedCountV8,.-osl_decrementInterlockedCountV8
213 #endif /* !__sparcv8plus && !__sparcv9 && !_sparcv9__ */
216 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
217 #define osl_incrementInterlockedCountV9 osl_incrementInterlockedCount
218 .global osl_incrementInterlockedCountV9
220 .local osl_incrementInterlockedCountV9
224 ! Implements osl_
[increment|decrement
]InterlockedCount with sparcv9
(sparcv8plus
) "cas"
227 osl_incrementInterlockedCountV9
:
231 ! allow linux to build for v8
233 ! cas
[%o0
], %o1
, %o2
238 add %o2
, 1, %o0
! delay slot
240 .type osl_incrementInterlockedCountV9,#function
241 .size osl_incrementInterlockedCountV9,.-osl_incrementInterlockedCountV9
245 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
246 #define osl_decrementInterlockedCountV9 osl_decrementInterlockedCount
247 .global osl_decrementInterlockedCountV9
249 .local osl_decrementInterlockedCountV9
253 osl_decrementInterlockedCountV9
:
257 ! allow linux to build for v8
259 ! cas
[%o0
], %o1
, %o2
264 sub %o2
, 1, %o0
! delay slot
266 .type osl_decrementInterlockedCountV9,#function
267 .size osl_decrementInterlockedCountV9,.-osl_decrementInterlockedCountV9