merge the formfield patch from ooo-build
[ooovba.git] / sal / osl / unx / asm / interlck_sparc.s
blob51604d3ea1a8734e639795e41d9a08e2b32847ae
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: interlck_sparc.s,v $
10 * $Revision: 1.7 $
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
41 * SPARC cpu's
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
50 * -xarch=v9 (64 bit).
54 #if !defined(__sparcv8plus) && !defined(__sparcv9) && !defined(__sparc_v9__)
56 .section ".data"
57 .align 4
58 osl_incrementInterLockCountFuncPtr:
59 .word osl_incrementInterlockedCountV8
60 .type osl_incrementInterLockCountFuncPtr,#object
61 .size osl_incrementInterLockCountFuncPtr,4
63 .align 4
64 osl_decrementInterLockCountFuncPtr:
65 .word osl_decrementInterlockedCountV8
66 .type osl_decrementInterLockCountFuncPtr,#object
67 .size osl_decrementInterLockCountFuncPtr,4
69 .section ".text"
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_
75 .Laddoseven:
76 retl
77 add %o7, %o5, %o5
78 #endif
80 .global osl_incrementInterlockedCount
81 .align 4
83 osl_incrementInterlockedCount:
85 #if defined(NETBSD) || defined(LINUX)
86 mov %o7, %g1
87 sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
88 call .Laddoseven
89 add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
90 mov %g1, %o7
91 #endif
92 set osl_incrementInterLockCountFuncPtr, %o1
93 #if defined(NETBSD)
94 ld [%o1 + %o5], %o1
95 #endif
96 ld [%o1], %o1
97 jmp %o1
98 nop ! delay slot
99 .type osl_incrementInterlockedCount,#function
100 .size osl_incrementInterlockedCount,.-osl_incrementInterlockedCount
102 .section ".text"
103 .global osl_decrementInterlockedCount
104 .align 4
106 osl_decrementInterlockedCount:
108 #if defined(NETBSD) || defined(LINUX)
109 mov %o7, %g1
110 sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
111 call .Laddoseven
112 add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
113 mov %g1, %o7
114 #endif
115 set osl_decrementInterLockCountFuncPtr, %o1
116 #if defined(NETBSD) || defined(LINUX)
117 ld [%o1 + %o5], %o1
118 #endif
119 ld [%o1], %o1
120 jmp %o1
121 nop ! delay slot
122 .type osl_decrementInterlockedCount,#function
123 .size osl_decrementInterlockedCount,.-osl_decrementInterlockedCount
125 .section ".text"
126 .global osl_InterlockedCountSetV9
127 .align 4
129 osl_InterlockedCountSetV9:
131 #if defined(NETBSD) || defined(LINUX)
132 mov %o7, %g1
133 sethi %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
134 call .Laddoseven
135 add %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
136 mov %g1, %o7
137 #endif
138 set osl_incrementInterLockCountFuncPtr, %o1
139 set osl_decrementInterLockCountFuncPtr, %o2
140 cmp %o0, %g0
141 bnz 1f
142 nop ! delay slot
143 set osl_incrementInterlockedCountV8, %o0
144 set osl_decrementInterlockedCountV8, %o3
145 #if defined(NETBSD) || defined(LINUX)
146 ld [%o0 + %o5], %o0
147 ld [%o1 + %o5], %o1
148 ld [%o2 + %o5], %o2
149 ld [%o3 + %o5], %o3
150 #endif
151 st %o3,[%o2]
152 retl
153 st %o0,[%o1]
154 1: set osl_incrementInterlockedCountV9, %o0
155 set osl_decrementInterlockedCountV9, %o3
156 #if defined(NETBSD) || defined(LINUX)
157 ld [%o0 + %o5], %o0
158 ld [%o1 + %o5], %o1
159 ld [%o2 + %o5], %o2
160 ld [%o3 + %o5], %o3
161 #endif
162 st %o3,[%o2]
163 retl
164 st %o0,[%o1]
166 .type osl_InterlockedCountSetV9,#function
167 .size osl_InterlockedCountSetV9,.-osl_InterlockedCountSetV9
170 .section ".text"
171 .local osl_incrementInterlockedCountV8
172 .align 4
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:
179 1: ld [%o0], %o1
180 cmp %o1, -4096 ! test spinlock
181 be 1b
182 mov -4096, %o1 ! delay slot
183 swap [%o0], %o1
184 cmp %o1, -4096
185 be 1b
186 inc %o1 ! delay slot, if we got spinlock, increment count
187 st %o1, [%o0]
188 retl
189 mov %o1, %o0 ! delay slot
191 .type osl_incrementInterlockedCountV8,#function
192 .size osl_incrementInterlockedCountV8,.-osl_incrementInterlockedCountV8
195 .section ".text"
196 .local osl_decrementInterlockedCountV8
197 .align 4
199 osl_decrementInterlockedCountV8:
201 1: ld [%o0], %o1
202 cmp %o1, -4096 ! test spinlock
203 be 1b
204 mov -4096, %o1 ! delay slot
205 swap [%o0], %o1
206 cmp %o1, -4096
207 be 1b
208 dec %o1 ! delay slot, if we got spinlock, decrement count
209 st %o1, [%o0] ! delay slot
210 retl
211 mov %o1, %o0 ! delay slot
213 .type osl_decrementInterlockedCountV8,#function
214 .size osl_decrementInterlockedCountV8,.-osl_decrementInterlockedCountV8
216 #endif /* !__sparcv8plus && !__sparcv9 && !_sparcv9__ */
218 .section ".text"
219 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
220 #define osl_incrementInterlockedCountV9 osl_incrementInterlockedCount
221 .global osl_incrementInterlockedCountV9
222 #else
223 .local osl_incrementInterlockedCountV9
224 #endif
225 .align 8
227 ! Implements osl_[increment|decrement]InterlockedCount with sparcv9(sparcv8plus) "cas"
228 ! instruction.
230 osl_incrementInterlockedCountV9:
232 1: ld [%o0], %o1
233 add %o1, 1, %o2
234 ! allow linux to build for v8
235 .word 0xD5E21009
236 ! cas [%o0], %o1, %o2
237 cmp %o1, %o2
238 bne 1b
239 nop ! delay slot
240 retl
241 add %o2, 1, %o0 ! delay slot
243 .type osl_incrementInterlockedCountV9,#function
244 .size osl_incrementInterlockedCountV9,.-osl_incrementInterlockedCountV9
247 .section ".text"
248 #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
249 #define osl_decrementInterlockedCountV9 osl_decrementInterlockedCount
250 .global osl_decrementInterlockedCountV9
251 #else
252 .local osl_decrementInterlockedCountV9
253 #endif
254 .align 8
256 osl_decrementInterlockedCountV9:
258 1: ld [%o0], %o1
259 sub %o1, 1, %o2
260 ! allow linux to build for v8
261 .word 0xD5E21009
262 ! cas [%o0], %o1, %o2
263 cmp %o1, %o2
264 bne 1b
265 nop ! delay slot
266 retl
267 sub %o2, 1, %o0 ! delay slot
269 .type osl_decrementInterlockedCountV9,#function
270 .size osl_decrementInterlockedCountV9,.-osl_decrementInterlockedCountV9