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