xref: /illumos-gate/usr/src/lib/libc/inc/thr_inlines.h (revision 0ec57554)
1*0ec57554Sraf /*
2*0ec57554Sraf  * CDDL HEADER START
3*0ec57554Sraf  *
4*0ec57554Sraf  * The contents of this file are subject to the terms of the
5*0ec57554Sraf  * Common Development and Distribution License (the "License").
6*0ec57554Sraf  * You may not use this file except in compliance with the License.
7*0ec57554Sraf  *
8*0ec57554Sraf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*0ec57554Sraf  * or http://www.opensolaris.org/os/licensing.
10*0ec57554Sraf  * See the License for the specific language governing permissions
11*0ec57554Sraf  * and limitations under the License.
12*0ec57554Sraf  *
13*0ec57554Sraf  * When distributing Covered Code, include this CDDL HEADER in each
14*0ec57554Sraf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*0ec57554Sraf  * If applicable, add the following below this CDDL HEADER, with the
16*0ec57554Sraf  * fields enclosed by brackets "[]" replaced with your own identifying
17*0ec57554Sraf  * information: Portions Copyright [yyyy] [name of copyright owner]
18*0ec57554Sraf  *
19*0ec57554Sraf  * CDDL HEADER END
20*0ec57554Sraf  */
21*0ec57554Sraf 
22*0ec57554Sraf /*
23*0ec57554Sraf  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0ec57554Sraf  * Use is subject to license terms.
25*0ec57554Sraf  */
26*0ec57554Sraf 
27*0ec57554Sraf #ifndef _THR_INLINES_H
28*0ec57554Sraf #define	_THR_INLINES_H
29*0ec57554Sraf 
30*0ec57554Sraf #pragma ident	"%Z%%M%	%I%	%E% SMI"
31*0ec57554Sraf 
32*0ec57554Sraf #if !defined(__lint) && defined(__GNUC__)
33*0ec57554Sraf 
34*0ec57554Sraf /* inlines for gcc */
35*0ec57554Sraf 
36*0ec57554Sraf extern __inline__ ulwp_t *
37*0ec57554Sraf _curthread(void)
38*0ec57554Sraf {
39*0ec57554Sraf #if defined(__amd64)
40*0ec57554Sraf 	ulwp_t *__value;
41*0ec57554Sraf 	__asm__ __volatile__("movq %%fs:0, %0" : "=r" (__value));
42*0ec57554Sraf #elif defined(__i386)
43*0ec57554Sraf 	ulwp_t *__value;
44*0ec57554Sraf 	__asm__ __volatile__("movl %%gs:0, %0" : "=r" (__value));
45*0ec57554Sraf #elif defined(__sparc)
46*0ec57554Sraf 	register ulwp_t *__value __asm__("g7");
47*0ec57554Sraf #else
48*0ec57554Sraf #error	"port me"
49*0ec57554Sraf #endif
50*0ec57554Sraf 	return (__value);
51*0ec57554Sraf }
52*0ec57554Sraf 
53*0ec57554Sraf extern __inline__ ulwp_t *
54*0ec57554Sraf __curthread(void)
55*0ec57554Sraf {
56*0ec57554Sraf 	ulwp_t *__value;
57*0ec57554Sraf 	__asm__ __volatile__(
58*0ec57554Sraf #if defined(__amd64)
59*0ec57554Sraf 		"xorq %0, %0\n\t"
60*0ec57554Sraf 		"mov %%fs, %0\n\t"
61*0ec57554Sraf 		"andq %0, %0\n\t"
62*0ec57554Sraf 		"je 1f\n\t"
63*0ec57554Sraf 		"movq %%fs:0, %0\n\t"
64*0ec57554Sraf #elif defined(__i386)
65*0ec57554Sraf 		"xorl %0, %0\n\t"
66*0ec57554Sraf 		"mov %%gs, %0\n\t"
67*0ec57554Sraf 		"andl %0, %0\n\t"
68*0ec57554Sraf 		"je 1f\n\t"
69*0ec57554Sraf 		"movl %%gs:0, %0\n\t"
70*0ec57554Sraf #elif defined(__sparcv9)
71*0ec57554Sraf 		".register %%g7, #scratch\n\t"
72*0ec57554Sraf 		"tst %%g7\n\t"
73*0ec57554Sraf 		"be,a,pn %%xcc, 1f\n\t"
74*0ec57554Sraf 		"  mov %%g0, %0\n\t"
75*0ec57554Sraf 		"ldx [%%g7 + 80], %0\n\t"
76*0ec57554Sraf #elif defined(__sparc)
77*0ec57554Sraf 		".register %%g7, #scratch\n\t"
78*0ec57554Sraf 		"tst %%g7\n\t"
79*0ec57554Sraf 		"be,a 1f\n\t"
80*0ec57554Sraf 		"  mov %%g0, %0\n\t"
81*0ec57554Sraf 		"ld [%%g7 + 80], %0\n\t"
82*0ec57554Sraf #else
83*0ec57554Sraf #error	"port me"
84*0ec57554Sraf #endif
85*0ec57554Sraf 		"1:"
86*0ec57554Sraf 		: "=r" (__value)
87*0ec57554Sraf 		: : "cc");
88*0ec57554Sraf 	return (__value);
89*0ec57554Sraf }
90*0ec57554Sraf 
91*0ec57554Sraf extern __inline__ greg_t
92*0ec57554Sraf stkptr(void)
93*0ec57554Sraf {
94*0ec57554Sraf #if defined(__amd64)
95*0ec57554Sraf 	register greg_t __value __asm__("rsp");
96*0ec57554Sraf #elif defined(__i386)
97*0ec57554Sraf 	register greg_t __value __asm__("esp");
98*0ec57554Sraf #elif defined(__sparc)
99*0ec57554Sraf 	register greg_t __value __asm__("sp");
100*0ec57554Sraf #else
101*0ec57554Sraf #error	"port me"
102*0ec57554Sraf #endif
103*0ec57554Sraf 	return (__value);
104*0ec57554Sraf }
105*0ec57554Sraf 
106*0ec57554Sraf extern __inline__ hrtime_t
107*0ec57554Sraf gethrtime(void)		/* note: caller-saved registers are trashed */
108*0ec57554Sraf {
109*0ec57554Sraf #if defined(__amd64)
110*0ec57554Sraf 	hrtime_t __value;
111*0ec57554Sraf 	__asm__ __volatile__(
112*0ec57554Sraf 		"movl $3, %%eax\n\t"
113*0ec57554Sraf 		"int $0xd2"
114*0ec57554Sraf 		: "=a" (__value)
115*0ec57554Sraf 		: : "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "cc");
116*0ec57554Sraf #elif defined(__i386)
117*0ec57554Sraf 	hrtime_t __value;
118*0ec57554Sraf 	__asm__ __volatile__(
119*0ec57554Sraf 		"movl $3, %%eax\n\t"
120*0ec57554Sraf 		"int $0xd2"
121*0ec57554Sraf 		: "=A" (__value)
122*0ec57554Sraf 		: : "ecx", "cc");
123*0ec57554Sraf #elif defined(__sparcv9)
124*0ec57554Sraf 	register hrtime_t __value __asm__("o0");
125*0ec57554Sraf 	__asm__ __volatile__(
126*0ec57554Sraf 		"ta 0x24\n\t"
127*0ec57554Sraf 		"sllx %%o0, 32, %0\n\t"
128*0ec57554Sraf 		"or %%o1, %0, %0"
129*0ec57554Sraf 		: "=r" (__value)
130*0ec57554Sraf 		: : "o1", "o2", "o3", "o4", "o5", "cc");
131*0ec57554Sraf #elif defined(__sparc)
132*0ec57554Sraf 	register hrtime_t __value __asm__("o0");
133*0ec57554Sraf 	__asm__ __volatile__(
134*0ec57554Sraf 		"ta 0x24"
135*0ec57554Sraf 		: "=r" (__value)
136*0ec57554Sraf 		: : "o2", "o3", "o4", "o5", "cc");
137*0ec57554Sraf #else
138*0ec57554Sraf #error	"port me"
139*0ec57554Sraf #endif
140*0ec57554Sraf 	return (__value);
141*0ec57554Sraf }
142*0ec57554Sraf 
143*0ec57554Sraf extern __inline__ int
144*0ec57554Sraf set_lock_byte(volatile uint8_t *__lockp)
145*0ec57554Sraf {
146*0ec57554Sraf 	int __value;
147*0ec57554Sraf #if defined(__x86)
148*0ec57554Sraf 	__asm__ __volatile__(
149*0ec57554Sraf 		"movl $1, %0\n\t"
150*0ec57554Sraf 		"xchgb %%dl, %1"
151*0ec57554Sraf 		: "+d" (__value), "+m" (*__lockp));
152*0ec57554Sraf #elif defined(__sparc)
153*0ec57554Sraf 	__asm__ __volatile__(
154*0ec57554Sraf 		"ldstub %1, %0\n\t"
155*0ec57554Sraf 		"membar #LoadLoad"
156*0ec57554Sraf 		: "=r" (__value), "+m" (*__lockp));
157*0ec57554Sraf #else
158*0ec57554Sraf #error	"port me"
159*0ec57554Sraf #endif
160*0ec57554Sraf 	return (__value);
161*0ec57554Sraf }
162*0ec57554Sraf 
163*0ec57554Sraf extern __inline__ uint32_t
164*0ec57554Sraf swap32(volatile uint32_t *__memory, uint32_t __value)
165*0ec57554Sraf {
166*0ec57554Sraf #if defined(__x86)
167*0ec57554Sraf 	__asm__ __volatile__(
168*0ec57554Sraf 		"xchgl %0, %1"
169*0ec57554Sraf 		: "+q" (__value), "+m" (*__memory));
170*0ec57554Sraf 	return (__value);
171*0ec57554Sraf #elif defined(__sparc)
172*0ec57554Sraf 	uint32_t __tmp1, __tmp2;
173*0ec57554Sraf 	__asm__ __volatile__(
174*0ec57554Sraf 		"ld [%3], %0\n\t"
175*0ec57554Sraf 		"1:\n\t"
176*0ec57554Sraf 		"mov %4, %1\n\t"
177*0ec57554Sraf 		"cas [%3], %0, %1\n\t"
178*0ec57554Sraf 		"cmp %0, %1\n\t"
179*0ec57554Sraf 		"bne,a,pn %%icc, 1b\n\t"
180*0ec57554Sraf 		"  mov %1, %0"
181*0ec57554Sraf 		: "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory)
182*0ec57554Sraf 		: "r" (__memory), "r" (__value)
183*0ec57554Sraf 		: "cc");
184*0ec57554Sraf 	return (__tmp2);
185*0ec57554Sraf #else
186*0ec57554Sraf #error	"port me"
187*0ec57554Sraf #endif
188*0ec57554Sraf }
189*0ec57554Sraf 
190*0ec57554Sraf extern __inline__ uint32_t
191*0ec57554Sraf cas32(volatile uint32_t *__memory, uint32_t __cmp, uint32_t __newvalue)
192*0ec57554Sraf {
193*0ec57554Sraf 	uint32_t __oldvalue;
194*0ec57554Sraf #if defined(__x86)
195*0ec57554Sraf 	__asm__ __volatile__(
196*0ec57554Sraf 		"lock; cmpxchgl %3, %0"
197*0ec57554Sraf 		: "=m" (*__memory), "=a" (__oldvalue)
198*0ec57554Sraf 		: "a" (__cmp), "r" (__newvalue));
199*0ec57554Sraf #elif defined(__sparc)
200*0ec57554Sraf 	__asm__ __volatile__(
201*0ec57554Sraf 		"cas [%2], %3, %1"
202*0ec57554Sraf 		: "=m" (*__memory),  "+r" (__oldvalue)
203*0ec57554Sraf 		: "r" (__memory), "r" (__cmp), "1" (__newvalue));
204*0ec57554Sraf #else
205*0ec57554Sraf #error	"port me"
206*0ec57554Sraf #endif
207*0ec57554Sraf 	return (__oldvalue);
208*0ec57554Sraf }
209*0ec57554Sraf 
210*0ec57554Sraf extern __inline__ void
211*0ec57554Sraf incr32(volatile uint32_t *__memory)
212*0ec57554Sraf {
213*0ec57554Sraf #if defined(__x86)
214*0ec57554Sraf 	__asm__ __volatile__(
215*0ec57554Sraf 		"lock; incl %0"
216*0ec57554Sraf 		: "+m" (*__memory));
217*0ec57554Sraf #elif defined(__sparc)
218*0ec57554Sraf 	uint32_t __tmp1, __tmp2;
219*0ec57554Sraf 	__asm__ __volatile__(
220*0ec57554Sraf 		"ld [%3], %0\n\t"
221*0ec57554Sraf 		"1:\n\t"
222*0ec57554Sraf 		"add %0, 1, %1\n\t"
223*0ec57554Sraf 		"cas [%3], %0, %1\n\t"
224*0ec57554Sraf 		"cmp %0, %1\n\t"
225*0ec57554Sraf 		"bne,a,pn %%icc, 1b\n\t"
226*0ec57554Sraf 		"  mov %1, %0"
227*0ec57554Sraf 		: "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory)
228*0ec57554Sraf 		: "r" (__memory)
229*0ec57554Sraf 		: "cc");
230*0ec57554Sraf #else
231*0ec57554Sraf #error	"port me"
232*0ec57554Sraf #endif
233*0ec57554Sraf }
234*0ec57554Sraf 
235*0ec57554Sraf extern __inline__ void
236*0ec57554Sraf decr32(volatile uint32_t *__memory)
237*0ec57554Sraf {
238*0ec57554Sraf #if defined(__x86)
239*0ec57554Sraf 	__asm__ __volatile__(
240*0ec57554Sraf 		"lock; decl %0"
241*0ec57554Sraf 		: "+m" (*__memory));
242*0ec57554Sraf #elif defined(__sparc)
243*0ec57554Sraf 	uint32_t __tmp1, __tmp2;
244*0ec57554Sraf 	__asm__ __volatile__(
245*0ec57554Sraf 		"ld [%3], %0\n\t"
246*0ec57554Sraf 		"1:\n\t"
247*0ec57554Sraf 		"sub %0, 1, %1\n\t"
248*0ec57554Sraf 		"cas [%3], %0, %1\n\t"
249*0ec57554Sraf 		"cmp %0, %1\n\t"
250*0ec57554Sraf 		"bne,a,pn %%icc, 1b\n\t"
251*0ec57554Sraf 		"  mov %1, %0"
252*0ec57554Sraf 		: "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory)
253*0ec57554Sraf 		: "r" (__memory)
254*0ec57554Sraf 		: "cc");
255*0ec57554Sraf #else
256*0ec57554Sraf #error	"port me"
257*0ec57554Sraf #endif
258*0ec57554Sraf }
259*0ec57554Sraf 
260*0ec57554Sraf #if defined(__sparc)	/* only needed on sparc */
261*0ec57554Sraf 
262*0ec57554Sraf extern __inline__ ulong_t
263*0ec57554Sraf caller(void)
264*0ec57554Sraf {
265*0ec57554Sraf 	register ulong_t __value __asm__("i7");
266*0ec57554Sraf 	return (__value);
267*0ec57554Sraf }
268*0ec57554Sraf 
269*0ec57554Sraf extern __inline__ ulong_t
270*0ec57554Sraf getfp(void)
271*0ec57554Sraf {
272*0ec57554Sraf 	register ulong_t __value __asm__("fp");
273*0ec57554Sraf 	return (__value);
274*0ec57554Sraf }
275*0ec57554Sraf 
276*0ec57554Sraf #endif	/* __sparc */
277*0ec57554Sraf 
278*0ec57554Sraf #if defined(__x86)	/* only needed on x86 */
279*0ec57554Sraf 
280*0ec57554Sraf extern __inline__ void
281*0ec57554Sraf ht_pause(void)
282*0ec57554Sraf {
283*0ec57554Sraf 	__asm__ __volatile__("rep; nop");
284*0ec57554Sraf }
285*0ec57554Sraf 
286*0ec57554Sraf #endif	/* __x86 */
287*0ec57554Sraf 
288*0ec57554Sraf #endif	/* !__lint && __GNUC__ */
289*0ec57554Sraf 
290*0ec57554Sraf #endif	/* _THR_INLINES_H */
291