bump product version to 4.1.6.2
[LibreOffice.git] / sal / osl / unx / asm / interlck_sparc.s
blob8d86b4de6e009dac80d040510f7314986acd7e5e
1 /*
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
29 * SPARC cpu's
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
38 * -xarch=v9 (64 bit).
42 #if !defined(__sparcv8plus) && !defined(__sparcv9) && !defined(__sparc_v9__)
44 .section ".data"
45 .align 4
46 osl_incrementInterLockCountFuncPtr:
47 .word osl_incrementInterlockedCountV8
48 .type osl_incrementInterLockCountFuncPtr,#object
49 .size osl_incrementInterLockCountFuncPtr,4
51 .align 4
52 osl_decrementInterLockCountFuncPtr:
53 .word osl_decrementInterlockedCountV8
54 .type osl_decrementInterLockCountFuncPtr,#object
55 .size osl_decrementInterLockCountFuncPtr,4
57 .section ".text"
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_
63 .Laddoseven:
64 retl
65 add %o7, %o5, %o5
66 #endif
68 .global osl_incrementInterlockedCount
69 .align 4
71 osl_incrementInterlockedCount:
73 #if defined(NETBSD) || defined(LINUX)
74 mov %o7, %g1
75 sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
76 call .Laddoseven
77 add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
78 mov %g1, %o7
79 #endif
80 set osl_incrementInterLockCountFuncPtr, %o1
81 #if defined(NETBSD)
82 ld [%o1 + %o5], %o1
83 #endif
84 ld [%o1], %o1
85 jmp %o1
86 nop ! delay slot
87 .type osl_incrementInterlockedCount,#function
88 .size osl_incrementInterlockedCount,.-osl_incrementInterlockedCount
90 .section ".text"
91 .global osl_decrementInterlockedCount
92 .align 4
94 osl_decrementInterlockedCount:
96 #if defined(NETBSD) || defined(LINUX)
97 mov %o7, %g1
98 sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
99 call .Laddoseven
100 add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
101 mov %g1, %o7
102 #endif
103 set osl_decrementInterLockCountFuncPtr, %o1
104 #if defined(NETBSD) || defined(LINUX)
105 ld [%o1 + %o5], %o1
106 #endif
107 ld [%o1], %o1
108 jmp %o1
109 nop ! delay slot
110 .type osl_decrementInterlockedCount,#function
111 .size osl_decrementInterlockedCount,.-osl_decrementInterlockedCount
113 .section ".text"
114 .global osl_InterlockedCountSetV9
115 .align 4
117 osl_InterlockedCountSetV9:
119 #if defined(NETBSD) || defined(LINUX)
120 mov %o7, %g1
121 sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
122 call .Laddoseven
123 add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
124 mov %g1, %o7
125 #endif
126 set osl_incrementInterLockCountFuncPtr, %o1
127 set osl_decrementInterLockCountFuncPtr, %o2
128 cmp %o0, %g0
129 bnz 1f
130 nop ! delay slot
131 set osl_incrementInterlockedCountV8, %o0
132 set osl_decrementInterlockedCountV8, %o3
133 #if defined(NETBSD) || defined(LINUX)
134 ld [%o0 + %o5], %o0
135 ld [%o1 + %o5], %o1
136 ld [%o2 + %o5], %o2
137 ld [%o3 + %o5], %o3
138 #endif
139 st %o3,[%o2]
140 retl
141 st %o0,[%o1]
142 1: set osl_incrementInterlockedCountV9, %o0
143 set osl_decrementInterlockedCountV9, %o3
144 #if defined(NETBSD) || defined(LINUX)
145 ld [%o0 + %o5], %o0
146 ld [%o1 + %o5], %o1
147 ld [%o2 + %o5], %o2
148 ld [%o3 + %o5], %o3
149 #endif
150 st %o3,[%o2]
151 retl
152 st %o0,[%o1]
154 .type osl_InterlockedCountSetV9,#function
155 .size osl_InterlockedCountSetV9,.-osl_InterlockedCountSetV9
158 .section ".text"
159 .local osl_incrementInterlockedCountV8
160 .align 4
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:
167 1: ld [%o0], %o1
168 cmp %o1, -4096 ! test spinlock
169 be 1b
170 mov -4096, %o1 ! delay slot
171 swap [%o0], %o1
172 cmp %o1, -4096
173 be 1b
174 inc %o1 ! delay slot, if we got spinlock, increment count
175 st %o1, [%o0]
176 retl
177 mov %o1, %o0 ! delay slot
179 .type osl_incrementInterlockedCountV8,#function
180 .size osl_incrementInterlockedCountV8,.-osl_incrementInterlockedCountV8
183 .section ".text"
184 .local osl_decrementInterlockedCountV8
185 .align 4
187 osl_decrementInterlockedCountV8:
189 1: ld [%o0], %o1
190 cmp %o1, -4096 ! test spinlock
191 be 1b
192 mov -4096, %o1 ! delay slot
193 swap [%o0], %o1
194 cmp %o1, -4096
195 be 1b
196 dec %o1 ! delay slot, if we got spinlock, decrement count
197 st %o1, [%o0] ! delay slot
198 retl
199 mov %o1, %o0 ! delay slot
201 .type osl_decrementInterlockedCountV8,#function
202 .size osl_decrementInterlockedCountV8,.-osl_decrementInterlockedCountV8
204 #endif /* !__sparcv8plus && !__sparcv9 && !_sparcv9__ */
206 .section ".text"
207 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
208 #define osl_incrementInterlockedCountV9 osl_incrementInterlockedCount
209 .global osl_incrementInterlockedCountV9
210 #else
211 .local osl_incrementInterlockedCountV9
212 #endif
213 .align 8
215 ! Implements osl_[increment|decrement]InterlockedCount with sparcv9(sparcv8plus) "cas"
216 ! instruction.
218 osl_incrementInterlockedCountV9:
220 1: ld [%o0], %o1
221 add %o1, 1, %o2
222 ! allow linux to build for v8
223 .word 0xD5E21009
224 ! cas [%o0], %o1, %o2
225 cmp %o1, %o2
226 bne 1b
227 nop ! delay slot
228 retl
229 add %o2, 1, %o0 ! delay slot
231 .type osl_incrementInterlockedCountV9,#function
232 .size osl_incrementInterlockedCountV9,.-osl_incrementInterlockedCountV9
235 .section ".text"
236 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
237 #define osl_decrementInterlockedCountV9 osl_decrementInterlockedCount
238 .global osl_decrementInterlockedCountV9
239 #else
240 .local osl_decrementInterlockedCountV9
241 #endif
242 .align 8
244 osl_decrementInterlockedCountV9:
246 1: ld [%o0], %o1
247 sub %o1, 1, %o2
248 ! allow linux to build for v8
249 .word 0xD5E21009
250 ! cas [%o0], %o1, %o2
251 cmp %o1, %o2
252 bne 1b
253 nop ! delay slot
254 retl
255 sub %o2, 1, %o0 ! delay slot
257 .type osl_decrementInterlockedCountV9,#function
258 .size osl_decrementInterlockedCountV9,.-osl_decrementInterlockedCountV9