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