4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 #ifndef _THR_INLINES_H
28 #define _THR_INLINES_H
30 #include <sys/ccompile.h>
35 * ON-usable GCC 4.x emits register pseudo-ops declaring %g7 as ignored, rather
36 * than scratch, GCC 3 does the reverse. All uses, both ones it generated
37 * (_curthread) and ones it didn't (__curthread) must agree.
40 #define SPARC_REG_SPEC "#ignore"
42 #define SPARC_REG_SPEC "#scratch"
45 extern __GNU_INLINE ulwp_t
*
50 __asm__
__volatile__("movq %%fs:0, %0" : "=r" (__value
));
53 __asm__
__volatile__("movl %%gs:0, %0" : "=r" (__value
));
54 #elif defined(__sparc)
55 register ulwp_t
*__value
__asm__("g7");
62 extern __GNU_INLINE ulwp_t
*
71 #elif defined(__sparcv9)
72 ".register %%g7, " SPARC_REG_SPEC
"\n\t"
73 "ldx [%%g7 + 80], %0\n\t"
74 #elif defined(__sparc)
75 ".register %%g7, " SPARC_REG_SPEC
"\n\t"
76 "ld [%%g7 + 80], %0\n\t"
84 extern __GNU_INLINE greg_t
88 register greg_t __value
__asm__("rsp");
90 register greg_t __value
__asm__("esp");
91 #elif defined(__sparc)
92 register greg_t __value
__asm__("sp");
99 extern __GNU_INLINE hrtime_t
100 gethrtime(void) /* note: caller-saved registers are trashed */
104 __asm__
__volatile__(
108 : : "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "cc");
109 #elif defined(__i386)
111 __asm__
__volatile__(
116 #elif defined(__sparcv9)
117 register hrtime_t __value
__asm__("o0");
118 __asm__
__volatile__(
120 "sllx %%o0, 32, %0\n\t"
123 : : "o1", "o2", "o3", "o4", "o5", "cc");
124 #elif defined(__sparc)
125 register hrtime_t __value
__asm__("o0");
126 __asm__
__volatile__(
129 : : "o2", "o3", "o4", "o5", "cc");
136 extern __GNU_INLINE
int
137 set_lock_byte(volatile uint8_t *__lockp
)
141 __asm__
__volatile__(
144 : "+d" (__value
), "+m" (*__lockp
));
145 #elif defined(__sparc)
146 __asm__
__volatile__(
149 : "=r" (__value
), "+m" (*__lockp
));
156 extern __GNU_INLINE
uint32_t
157 atomic_swap_32(volatile uint32_t *__memory
, uint32_t __value
)
160 __asm__
__volatile__(
162 : "+q" (__value
), "+m" (*__memory
));
164 #elif defined(__sparc)
165 uint32_t __tmp1
, __tmp2
;
166 __asm__
__volatile__(
170 "cas [%3], %0, %1\n\t"
172 "bne,a,pn %%icc, 1b\n\t"
174 : "=&r" (__tmp1
), "=&r" (__tmp2
), "=m" (*__memory
)
175 : "r" (__memory
), "r" (__value
)
183 extern __GNU_INLINE
uint32_t
184 atomic_cas_32(volatile uint32_t *__memory
, uint32_t __cmp
, uint32_t __newvalue
)
188 __asm__
__volatile__(
189 "lock; cmpxchgl %3, %0"
190 : "=m" (*__memory
), "=a" (__oldvalue
)
191 : "a" (__cmp
), "r" (__newvalue
));
192 #elif defined(__sparc)
193 __asm__
__volatile__(
195 : "=m" (*__memory
), "=&r" (__oldvalue
)
196 : "r" (__memory
), "r" (__cmp
), "1" (__newvalue
));
203 extern __GNU_INLINE
void
204 atomic_inc_32(volatile uint32_t *__memory
)
207 __asm__
__volatile__(
210 #elif defined(__sparc)
211 uint32_t __tmp1
, __tmp2
;
212 __asm__
__volatile__(
216 "cas [%3], %0, %1\n\t"
218 "bne,a,pn %%icc, 1b\n\t"
220 : "=&r" (__tmp1
), "=&r" (__tmp2
), "=m" (*__memory
)
228 extern __GNU_INLINE
void
229 atomic_dec_32(volatile uint32_t *__memory
)
232 __asm__
__volatile__(
235 #elif defined(__sparc)
236 uint32_t __tmp1
, __tmp2
;
237 __asm__
__volatile__(
241 "cas [%3], %0, %1\n\t"
243 "bne,a,pn %%icc, 1b\n\t"
245 : "=&r" (__tmp1
), "=&r" (__tmp2
), "=m" (*__memory
)
253 extern __GNU_INLINE
void
254 atomic_and_32(volatile uint32_t *__memory
, uint32_t __bits
)
257 __asm__
__volatile__(
261 #elif defined(__sparc)
262 uint32_t __tmp1
, __tmp2
;
263 __asm__
__volatile__(
267 "cas [%3], %0, %1\n\t"
269 "bne,a,pn %%icc, 1b\n\t"
271 : "=&r" (__tmp1
), "=&r" (__tmp2
), "=m" (*__memory
)
272 : "r" (__memory
), "r" (__bits
)
279 extern __GNU_INLINE
void
280 atomic_or_32(volatile uint32_t *__memory
, uint32_t __bits
)
283 __asm__
__volatile__(
287 #elif defined(__sparc)
288 uint32_t __tmp1
, __tmp2
;
289 __asm__
__volatile__(
293 "cas [%3], %0, %1\n\t"
295 "bne,a,pn %%icc, 1b\n\t"
297 : "=&r" (__tmp1
), "=&r" (__tmp2
), "=m" (*__memory
)
298 : "r" (__memory
), "r" (__bits
)
305 #if defined(__sparc) /* only needed on sparc */
307 extern __GNU_INLINE ulong_t
310 register ulong_t __value
__asm__("i7");
314 extern __GNU_INLINE ulong_t
317 register ulong_t __value
__asm__("fp");
323 #if defined(__x86) /* only needed on x86 */
325 extern __GNU_INLINE
void
328 __asm__
__volatile__("rep; nop");
333 #endif /* _THR_INLINES_H */