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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#ifndef _MACH_I386_SDT_ISA_H 28#define _MACH_I386_SDT_ISA_H 29 30/* 31 * Only define when testing. This makes the calls into actual calls to 32 * test functions. 33 */ 34/* #define DTRACE_CALL_TEST */ 35 36#define DTRACE_STRINGIFY(s) #s 37#define DTRACE_TOSTRING(s) DTRACE_STRINGIFY(s) 38#if defined(KERNEL) 39/* 40 * For the kernel, set an explicit global label so the symbol can be located 41 */ 42#ifdef __x86_64__ 43#define DTRACE_LAB(p, n) \ 44 "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n) 45 46#define DTRACE_LABEL(p, n) \ 47 ".section __DATA, __data\n\t" \ 48 ".globl " DTRACE_LAB(p, n) "\n\t" \ 49 DTRACE_LAB(p, n) ":" ".quad 1f""\n\t" \ 50 ".text" "\n\t" \ 51 "1:" 52#else 53#define DTRACE_LAB(p, n) \ 54 "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n) 55 56#define DTRACE_LABEL(p, n) \ 57 ".section __DATA, __data\n\t" \ 58 ".globl " DTRACE_LAB(p, n) "\n\t" \ 59 DTRACE_LAB(p, n) ":" ".long 1f""\n\t" \ 60 ".text" "\n\t" \ 61 "1:" 62#endif 63#else /* !KERNEL */ 64#define DTRACE_LABEL(p, n) \ 65 "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n) ":" "\n\t" 66#endif /* !KERNEL */ 67 68#ifdef DTRACE_CALL_TEST 69 70#define DTRACE_CALL(p,n) \ 71 DTRACE_LABEL(p,n) \ 72 DTRACE_CALL_INSN(p,n) 73 74#else 75 76#define DTRACE_CALL(p,n) \ 77 DTRACE_LABEL(p,n) \ 78 DTRACE_NOPS 79 80#endif 81 82#ifdef __x86_64__ 83 84#define DTRACE_NOPS \ 85 "nop" "\n\t" \ 86 "nop" "\n\t" \ 87 "nop" "\n\t" 88 89#define DTRACE_CALL_INSN(p,n) \ 90 "call _dtracetest" DTRACE_STRINGIFY(_##p##_##n) "\n\t" 91 92#define ARG1_EXTENT 1 93#define ARGS2_EXTENT 2 94#define ARGS3_EXTENT 3 95#define ARGS4_EXTENT 4 96#define ARGS5_EXTENT 5 97#define ARGS6_EXTENT 6 98#define ARGS7_EXTENT 7 99#define ARGS8_EXTENT 8 100#define ARGS9_EXTENT 9 101#define ARGS10_EXTENT 10 102 103#define DTRACE_CALL0ARGS(provider, name) \ 104 asm volatile ( \ 105 DTRACE_CALL(provider, name) \ 106 : \ 107 : \ 108 ); 109 110#define DTRACE_CALL1ARG(provider, name) \ 111 asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ 112 DTRACE_CALL(provider, name) \ 113 : \ 114 : "r" (__dtrace_args) \ 115 : "memory", "rdi" \ 116 ); 117 118#define DTRACE_CALL2ARGS(provider, name) \ 119 asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ 120 "movq\t0x8(%0),%%rsi" "\n\t" \ 121 DTRACE_CALL(provider, name) \ 122 : \ 123 : "r" (__dtrace_args) \ 124 : "memory", "rdi", "rsi" \ 125 ); 126 127#define DTRACE_CALL3ARGS(provider, name) \ 128 asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ 129 "movq\t0x8(%0),%%rsi" "\n\t" \ 130 "movq\t0x10(%0),%%rdx" "\n\t" \ 131 DTRACE_CALL(provider, name) \ 132 : \ 133 : "r" (__dtrace_args) \ 134 : "memory", "rdi", "rsi", "rdx" \ 135 ); 136 137#define DTRACE_CALL4ARGS(provider, name) \ 138 asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ 139 "movq\t0x8(%0),%%rsi" "\n\t" \ 140 "movq\t0x10(%0),%%rdx" "\n\t" \ 141 "movq\t0x18(%0),%%rcx" "\n\t" \ 142 DTRACE_CALL(provider, name) \ 143 : \ 144 : "r" (__dtrace_args) \ 145 : "memory", "rdi", "rsi", "rdx", "rcx" \ 146 ); 147 148#define DTRACE_CALL5ARGS(provider, name) \ 149 asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ 150 "movq\t0x8(%0),%%rsi" "\n\t" \ 151 "movq\t0x10(%0),%%rdx" "\n\t" \ 152 "movq\t0x18(%0),%%rcx" "\n\t" \ 153 "movq\t0x20(%0),%%r8" "\n\t" \ 154 DTRACE_CALL(provider, name) \ 155 : \ 156 : "r" (__dtrace_args) \ 157 : "memory", "rdi", "rsi", "rdx", "rcx", "r8" \ 158 ); 159 160#define DTRACE_CALL6ARGS(provider, name) \ 161 asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ 162 "movq\t0x8(%0),%%rsi" "\n\t" \ 163 "movq\t0x10(%0),%%rdx" "\n\t" \ 164 "movq\t0x18(%0),%%rcx" "\n\t" \ 165 "movq\t0x20(%0),%%r8" "\n\t" \ 166 "movq\t0x28(%0),%%r9" "\n\t" \ 167 DTRACE_CALL(provider, name) \ 168 : \ 169 : "r" (__dtrace_args) \ 170 : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9" \ 171 ); 172 173#define DTRACE_CALL7ARGS(provider, name) \ 174 asm volatile ("subq\t$0x8,%%rsp" "\n\t" \ 175 "movq\t0x0(%0),%%rdi" "\n\t" \ 176 "movq\t0x8(%0),%%rsi" "\n\t" \ 177 "movq\t0x10(%0),%%rdx" "\n\t" \ 178 "movq\t0x18(%0),%%rcx" "\n\t" \ 179 "movq\t0x20(%0),%%r8" "\n\t" \ 180 "movq\t0x28(%0),%%r9" "\n\t" \ 181 "movq\t0x30(%0),%%rax" "\n\t" \ 182 "movq\t%%rax,0x0(%%rsp)" "\n\t" \ 183 DTRACE_CALL(provider, name) \ 184 "addq\t$0x8,%%rsp" "\n\t" \ 185 : \ 186 : "r" (__dtrace_args) \ 187 : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "rax" \ 188 ); 189 190#endif // __x86_64__ 191 192#ifdef __i386__ 193 194#define DTRACE_NOPS \ 195 "nop" "\n\t" \ 196 "leal 0(%%esi), %%esi" "\n\t" 197 198#define DTRACE_CALL_INSN(p,n) \ 199 "call _dtracetest" DTRACE_STRINGIFY(_##p##_##n) "\n\t" 200 201#define ARG1_EXTENT 1 202#define ARGS2_EXTENT 2 203#define ARGS3_EXTENT 4 204#define ARGS4_EXTENT 4 205#define ARGS5_EXTENT 8 206#define ARGS6_EXTENT 8 207#define ARGS7_EXTENT 8 208#define ARGS8_EXTENT 8 209#define ARGS9_EXTENT 12 210#define ARGS10_EXTENT 12 211 212/* 213 * Because this code is used in the kernel, we must not touch any floating point 214 * or specialized registers. This leaves the following registers: 215 * 216 * eax ; volatile, safe to use 217 * ebx ; PIC register, gcc error when used 218 * ecx ; volatile, safe to use 219 * edx ; volatile, safe to use 220 * esi ; non-volatile, otherwise safe to use 221 * edi ; non-volatile, otherwise safe to use 222 * 223 * Using any of the non volatile register causes a spill to stack which is almost 224 * certainly a net performance loss. Also, note that the array ref (__dtrace_args) 225 * consumes one free register. If all three of the volatile regs are used for load/store, 226 * the compiler will spill a register to hold the array ref. 227 * 228 * The end result is that we only pipeline two loads/stores at a time. Blech. 229 */ 230 231#define DTRACE_CALL0ARGS(provider, name) \ 232 asm volatile ( \ 233 DTRACE_CALL(provider, name) \ 234 "# eat trailing nl +tabfrom DTRACE_CALL" \ 235 : \ 236 : \ 237 ); 238 239#define DTRACE_CALL1ARG(provider, name) \ 240 asm volatile ("subl\t$0x10,%%esp" "\n\t" \ 241 "movl\t0x0(%0),%%eax" "\n\t" \ 242 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 243 DTRACE_CALL(provider, name) \ 244 "addl\t$0x10,%%esp" \ 245 : \ 246 : "r" (__dtrace_args) \ 247 : "memory", "eax" \ 248 ); 249 250#define DTRACE_CALL2ARGS(provider, name) \ 251 asm volatile ("subl\t$0x10,%%esp" "\n\t" \ 252 "movl\t0x0(%0),%%eax" "\n\t" \ 253 "movl\t0x4(%0),%%edx" "\n\t" \ 254 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 255 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 256 DTRACE_CALL(provider, name) \ 257 "addl\t$0x10,%%esp" \ 258 : \ 259 : "r" (__dtrace_args) \ 260 : "memory", "eax", "edx" \ 261 ); 262 263#define DTRACE_CALL3ARGS(provider, name) \ 264 asm volatile ("subl\t$0x10,%%esp" "\n\t" \ 265 "movl\t0x0(%0),%%eax" "\n\t" \ 266 "movl\t0x4(%0),%%edx" "\n\t" \ 267 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 268 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 269 "movl\t0x8(%0),%%eax" "\n\t" \ 270 "movl\t%%eax,0x8(%%esp)" "\n\t" \ 271 DTRACE_CALL(provider, name) \ 272 "addl\t$0x10,%%esp" \ 273 : \ 274 : "r" (__dtrace_args) \ 275 : "memory", "eax", "edx" \ 276 ); 277 278#define DTRACE_CALL4ARGS(provider, name) \ 279 asm volatile ("subl\t$0x10,%%esp" "\n\t" \ 280 "movl\t0x0(%0),%%eax" "\n\t" \ 281 "movl\t0x4(%0),%%edx" "\n\t" \ 282 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 283 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 284 "movl\t0x8(%0),%%eax" "\n\t" \ 285 "movl\t0xC(%0),%%edx" "\n\t" \ 286 "movl\t%%eax,0x8(%%esp)" "\n\t" \ 287 "movl\t%%edx,0xC(%%esp)" "\n\t" \ 288 DTRACE_CALL(provider, name) \ 289 "addl\t$0x10,%%esp" \ 290 : \ 291 : "r" (__dtrace_args) \ 292 : "memory", "eax", "edx" \ 293 ); 294 295#define DTRACE_CALL5ARGS(provider, name) \ 296 asm volatile ("subl\t$0x20,%%esp" "\n\t" \ 297 "movl\t0x0(%0),%%eax" "\n\t" \ 298 "movl\t0x4(%0),%%edx" "\n\t" \ 299 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 300 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 301 "movl\t0x8(%0),%%eax" "\n\t" \ 302 "movl\t0xC(%0),%%edx" "\n\t" \ 303 "movl\t%%eax,0x8(%%esp)" "\n\t" \ 304 "movl\t%%edx,0xC(%%esp)" "\n\t" \ 305 "movl\t0x10(%0),%%eax" "\n\t" \ 306 "movl\t%%eax,0x10(%%esp)" "\n\t" \ 307 DTRACE_CALL(provider, name) \ 308 "addl\t$0x20,%%esp" \ 309 : \ 310 : "r" (__dtrace_args) \ 311 : "memory", "eax", "edx" \ 312 ); 313 314#define DTRACE_CALL6ARGS(provider, name) \ 315 asm volatile ("subl\t$0x20,%%esp" "\n\t" \ 316 "movl\t0x0(%0),%%eax" "\n\t" \ 317 "movl\t0x4(%0),%%edx" "\n\t" \ 318 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 319 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 320 "movl\t0x8(%0),%%eax" "\n\t" \ 321 "movl\t0xC(%0),%%edx" "\n\t" \ 322 "movl\t%%eax,0x8(%%esp)" "\n\t" \ 323 "movl\t%%edx,0xC(%%esp)" "\n\t" \ 324 "movl\t0x10(%0),%%eax" "\n\t" \ 325 "movl\t0x14(%0),%%edx" "\n\t" \ 326 "movl\t%%eax,0x10(%%esp)" "\n\t" \ 327 "movl\t%%edx,0x14(%%esp)" "\n\t" \ 328 DTRACE_CALL(provider, name) \ 329 "addl\t$0x20,%%esp" \ 330 : \ 331 : "r" (__dtrace_args) \ 332 : "memory", "eax", "edx" \ 333 ); 334 335#define DTRACE_CALL7ARGS(provider, name) \ 336 asm volatile ("subl\t$0x20,%%esp" "\n\t" \ 337 "movl\t0x0(%0),%%eax" "\n\t" \ 338 "movl\t0x4(%0),%%edx" "\n\t" \ 339 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 340 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 341 "movl\t0x8(%0),%%eax" "\n\t" \ 342 "movl\t0xC(%0),%%edx" "\n\t" \ 343 "movl\t%%eax,0x8(%%esp)" "\n\t" \ 344 "movl\t%%edx,0xC(%%esp)" "\n\t" \ 345 "movl\t0x10(%0),%%eax" "\n\t" \ 346 "movl\t0x14(%0),%%edx" "\n\t" \ 347 "movl\t%%eax,0x10(%%esp)" "\n\t" \ 348 "movl\t%%edx,0x14(%%esp)" "\n\t" \ 349 "movl\t0x18(%0),%%eax" "\n\t" \ 350 "movl\t%%eax,0x18(%%esp)" "\n\t" \ 351 DTRACE_CALL(provider, name) \ 352 "addl\t$0x20,%%esp" \ 353 : \ 354 : "r" (__dtrace_args) \ 355 : "memory", "eax", "edx" \ 356 ); 357 358#define DTRACE_CALL8ARGS(provider, name) \ 359 asm volatile ("subl\t$0x20,%%esp" "\n\t" \ 360 "movl\t0x0(%0),%%eax" "\n\t" \ 361 "movl\t0x4(%0),%%edx" "\n\t" \ 362 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 363 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 364 "movl\t0x8(%0),%%eax" "\n\t" \ 365 "movl\t0xC(%0),%%edx" "\n\t" \ 366 "movl\t%%eax,0x8(%%esp)" "\n\t" \ 367 "movl\t%%edx,0xC(%%esp)" "\n\t" \ 368 "movl\t0x10(%0),%%eax" "\n\t" \ 369 "movl\t0x14(%0),%%edx" "\n\t" \ 370 "movl\t%%eax,0x10(%%esp)" "\n\t" \ 371 "movl\t%%edx,0x14(%%esp)" "\n\t" \ 372 "movl\t0x18(%0),%%eax" "\n\t" \ 373 "movl\t0x1C(%0),%%edx" "\n\t" \ 374 "movl\t%%eax,0x18(%%esp)" "\n\t" \ 375 "movl\t%%edx,0x1C(%%esp)" "\n\t" \ 376 DTRACE_CALL(provider, name) \ 377 "addl\t$0x20,%%esp" \ 378 : \ 379 : "r" (__dtrace_args) \ 380 : "memory", "eax", "edx" \ 381 ); 382 383#define DTRACE_CALL9ARGS(provider, name) \ 384 asm volatile ("subl\t$0x30,%%esp" "\n\t" \ 385 "movl\t0x0(%0),%%eax" "\n\t" \ 386 "movl\t0x4(%0),%%edx" "\n\t" \ 387 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 388 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 389 "movl\t0x8(%0),%%eax" "\n\t" \ 390 "movl\t0xC(%0),%%edx" "\n\t" \ 391 "movl\t%%eax,0x8(%%esp)" "\n\t" \ 392 "movl\t%%edx,0xC(%%esp)" "\n\t" \ 393 "movl\t0x10(%0),%%eax" "\n\t" \ 394 "movl\t0x14(%0),%%edx" "\n\t" \ 395 "movl\t%%eax,0x10(%%esp)" "\n\t" \ 396 "movl\t%%edx,0x14(%%esp)" "\n\t" \ 397 "movl\t0x18(%0),%%eax" "\n\t" \ 398 "movl\t0x1C(%0),%%edx" "\n\t" \ 399 "movl\t%%eax,0x18(%%esp)" "\n\t" \ 400 "movl\t%%edx,0x1C(%%esp)" "\n\t" \ 401 "movl\t0x20(%0),%%eax" "\n\t" \ 402 "movl\t%%eax,0x20(%%esp)" "\n\t" \ 403 DTRACE_CALL(provider, name) \ 404 "addl\t$0x30,%%esp" \ 405 : \ 406 : "r" (__dtrace_args) \ 407 : "memory", "eax", "edx" \ 408 ); 409 410#define DTRACE_CALL10ARGS(provider, name) \ 411 asm volatile ("subl\t$0x30,%%esp" "\n\t" \ 412 "movl\t0x0(%0),%%eax" "\n\t" \ 413 "movl\t0x4(%0),%%edx" "\n\t" \ 414 "movl\t%%eax,0x0(%%esp)" "\n\t" \ 415 "movl\t%%edx,0x4(%%esp)" "\n\t" \ 416 "movl\t0x8(%0),%%eax" "\n\t" \ 417 "movl\t0xC(%0),%%edx" "\n\t" \ 418 "movl\t%%eax,0x8(%%esp)" "\n\t" \ 419 "movl\t%%edx,0xC(%%esp)" "\n\t" \ 420 "movl\t0x10(%0),%%eax" "\n\t" \ 421 "movl\t0x14(%0),%%edx" "\n\t" \ 422 "movl\t%%eax,0x10(%%esp)" "\n\t" \ 423 "movl\t%%edx,0x14(%%esp)" "\n\t" \ 424 "movl\t0x18(%0),%%eax" "\n\t" \ 425 "movl\t0x1C(%0),%%edx" "\n\t" \ 426 "movl\t%%eax,0x18(%%esp)" "\n\t" \ 427 "movl\t%%edx,0x1C(%%esp)" "\n\t" \ 428 "movl\t0x20(%0),%%eax" "\n\t" \ 429 "movl\t0x24(%0),%%edx" "\n\t" \ 430 "movl\t%%eax,0x20(%%esp)" "\n\t" \ 431 "movl\t%%edx,0x24(%%esp)" "\n\t" \ 432 DTRACE_CALL(provider, name) \ 433 "addl\t$0x30,%%esp" \ 434 : \ 435 : "r" (__dtrace_args) \ 436 : "memory", "eax", "edx" \ 437 ); 438 439#endif // __i386__ 440 441#endif /* _MACH_I386_SDT_ISA_H */ 442