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