xref: /onnv-gate/usr/src/lib/libc/inc/thr_inlines.h (revision 4570:f93b74ddbdd5)
11016Sraf /*
21016Sraf  * CDDL HEADER START
31016Sraf  *
41016Sraf  * The contents of this file are subject to the terms of the
51016Sraf  * Common Development and Distribution License (the "License").
61016Sraf  * You may not use this file except in compliance with the License.
71016Sraf  *
81016Sraf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
91016Sraf  * or http://www.opensolaris.org/os/licensing.
101016Sraf  * See the License for the specific language governing permissions
111016Sraf  * and limitations under the License.
121016Sraf  *
131016Sraf  * When distributing Covered Code, include this CDDL HEADER in each
141016Sraf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
151016Sraf  * If applicable, add the following below this CDDL HEADER, with the
161016Sraf  * fields enclosed by brackets "[]" replaced with your own identifying
171016Sraf  * information: Portions Copyright [yyyy] [name of copyright owner]
181016Sraf  *
191016Sraf  * CDDL HEADER END
201016Sraf  */
211016Sraf 
221016Sraf /*
233446Smrj  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
241016Sraf  * Use is subject to license terms.
251016Sraf  */
261016Sraf 
271016Sraf #ifndef _THR_INLINES_H
281016Sraf #define	_THR_INLINES_H
291016Sraf 
301016Sraf #pragma ident	"%Z%%M%	%I%	%E% SMI"
311016Sraf 
321016Sraf #if !defined(__lint) && defined(__GNUC__)
331016Sraf 
341016Sraf /* inlines for gcc */
351016Sraf 
361016Sraf extern __inline__ ulwp_t *
_curthread(void)371016Sraf _curthread(void)
381016Sraf {
391016Sraf #if defined(__amd64)
401016Sraf 	ulwp_t *__value;
411016Sraf 	__asm__ __volatile__("movq %%fs:0, %0" : "=r" (__value));
421016Sraf #elif defined(__i386)
431016Sraf 	ulwp_t *__value;
441016Sraf 	__asm__ __volatile__("movl %%gs:0, %0" : "=r" (__value));
451016Sraf #elif defined(__sparc)
461016Sraf 	register ulwp_t *__value __asm__("g7");
471016Sraf #else
481016Sraf #error	"port me"
491016Sraf #endif
501016Sraf 	return (__value);
511016Sraf }
521016Sraf 
531016Sraf extern __inline__ ulwp_t *
__curthread(void)541016Sraf __curthread(void)
551016Sraf {
561016Sraf 	ulwp_t *__value;
571016Sraf 	__asm__ __volatile__(
581016Sraf #if defined(__amd64)
591016Sraf 		"movq %%fs:0, %0\n\t"
601016Sraf #elif defined(__i386)
611016Sraf 		"movl %%gs:0, %0\n\t"
621016Sraf #elif defined(__sparcv9)
631016Sraf 		".register %%g7, #scratch\n\t"
641016Sraf 		"ldx [%%g7 + 80], %0\n\t"
651016Sraf #elif defined(__sparc)
661016Sraf 		".register %%g7, #scratch\n\t"
671016Sraf 		"ld [%%g7 + 80], %0\n\t"
681016Sraf #else
691016Sraf #error	"port me"
701016Sraf #endif
711016Sraf 		"1:"
721016Sraf 		: "=r" (__value)
731016Sraf 		: : "cc");
741016Sraf 	return (__value);
751016Sraf }
761016Sraf 
771016Sraf extern __inline__ greg_t
stkptr(void)781016Sraf stkptr(void)
791016Sraf {
801016Sraf #if defined(__amd64)
811016Sraf 	register greg_t __value __asm__("rsp");
821016Sraf #elif defined(__i386)
831016Sraf 	register greg_t __value __asm__("esp");
841016Sraf #elif defined(__sparc)
851016Sraf 	register greg_t __value __asm__("sp");
861016Sraf #else
871016Sraf #error	"port me"
881016Sraf #endif
891016Sraf 	return (__value);
901016Sraf }
911016Sraf 
921016Sraf extern __inline__ hrtime_t
gethrtime(void)931016Sraf gethrtime(void)		/* note: caller-saved registers are trashed */
941016Sraf {
951016Sraf #if defined(__amd64)
961016Sraf 	hrtime_t __value;
971016Sraf 	__asm__ __volatile__(
981016Sraf 		"movl $3, %%eax\n\t"
991016Sraf 		"int $0xd2"
1001016Sraf 		: "=a" (__value)
1011016Sraf 		: : "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "cc");
1021016Sraf #elif defined(__i386)
1031016Sraf 	hrtime_t __value;
1041016Sraf 	__asm__ __volatile__(
1051016Sraf 		"movl $3, %%eax\n\t"
1061016Sraf 		"int $0xd2"
1071016Sraf 		: "=A" (__value)
1081016Sraf 		: : "ecx", "cc");
1091016Sraf #elif defined(__sparcv9)
1101016Sraf 	register hrtime_t __value __asm__("o0");
1111016Sraf 	__asm__ __volatile__(
1121016Sraf 		"ta 0x24\n\t"
1131016Sraf 		"sllx %%o0, 32, %0\n\t"
1141016Sraf 		"or %%o1, %0, %0"
1151016Sraf 		: "=r" (__value)
1161016Sraf 		: : "o1", "o2", "o3", "o4", "o5", "cc");
1171016Sraf #elif defined(__sparc)
1181016Sraf 	register hrtime_t __value __asm__("o0");
1191016Sraf 	__asm__ __volatile__(
1201016Sraf 		"ta 0x24"
1211016Sraf 		: "=r" (__value)
1221016Sraf 		: : "o2", "o3", "o4", "o5", "cc");
1231016Sraf #else
1241016Sraf #error	"port me"
1251016Sraf #endif
1261016Sraf 	return (__value);
1271016Sraf }
1281016Sraf 
1291016Sraf extern __inline__ int
set_lock_byte(volatile uint8_t * __lockp)1301016Sraf set_lock_byte(volatile uint8_t *__lockp)
1311016Sraf {
1321016Sraf 	int __value;
1331016Sraf #if defined(__x86)
1341016Sraf 	__asm__ __volatile__(
1351016Sraf 		"movl $1, %0\n\t"
1361016Sraf 		"xchgb %%dl, %1"
1371016Sraf 		: "+d" (__value), "+m" (*__lockp));
1381016Sraf #elif defined(__sparc)
1391016Sraf 	__asm__ __volatile__(
1401016Sraf 		"ldstub %1, %0\n\t"
1411016Sraf 		"membar #LoadLoad"
1421016Sraf 		: "=r" (__value), "+m" (*__lockp));
1431016Sraf #else
1441016Sraf #error	"port me"
1451016Sraf #endif
1461016Sraf 	return (__value);
1471016Sraf }
1481016Sraf 
1491016Sraf extern __inline__ uint32_t
atomic_swap_32(volatile uint32_t * __memory,uint32_t __value)150*4570Sraf atomic_swap_32(volatile uint32_t *__memory, uint32_t __value)
1511016Sraf {
1521016Sraf #if defined(__x86)
1531016Sraf 	__asm__ __volatile__(
1541016Sraf 		"xchgl %0, %1"
1551016Sraf 		: "+q" (__value), "+m" (*__memory));
1561016Sraf 	return (__value);
1571016Sraf #elif defined(__sparc)
1581016Sraf 	uint32_t __tmp1, __tmp2;
1591016Sraf 	__asm__ __volatile__(
1601016Sraf 		"ld [%3], %0\n\t"
1611016Sraf 		"1:\n\t"
1621016Sraf 		"mov %4, %1\n\t"
1631016Sraf 		"cas [%3], %0, %1\n\t"
1641016Sraf 		"cmp %0, %1\n\t"
1651016Sraf 		"bne,a,pn %%icc, 1b\n\t"
1661016Sraf 		"  mov %1, %0"
1671016Sraf 		: "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory)
1681016Sraf 		: "r" (__memory), "r" (__value)
1691016Sraf 		: "cc");
1701016Sraf 	return (__tmp2);
1711016Sraf #else
1721016Sraf #error	"port me"
1731016Sraf #endif
1741016Sraf }
1751016Sraf 
1761016Sraf extern __inline__ uint32_t
atomic_cas_32(volatile uint32_t * __memory,uint32_t __cmp,uint32_t __newvalue)177*4570Sraf atomic_cas_32(volatile uint32_t *__memory, uint32_t __cmp, uint32_t __newvalue)
1781016Sraf {
1791016Sraf 	uint32_t __oldvalue;
1801016Sraf #if defined(__x86)
1811016Sraf 	__asm__ __volatile__(
1821016Sraf 		"lock; cmpxchgl %3, %0"
1831016Sraf 		: "=m" (*__memory), "=a" (__oldvalue)
1841016Sraf 		: "a" (__cmp), "r" (__newvalue));
1851016Sraf #elif defined(__sparc)
1861016Sraf 	__asm__ __volatile__(
1871016Sraf 		"cas [%2], %3, %1"
188*4570Sraf 		: "=m" (*__memory), "=&r" (__oldvalue)
1891016Sraf 		: "r" (__memory), "r" (__cmp), "1" (__newvalue));
1901016Sraf #else
1911016Sraf #error	"port me"
1921016Sraf #endif
1931016Sraf 	return (__oldvalue);
1941016Sraf }
1951016Sraf 
1961016Sraf extern __inline__ void
atomic_inc_32(volatile uint32_t * __memory)197*4570Sraf atomic_inc_32(volatile uint32_t *__memory)
1981016Sraf {
1991016Sraf #if defined(__x86)
2001016Sraf 	__asm__ __volatile__(
2011016Sraf 		"lock; incl %0"
2021016Sraf 		: "+m" (*__memory));
2031016Sraf #elif defined(__sparc)
2041016Sraf 	uint32_t __tmp1, __tmp2;
2051016Sraf 	__asm__ __volatile__(
2061016Sraf 		"ld [%3], %0\n\t"
2071016Sraf 		"1:\n\t"
2081016Sraf 		"add %0, 1, %1\n\t"
2091016Sraf 		"cas [%3], %0, %1\n\t"
2101016Sraf 		"cmp %0, %1\n\t"
2111016Sraf 		"bne,a,pn %%icc, 1b\n\t"
2121016Sraf 		"  mov %1, %0"
2131016Sraf 		: "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory)
2141016Sraf 		: "r" (__memory)
2151016Sraf 		: "cc");
2161016Sraf #else
2171016Sraf #error	"port me"
2181016Sraf #endif
2191016Sraf }
2201016Sraf 
2211016Sraf extern __inline__ void
atomic_dec_32(volatile uint32_t * __memory)222*4570Sraf atomic_dec_32(volatile uint32_t *__memory)
2231016Sraf {
2241016Sraf #if defined(__x86)
2251016Sraf 	__asm__ __volatile__(
2261016Sraf 		"lock; decl %0"
2271016Sraf 		: "+m" (*__memory));
2281016Sraf #elif defined(__sparc)
2291016Sraf 	uint32_t __tmp1, __tmp2;
2301016Sraf 	__asm__ __volatile__(
2311016Sraf 		"ld [%3], %0\n\t"
2321016Sraf 		"1:\n\t"
2331016Sraf 		"sub %0, 1, %1\n\t"
2341016Sraf 		"cas [%3], %0, %1\n\t"
2351016Sraf 		"cmp %0, %1\n\t"
2361016Sraf 		"bne,a,pn %%icc, 1b\n\t"
2371016Sraf 		"  mov %1, %0"
2381016Sraf 		: "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory)
2391016Sraf 		: "r" (__memory)
2401016Sraf 		: "cc");
2411016Sraf #else
2421016Sraf #error	"port me"
2431016Sraf #endif
2441016Sraf }
2451016Sraf 
246*4570Sraf extern __inline__ void
atomic_and_32(volatile uint32_t * __memory,uint32_t __bits)247*4570Sraf atomic_and_32(volatile uint32_t *__memory, uint32_t __bits)
248*4570Sraf {
249*4570Sraf #if defined(__x86)
250*4570Sraf 	__asm__ __volatile__(
251*4570Sraf 		"lock; andl %1, %0"
252*4570Sraf 		: "+m" (*__memory)
253*4570Sraf 		: "r" (__bits));
254*4570Sraf #elif defined(__sparc)
255*4570Sraf 	uint32_t __tmp1, __tmp2;
256*4570Sraf 	__asm__ __volatile__(
257*4570Sraf 		"ld [%3], %0\n\t"
258*4570Sraf 		"1:\n\t"
259*4570Sraf 		"and %0, %4, %1\n\t"
260*4570Sraf 		"cas [%3], %0, %1\n\t"
261*4570Sraf 		"cmp %0, %1\n\t"
262*4570Sraf 		"bne,a,pn %%icc, 1b\n\t"
263*4570Sraf 		"  mov %1, %0"
264*4570Sraf 		: "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory)
265*4570Sraf 		: "r" (__memory), "r" (__bits)
266*4570Sraf 		: "cc");
267*4570Sraf #else
268*4570Sraf #error	"port me"
269*4570Sraf #endif
270*4570Sraf }
271*4570Sraf 
272*4570Sraf extern __inline__ void
atomic_or_32(volatile uint32_t * __memory,uint32_t __bits)273*4570Sraf atomic_or_32(volatile uint32_t *__memory, uint32_t __bits)
274*4570Sraf {
275*4570Sraf #if defined(__x86)
276*4570Sraf 	__asm__ __volatile__(
277*4570Sraf 		"lock; orl %1, %0"
278*4570Sraf 		: "+m" (*__memory)
279*4570Sraf 		: "r" (__bits));
280*4570Sraf #elif defined(__sparc)
281*4570Sraf 	uint32_t __tmp1, __tmp2;
282*4570Sraf 	__asm__ __volatile__(
283*4570Sraf 		"ld [%3], %0\n\t"
284*4570Sraf 		"1:\n\t"
285*4570Sraf 		"or %0, %4, %1\n\t"
286*4570Sraf 		"cas [%3], %0, %1\n\t"
287*4570Sraf 		"cmp %0, %1\n\t"
288*4570Sraf 		"bne,a,pn %%icc, 1b\n\t"
289*4570Sraf 		"  mov %1, %0"
290*4570Sraf 		: "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory)
291*4570Sraf 		: "r" (__memory), "r" (__bits)
292*4570Sraf 		: "cc");
293*4570Sraf #else
294*4570Sraf #error	"port me"
295*4570Sraf #endif
296*4570Sraf }
297*4570Sraf 
2981016Sraf #if defined(__sparc)	/* only needed on sparc */
2991016Sraf 
3001016Sraf extern __inline__ ulong_t
caller(void)3011016Sraf caller(void)
3021016Sraf {
3031016Sraf 	register ulong_t __value __asm__("i7");
3041016Sraf 	return (__value);
3051016Sraf }
3061016Sraf 
3071016Sraf extern __inline__ ulong_t
getfp(void)3081016Sraf getfp(void)
3091016Sraf {
3101016Sraf 	register ulong_t __value __asm__("fp");
3111016Sraf 	return (__value);
3121016Sraf }
3131016Sraf 
3141016Sraf #endif	/* __sparc */
3151016Sraf 
3161016Sraf #if defined(__x86)	/* only needed on x86 */
3171016Sraf 
3181016Sraf extern __inline__ void
ht_pause(void)3191016Sraf ht_pause(void)
3201016Sraf {
3211016Sraf 	__asm__ __volatile__("rep; nop");
3221016Sraf }
3231016Sraf 
3241016Sraf #endif	/* __x86 */
3251016Sraf 
3261016Sraf #endif	/* !__lint && __GNUC__ */
3271016Sraf 
3281016Sraf #endif	/* _THR_INLINES_H */
329