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 2007 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 "movq %%fs:0, %0\n\t" 60 #elif defined(__i386) 61 "movl %%gs:0, %0\n\t" 62 #elif defined(__sparcv9) 63 ".register %%g7, #scratch\n\t" 64 "ldx [%%g7 + 80], %0\n\t" 65 #elif defined(__sparc) 66 ".register %%g7, #scratch\n\t" 67 "ld [%%g7 + 80], %0\n\t" 68 #else 69 #error "port me" 70 #endif 71 "1:" 72 : "=r" (__value) 73 : : "cc"); 74 return (__value); 75 } 76 77 extern __inline__ greg_t 78 stkptr(void) 79 { 80 #if defined(__amd64) 81 register greg_t __value __asm__("rsp"); 82 #elif defined(__i386) 83 register greg_t __value __asm__("esp"); 84 #elif defined(__sparc) 85 register greg_t __value __asm__("sp"); 86 #else 87 #error "port me" 88 #endif 89 return (__value); 90 } 91 92 extern __inline__ hrtime_t 93 gethrtime(void) /* note: caller-saved registers are trashed */ 94 { 95 #if defined(__amd64) 96 hrtime_t __value; 97 __asm__ __volatile__( 98 "movl $3, %%eax\n\t" 99 "int $0xd2" 100 : "=a" (__value) 101 : : "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11", "cc"); 102 #elif defined(__i386) 103 hrtime_t __value; 104 __asm__ __volatile__( 105 "movl $3, %%eax\n\t" 106 "int $0xd2" 107 : "=A" (__value) 108 : : "ecx", "cc"); 109 #elif defined(__sparcv9) 110 register hrtime_t __value __asm__("o0"); 111 __asm__ __volatile__( 112 "ta 0x24\n\t" 113 "sllx %%o0, 32, %0\n\t" 114 "or %%o1, %0, %0" 115 : "=r" (__value) 116 : : "o1", "o2", "o3", "o4", "o5", "cc"); 117 #elif defined(__sparc) 118 register hrtime_t __value __asm__("o0"); 119 __asm__ __volatile__( 120 "ta 0x24" 121 : "=r" (__value) 122 : : "o2", "o3", "o4", "o5", "cc"); 123 #else 124 #error "port me" 125 #endif 126 return (__value); 127 } 128 129 extern __inline__ int 130 set_lock_byte(volatile uint8_t *__lockp) 131 { 132 int __value; 133 #if defined(__x86) 134 __asm__ __volatile__( 135 "movl $1, %0\n\t" 136 "xchgb %%dl, %1" 137 : "+d" (__value), "+m" (*__lockp)); 138 #elif defined(__sparc) 139 __asm__ __volatile__( 140 "ldstub %1, %0\n\t" 141 "membar #LoadLoad" 142 : "=r" (__value), "+m" (*__lockp)); 143 #else 144 #error "port me" 145 #endif 146 return (__value); 147 } 148 149 extern __inline__ uint32_t 150 swap32(volatile uint32_t *__memory, uint32_t __value) 151 { 152 #if defined(__x86) 153 __asm__ __volatile__( 154 "xchgl %0, %1" 155 : "+q" (__value), "+m" (*__memory)); 156 return (__value); 157 #elif defined(__sparc) 158 uint32_t __tmp1, __tmp2; 159 __asm__ __volatile__( 160 "ld [%3], %0\n\t" 161 "1:\n\t" 162 "mov %4, %1\n\t" 163 "cas [%3], %0, %1\n\t" 164 "cmp %0, %1\n\t" 165 "bne,a,pn %%icc, 1b\n\t" 166 " mov %1, %0" 167 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory) 168 : "r" (__memory), "r" (__value) 169 : "cc"); 170 return (__tmp2); 171 #else 172 #error "port me" 173 #endif 174 } 175 176 extern __inline__ uint32_t 177 cas32(volatile uint32_t *__memory, uint32_t __cmp, uint32_t __newvalue) 178 { 179 uint32_t __oldvalue; 180 #if defined(__x86) 181 __asm__ __volatile__( 182 "lock; cmpxchgl %3, %0" 183 : "=m" (*__memory), "=a" (__oldvalue) 184 : "a" (__cmp), "r" (__newvalue)); 185 #elif defined(__sparc) 186 __asm__ __volatile__( 187 "cas [%2], %3, %1" 188 : "=m" (*__memory), "+r" (__oldvalue) 189 : "r" (__memory), "r" (__cmp), "1" (__newvalue)); 190 #else 191 #error "port me" 192 #endif 193 return (__oldvalue); 194 } 195 196 extern __inline__ void 197 incr32(volatile uint32_t *__memory) 198 { 199 #if defined(__x86) 200 __asm__ __volatile__( 201 "lock; incl %0" 202 : "+m" (*__memory)); 203 #elif defined(__sparc) 204 uint32_t __tmp1, __tmp2; 205 __asm__ __volatile__( 206 "ld [%3], %0\n\t" 207 "1:\n\t" 208 "add %0, 1, %1\n\t" 209 "cas [%3], %0, %1\n\t" 210 "cmp %0, %1\n\t" 211 "bne,a,pn %%icc, 1b\n\t" 212 " mov %1, %0" 213 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory) 214 : "r" (__memory) 215 : "cc"); 216 #else 217 #error "port me" 218 #endif 219 } 220 221 extern __inline__ void 222 decr32(volatile uint32_t *__memory) 223 { 224 #if defined(__x86) 225 __asm__ __volatile__( 226 "lock; decl %0" 227 : "+m" (*__memory)); 228 #elif defined(__sparc) 229 uint32_t __tmp1, __tmp2; 230 __asm__ __volatile__( 231 "ld [%3], %0\n\t" 232 "1:\n\t" 233 "sub %0, 1, %1\n\t" 234 "cas [%3], %0, %1\n\t" 235 "cmp %0, %1\n\t" 236 "bne,a,pn %%icc, 1b\n\t" 237 " mov %1, %0" 238 : "=&r" (__tmp1), "=&r" (__tmp2), "=m" (*__memory) 239 : "r" (__memory) 240 : "cc"); 241 #else 242 #error "port me" 243 #endif 244 } 245 246 #if defined(__sparc) /* only needed on sparc */ 247 248 extern __inline__ ulong_t 249 caller(void) 250 { 251 register ulong_t __value __asm__("i7"); 252 return (__value); 253 } 254 255 extern __inline__ ulong_t 256 getfp(void) 257 { 258 register ulong_t __value __asm__("fp"); 259 return (__value); 260 } 261 262 #endif /* __sparc */ 263 264 #if defined(__x86) /* only needed on x86 */ 265 266 extern __inline__ void 267 ht_pause(void) 268 { 269 __asm__ __volatile__("rep; nop"); 270 } 271 272 #endif /* __x86 */ 273 274 #endif /* !__lint && __GNUC__ */ 275 276 #endif /* _THR_INLINES_H */ 277