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