xref: /aoo4110/main/sal/osl/unx/asm/interlck_sparc.s (revision b1cdbd2c)
1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski 
25*b1cdbd2cSJim Jagielski /*
26*b1cdbd2cSJim Jagielski  * Implements osl_[increment|decrement]InterlockedCount in two ways:
27*b1cdbd2cSJim Jagielski  * sparcv8 architecture:                use the "swap" instruction
28*b1cdbd2cSJim Jagielski  * sparcv9/sparcv8plus architecture:    use the "cas"  instruction
29*b1cdbd2cSJim Jagielski  *
30*b1cdbd2cSJim Jagielski  * 32 bit mode with v8 and v8plus support:
31*b1cdbd2cSJim Jagielski  * Initialize once with osl_InterlockedCountSetV9(int bv9) if you want to
32*b1cdbd2cSJim Jagielski  * use the "cas" instruction, which is faster (no spinlock needed)
33*b1cdbd2cSJim Jagielski  * Default is to use the "swap" instruction, which works on all supported
34*b1cdbd2cSJim Jagielski  * SPARC cpu's
35*b1cdbd2cSJim Jagielski  *
36*b1cdbd2cSJim Jagielski  * osl_InterlockedCountSetV9(int bv9)
37*b1cdbd2cSJim Jagielski  *    bv9 = 0   use sparcv8 "swap" (spinlock)
38*b1cdbd2cSJim Jagielski  *    bv9 = 1   use sparcv9/sparcv8plus "cas" (no spinlock)
39*b1cdbd2cSJim Jagielski  *
40*b1cdbd2cSJim Jagielski  * 32 bit mode without v8 support (implies v8plus) or 64 bit mode:
41*b1cdbd2cSJim Jagielski  * No need (nor the possibilty) to call osl_InterlockedCountSetV9(),
42*b1cdbd2cSJim Jagielski  * sparcv9 mode is implied. Assemble with -xarch=v8plus (32 bit) or
43*b1cdbd2cSJim Jagielski  * -xarch=v9 (64 bit).
44*b1cdbd2cSJim Jagielski  *
45*b1cdbd2cSJim Jagielski  */
46*b1cdbd2cSJim Jagielski 
47*b1cdbd2cSJim Jagielski #if !defined(__sparcv8plus) && !defined(__sparcv9) && !defined(__sparc_v9__)
48*b1cdbd2cSJim Jagielski 
49*b1cdbd2cSJim Jagielski .section ".data"
50*b1cdbd2cSJim Jagielski .align 4
51*b1cdbd2cSJim Jagielski osl_incrementInterLockCountFuncPtr:
52*b1cdbd2cSJim Jagielski .word osl_incrementInterlockedCountV8
53*b1cdbd2cSJim Jagielski .type osl_incrementInterLockCountFuncPtr,#object
54*b1cdbd2cSJim Jagielski .size osl_incrementInterLockCountFuncPtr,4
55*b1cdbd2cSJim Jagielski 
56*b1cdbd2cSJim Jagielski .align 4
57*b1cdbd2cSJim Jagielski osl_decrementInterLockCountFuncPtr:
58*b1cdbd2cSJim Jagielski .word osl_decrementInterlockedCountV8
59*b1cdbd2cSJim Jagielski .type osl_decrementInterLockCountFuncPtr,#object
60*b1cdbd2cSJim Jagielski .size osl_decrementInterLockCountFuncPtr,4
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski .section   ".text"
63*b1cdbd2cSJim Jagielski 
64*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX)
65*b1cdbd2cSJim Jagielski /* add the address of the calling "call" instruction (stored in %o7) to
66*b1cdbd2cSJim Jagielski  * %o5 which contains _GLOBAL_OFFSET_TABLE_
67*b1cdbd2cSJim Jagielski  */
68*b1cdbd2cSJim Jagielski .Laddoseven:
69*b1cdbd2cSJim Jagielski         retl
70*b1cdbd2cSJim Jagielski         add %o7, %o5, %o5
71*b1cdbd2cSJim Jagielski #endif
72*b1cdbd2cSJim Jagielski 
73*b1cdbd2cSJim Jagielski  .global   osl_incrementInterlockedCount
74*b1cdbd2cSJim Jagielski  .align   4
75*b1cdbd2cSJim Jagielski 
76*b1cdbd2cSJim Jagielski osl_incrementInterlockedCount:
77*b1cdbd2cSJim Jagielski 
78*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX)
79*b1cdbd2cSJim Jagielski         mov     %o7, %g1
80*b1cdbd2cSJim Jagielski         sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
81*b1cdbd2cSJim Jagielski         call    .Laddoseven
82*b1cdbd2cSJim Jagielski         add     %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
83*b1cdbd2cSJim Jagielski         mov     %g1, %o7
84*b1cdbd2cSJim Jagielski #endif
85*b1cdbd2cSJim Jagielski         set     osl_incrementInterLockCountFuncPtr, %o1
86*b1cdbd2cSJim Jagielski #if defined(NETBSD)
87*b1cdbd2cSJim Jagielski         ld      [%o1 + %o5], %o1
88*b1cdbd2cSJim Jagielski #endif
89*b1cdbd2cSJim Jagielski         ld      [%o1], %o1
90*b1cdbd2cSJim Jagielski         jmp     %o1
91*b1cdbd2cSJim Jagielski         nop                                             ! delay slot
92*b1cdbd2cSJim Jagielski  .type  osl_incrementInterlockedCount,#function
93*b1cdbd2cSJim Jagielski  .size  osl_incrementInterlockedCount,.-osl_incrementInterlockedCount
94*b1cdbd2cSJim Jagielski 
95*b1cdbd2cSJim Jagielski .section   ".text"
96*b1cdbd2cSJim Jagielski  .global   osl_decrementInterlockedCount
97*b1cdbd2cSJim Jagielski  .align   4
98*b1cdbd2cSJim Jagielski 
99*b1cdbd2cSJim Jagielski osl_decrementInterlockedCount:
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX)
102*b1cdbd2cSJim Jagielski         mov     %o7, %g1
103*b1cdbd2cSJim Jagielski         sethi   %hi(_GLOBAL_OFFSET_TABLE_-4), %o5
104*b1cdbd2cSJim Jagielski         call    .Laddoseven
105*b1cdbd2cSJim Jagielski         add     %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
106*b1cdbd2cSJim Jagielski         mov     %g1, %o7
107*b1cdbd2cSJim Jagielski #endif
108*b1cdbd2cSJim Jagielski         set     osl_decrementInterLockCountFuncPtr, %o1
109*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX)
110*b1cdbd2cSJim Jagielski         ld      [%o1 + %o5], %o1
111*b1cdbd2cSJim Jagielski #endif
112*b1cdbd2cSJim Jagielski         ld      [%o1], %o1
113*b1cdbd2cSJim Jagielski         jmp     %o1
114*b1cdbd2cSJim Jagielski         nop                                             ! delay slot
115*b1cdbd2cSJim Jagielski  .type  osl_decrementInterlockedCount,#function
116*b1cdbd2cSJim Jagielski  .size  osl_decrementInterlockedCount,.-osl_decrementInterlockedCount
117*b1cdbd2cSJim Jagielski 
118*b1cdbd2cSJim Jagielski .section   ".text"
119*b1cdbd2cSJim Jagielski  .global   osl_InterlockedCountSetV9
120*b1cdbd2cSJim Jagielski  .align   4
121*b1cdbd2cSJim Jagielski 
122*b1cdbd2cSJim Jagielski osl_InterlockedCountSetV9:
123*b1cdbd2cSJim Jagielski 
124*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX)
125*b1cdbd2cSJim Jagielski         mov	    %o7, %g1
126*b1cdbd2cSJim Jagielski         sethi	%hi(_GLOBAL_OFFSET_TABLE_-4), %o5
127*b1cdbd2cSJim Jagielski         call	.Laddoseven
128*b1cdbd2cSJim Jagielski         add	    %o5, %lo(_GLOBAL_OFFSET_TABLE_+4), %o5
129*b1cdbd2cSJim Jagielski         mov	    %g1, %o7
130*b1cdbd2cSJim Jagielski #endif
131*b1cdbd2cSJim Jagielski         set     osl_incrementInterLockCountFuncPtr, %o1
132*b1cdbd2cSJim Jagielski         set     osl_decrementInterLockCountFuncPtr, %o2
133*b1cdbd2cSJim Jagielski         cmp     %o0, %g0
134*b1cdbd2cSJim Jagielski         bnz     1f
135*b1cdbd2cSJim Jagielski         nop                                             ! delay slot
136*b1cdbd2cSJim Jagielski         set     osl_incrementInterlockedCountV8, %o0
137*b1cdbd2cSJim Jagielski         set     osl_decrementInterlockedCountV8, %o3
138*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX)
139*b1cdbd2cSJim Jagielski         ld      [%o0 + %o5], %o0
140*b1cdbd2cSJim Jagielski         ld      [%o1 + %o5], %o1
141*b1cdbd2cSJim Jagielski         ld      [%o2 + %o5], %o2
142*b1cdbd2cSJim Jagielski         ld      [%o3 + %o5], %o3
143*b1cdbd2cSJim Jagielski #endif
144*b1cdbd2cSJim Jagielski         st      %o3,[%o2]
145*b1cdbd2cSJim Jagielski         retl
146*b1cdbd2cSJim Jagielski         st      %o0,[%o1]
147*b1cdbd2cSJim Jagielski 1:      set     osl_incrementInterlockedCountV9, %o0
148*b1cdbd2cSJim Jagielski         set     osl_decrementInterlockedCountV9, %o3
149*b1cdbd2cSJim Jagielski #if defined(NETBSD) || defined(LINUX)
150*b1cdbd2cSJim Jagielski         ld      [%o0 + %o5], %o0
151*b1cdbd2cSJim Jagielski         ld      [%o1 + %o5], %o1
152*b1cdbd2cSJim Jagielski         ld      [%o2 + %o5], %o2
153*b1cdbd2cSJim Jagielski         ld      [%o3 + %o5], %o3
154*b1cdbd2cSJim Jagielski #endif
155*b1cdbd2cSJim Jagielski         st      %o3,[%o2]
156*b1cdbd2cSJim Jagielski         retl
157*b1cdbd2cSJim Jagielski         st      %o0,[%o1]
158*b1cdbd2cSJim Jagielski 
159*b1cdbd2cSJim Jagielski  .type  osl_InterlockedCountSetV9,#function
160*b1cdbd2cSJim Jagielski  .size  osl_InterlockedCountSetV9,.-osl_InterlockedCountSetV9
161*b1cdbd2cSJim Jagielski 
162*b1cdbd2cSJim Jagielski 
163*b1cdbd2cSJim Jagielski .section   ".text"
164*b1cdbd2cSJim Jagielski  .local   osl_incrementInterlockedCountV8
165*b1cdbd2cSJim Jagielski  .align   4
166*b1cdbd2cSJim Jagielski 
167*b1cdbd2cSJim Jagielski ! Implements osl_[increment|decrement]InterlockedCount with sparcv8 "swap" instruction.
168*b1cdbd2cSJim Jagielski ! Uses -4096 as lock value for spinlock to allow for small negative counts.
169*b1cdbd2cSJim Jagielski 
170*b1cdbd2cSJim Jagielski osl_incrementInterlockedCountV8:
171*b1cdbd2cSJim Jagielski 
172*b1cdbd2cSJim Jagielski 1:      ld      [%o0], %o1
173*b1cdbd2cSJim Jagielski         cmp     %o1, -4096          ! test spinlock
174*b1cdbd2cSJim Jagielski         be      1b
175*b1cdbd2cSJim Jagielski         mov     -4096, %o1          ! delay slot
176*b1cdbd2cSJim Jagielski         swap    [%o0], %o1
177*b1cdbd2cSJim Jagielski         cmp     %o1, -4096
178*b1cdbd2cSJim Jagielski         be      1b
179*b1cdbd2cSJim Jagielski         inc     %o1                 ! delay slot, if we got spinlock, increment count
180*b1cdbd2cSJim Jagielski         st      %o1, [%o0]
181*b1cdbd2cSJim Jagielski         retl
182*b1cdbd2cSJim Jagielski         mov     %o1, %o0            ! delay slot
183*b1cdbd2cSJim Jagielski 
184*b1cdbd2cSJim Jagielski  .type  osl_incrementInterlockedCountV8,#function
185*b1cdbd2cSJim Jagielski  .size  osl_incrementInterlockedCountV8,.-osl_incrementInterlockedCountV8
186*b1cdbd2cSJim Jagielski 
187*b1cdbd2cSJim Jagielski 
188*b1cdbd2cSJim Jagielski .section   ".text"
189*b1cdbd2cSJim Jagielski  .local osl_decrementInterlockedCountV8
190*b1cdbd2cSJim Jagielski  .align   4
191*b1cdbd2cSJim Jagielski 
192*b1cdbd2cSJim Jagielski osl_decrementInterlockedCountV8:
193*b1cdbd2cSJim Jagielski 
194*b1cdbd2cSJim Jagielski 1:      ld      [%o0], %o1
195*b1cdbd2cSJim Jagielski         cmp     %o1, -4096          ! test spinlock
196*b1cdbd2cSJim Jagielski         be      1b
197*b1cdbd2cSJim Jagielski         mov     -4096, %o1          ! delay slot
198*b1cdbd2cSJim Jagielski         swap    [%o0], %o1
199*b1cdbd2cSJim Jagielski         cmp     %o1, -4096
200*b1cdbd2cSJim Jagielski         be      1b
201*b1cdbd2cSJim Jagielski         dec     %o1                 ! delay slot, if we got spinlock, decrement count
202*b1cdbd2cSJim Jagielski         st      %o1, [%o0]          ! delay slot
203*b1cdbd2cSJim Jagielski         retl
204*b1cdbd2cSJim Jagielski         mov     %o1, %o0            ! delay slot
205*b1cdbd2cSJim Jagielski 
206*b1cdbd2cSJim Jagielski  .type  osl_decrementInterlockedCountV8,#function
207*b1cdbd2cSJim Jagielski  .size  osl_decrementInterlockedCountV8,.-osl_decrementInterlockedCountV8
208*b1cdbd2cSJim Jagielski 
209*b1cdbd2cSJim Jagielski #endif /* !__sparcv8plus && !__sparcv9 && !_sparcv9__ */
210*b1cdbd2cSJim Jagielski 
211*b1cdbd2cSJim Jagielski .section   ".text"
212*b1cdbd2cSJim Jagielski #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
213*b1cdbd2cSJim Jagielski #define   osl_incrementInterlockedCountV9 osl_incrementInterlockedCount
214*b1cdbd2cSJim Jagielski  .global  osl_incrementInterlockedCountV9
215*b1cdbd2cSJim Jagielski #else
216*b1cdbd2cSJim Jagielski  .local   osl_incrementInterlockedCountV9
217*b1cdbd2cSJim Jagielski #endif
218*b1cdbd2cSJim Jagielski  .align   8
219*b1cdbd2cSJim Jagielski 
220*b1cdbd2cSJim Jagielski !   Implements osl_[increment|decrement]InterlockedCount with sparcv9(sparcv8plus) "cas"
221*b1cdbd2cSJim Jagielski !   instruction.
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski osl_incrementInterlockedCountV9:
224*b1cdbd2cSJim Jagielski 
225*b1cdbd2cSJim Jagielski 1:      ld      [%o0], %o1
226*b1cdbd2cSJim Jagielski         add     %o1, 1, %o2
227*b1cdbd2cSJim Jagielski !       allow linux to build for v8
228*b1cdbd2cSJim Jagielski         .word 0xD5E21009
229*b1cdbd2cSJim Jagielski !       cas     [%o0], %o1, %o2
230*b1cdbd2cSJim Jagielski         cmp     %o1, %o2
231*b1cdbd2cSJim Jagielski         bne     1b
232*b1cdbd2cSJim Jagielski         nop                         ! delay slot
233*b1cdbd2cSJim Jagielski         retl
234*b1cdbd2cSJim Jagielski         add     %o2, 1, %o0         ! delay slot
235*b1cdbd2cSJim Jagielski 
236*b1cdbd2cSJim Jagielski  .type  osl_incrementInterlockedCountV9,#function
237*b1cdbd2cSJim Jagielski  .size  osl_incrementInterlockedCountV9,.-osl_incrementInterlockedCountV9
238*b1cdbd2cSJim Jagielski 
239*b1cdbd2cSJim Jagielski 
240*b1cdbd2cSJim Jagielski .section   ".text"
241*b1cdbd2cSJim Jagielski #if defined(__sparcv8plus) || defined(__sparcv9) || defined(__sparc_v9__)
242*b1cdbd2cSJim Jagielski #define   osl_decrementInterlockedCountV9 osl_decrementInterlockedCount
243*b1cdbd2cSJim Jagielski  .global  osl_decrementInterlockedCountV9
244*b1cdbd2cSJim Jagielski #else
245*b1cdbd2cSJim Jagielski  .local   osl_decrementInterlockedCountV9
246*b1cdbd2cSJim Jagielski #endif
247*b1cdbd2cSJim Jagielski  .align   8
248*b1cdbd2cSJim Jagielski 
249*b1cdbd2cSJim Jagielski osl_decrementInterlockedCountV9:
250*b1cdbd2cSJim Jagielski 
251*b1cdbd2cSJim Jagielski 1:      ld      [%o0], %o1
252*b1cdbd2cSJim Jagielski         sub     %o1, 1, %o2
253*b1cdbd2cSJim Jagielski !       allow linux to build for v8
254*b1cdbd2cSJim Jagielski         .word 0xD5E21009
255*b1cdbd2cSJim Jagielski !       cas     [%o0], %o1, %o2
256*b1cdbd2cSJim Jagielski         cmp     %o1, %o2
257*b1cdbd2cSJim Jagielski         bne     1b
258*b1cdbd2cSJim Jagielski         nop                         ! delay slot
259*b1cdbd2cSJim Jagielski         retl
260*b1cdbd2cSJim Jagielski         sub     %o2, 1, %o0         ! delay slot
261*b1cdbd2cSJim Jagielski 
262*b1cdbd2cSJim Jagielski  .type  osl_decrementInterlockedCountV9,#function
263*b1cdbd2cSJim Jagielski  .size  osl_decrementInterlockedCountV9,.-osl_decrementInterlockedCountV9
264