2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 * Implements osl_[increment|decrement]InterlockedCount in two ways:
22 * sparcv8 architecture: use the "swap" instruction
23 * sparcv9/sparcv8plus architecture: use the "cas" instruction
25 * 32 bit mode with v8 and v8plus support:
26 * Initialize once with osl_InterlockedCountSetV9(int bv9) if you want to
27 * use the "cas" instruction, which is faster (no spinlock needed)
28 * Default is to use the "swap" instruction, which works on all supported
31 * osl_InterlockedCountSetV9(int bv9)
32 * bv9 = 0 use sparcv8 "swap" (spinlock)
33 * bv9 = 1 use sparcv9/sparcv8plus "cas" (no spinlock)
35 * 32 bit mode without v8 support (implies v8plus) or 64 bit mode:
36 * No need (nor the possibilty) to call osl_InterlockedCountSetV9(),
37 * sparcv9 mode is implied. Assemble with -xarch=v8plus (32 bit) or
42 #if !defined(__sparcv8plus) && !defined(__sparcv9) && !defined(__sparc_v9__)
46 osl_incrementInterLockCountFuncPtr
:
47 .word osl_incrementInterlockedCountV8
48 .type osl_incrementInterLockCountFuncPtr,#object
49 .size osl_incrementInterLockCountFuncPtr,4
52 osl_decrementInterLockCountFuncPtr
:
53 .word osl_decrementInterlockedCountV8
54 .type osl_decrementInterLockCountFuncPtr,#object
55 .size osl_decrementInterLockCountFuncPtr,4
59 #if defined(NETBSD) || defined(LINUX)
60 /* add the address of the calling "call" instruction (stored in %o7) to
61 * %o5 which contains _GLOBAL_OFFSET_TABLE_
68 .global osl_incrementInterlockedCount
71 osl_incrementInterlockedCount
:
73 #if defined(NETBSD) || defined(LINUX)
75 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
77 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
80 set osl_incrementInterLockCountFuncPtr
, %o1
87 .type osl_incrementInterlockedCount,#function
88 .size osl_incrementInterlockedCount,.-osl_incrementInterlockedCount
91 .global osl_decrementInterlockedCount
94 osl_decrementInterlockedCount
:
96 #if defined(NETBSD) || defined(LINUX)
98 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
100 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
103 set osl_decrementInterLockCountFuncPtr
, %o1
104 #if defined(NETBSD) || defined(LINUX)
110 .type osl_decrementInterlockedCount,#function
111 .size osl_decrementInterlockedCount,.-osl_decrementInterlockedCount
114 .global osl_InterlockedCountSetV9
117 osl_InterlockedCountSetV9
:
119 #if defined(NETBSD) || defined(LINUX)
121 sethi
%hi
(_GLOBAL_OFFSET_TABLE_-
4), %o5
123 add %o5
, %lo
(_GLOBAL_OFFSET_TABLE_+
4), %o5
126 set osl_incrementInterLockCountFuncPtr
, %o1
127 set osl_decrementInterLockCountFuncPtr
, %o2
131 set osl_incrementInterlockedCountV8
, %o0
132 set osl_decrementInterlockedCountV8
, %o3
133 #if defined(NETBSD) || defined(LINUX)
142 1: set osl_incrementInterlockedCountV9
, %o0
143 set osl_decrementInterlockedCountV9
, %o3
144 #if defined(NETBSD) || defined(LINUX)
154 .type osl_InterlockedCountSetV9,#function
155 .size osl_InterlockedCountSetV9,.-osl_InterlockedCountSetV9
159 .local osl_incrementInterlockedCountV8
162 ! Implements osl_
[increment|decrement
]InterlockedCount with sparcv8
"swap" instruction.
163 ! Uses
-4096 as lock value for spinlock to allow for small negative counts.
165 osl_incrementInterlockedCountV8
:
168 cmp %o1
, -4096 ! test spinlock
170 mov
-4096, %o1
! delay slot
174 inc
%o1
! delay slot
, if we got spinlock
, increment count
177 mov
%o1
, %o0
! delay slot
179 .type osl_incrementInterlockedCountV8,#function
180 .size osl_incrementInterlockedCountV8,.-osl_incrementInterlockedCountV8
184 .local osl_decrementInterlockedCountV8
187 osl_decrementInterlockedCountV8
:
190 cmp %o1
, -4096 ! test spinlock
192 mov
-4096, %o1
! delay slot
196 dec %o1
! delay slot
, if we got spinlock
, decrement count
197 st %o1
, [%o0
] ! delay slot
199 mov
%o1
, %o0
! delay slot
201 .type osl_decrementInterlockedCountV8,#function
202 .size osl_decrementInterlockedCountV8,.-osl_decrementInterlockedCountV8
204 #endif /* !__sparcv8plus && !__sparcv9 && !_sparcv9__ */
207 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
208 #define osl_incrementInterlockedCountV9 osl_incrementInterlockedCount
209 .global osl_incrementInterlockedCountV9
211 .local osl_incrementInterlockedCountV9
215 ! Implements osl_
[increment|decrement
]InterlockedCount with sparcv9
(sparcv8plus
) "cas"
218 osl_incrementInterlockedCountV9
:
222 ! allow linux to build for v8
224 ! cas
[%o0
], %o1
, %o2
229 add %o2
, 1, %o0
! delay slot
231 .type osl_incrementInterlockedCountV9,#function
232 .size osl_incrementInterlockedCountV9,.-osl_incrementInterlockedCountV9
236 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
237 #define osl_decrementInterlockedCountV9 osl_decrementInterlockedCount
238 .global osl_decrementInterlockedCountV9
240 .local osl_decrementInterlockedCountV9
244 osl_decrementInterlockedCountV9
:
248 ! allow linux to build for v8
250 ! cas
[%o0
], %o1
, %o2
255 sub %o2
, 1, %o0
! delay slot
257 .type osl_decrementInterlockedCountV9,#function
258 .size osl_decrementInterlockedCountV9,.-osl_decrementInterlockedCountV9