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  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 #if defined(lint) || defined(__lint)
  29 #include <sys/dtrace_impl.h>
  30 #else
  31 #include <sys/asm_linkage.h>
  32 #include <sys/privregs.h>
  33 #include <sys/fsr.h>
  34 #include <sys/asi.h>
  35 #include "assym.h"
  36 #endif
  37 
  38 #if defined(lint) || defined(__lint)
  39 
  40 int
  41 dtrace_getipl(void)
  42 { return (0); }
  43 
  44 #else   /* lint */
  45 
  46         ENTRY_NP(dtrace_getipl)
  47         retl
  48         rdpr    %pil, %o0
  49         SET_SIZE(dtrace_getipl)
  50 
  51 #endif  /* lint */
  52 
  53 #if defined(lint) || defined(__lint)
  54 
  55 uint_t
  56 dtrace_getotherwin(void)
  57 { return (0); }
  58 
  59 #else   /* lint */
  60 
  61         ENTRY_NP(dtrace_getotherwin)
  62         retl
  63         rdpr    %otherwin, %o0
  64         SET_SIZE(dtrace_getotherwin)
  65 
  66 #endif  /* lint */
  67 
  68 #if defined(lint) || defined(__lint)
  69 
  70 uint_t
  71 dtrace_getfprs(void)
  72 { return (0); }
  73 
  74 #else   /* lint */
  75 
  76         ENTRY_NP(dtrace_getfprs)
  77         retl
  78         rd      %fprs, %o0
  79         SET_SIZE(dtrace_getfprs)
  80 
  81 #endif  /* lint */
  82 
  83 #if defined(lint) || defined(__lint)
  84 
  85 /*ARGSUSED*/
  86 void
  87 dtrace_getfsr(uint64_t *val)
  88 {}
  89 
  90 #else   /* lint */
  91 
  92         ENTRY_NP(dtrace_getfsr)
  93         rdpr    %pstate, %o1
  94         andcc   %o1, PSTATE_PEF, %g0
  95         bz,pn   %xcc, 1f
  96         nop
  97         rd      %fprs, %o1
  98         andcc   %o1, FPRS_FEF, %g0
  99         bz,pn   %xcc, 1f
 100         nop
 101         retl
 102         stx     %fsr, [%o0]
 103 1:
 104         retl
 105         stx     %g0, [%o0]
 106         SET_SIZE(dtrace_getfsr)
 107 
 108 #endif  /* lint */
 109 
 110 #if defined(lint) || defined(__lint)
 111 
 112 greg_t
 113 dtrace_getfp(void)
 114 { return (0); }
 115 
 116 #else   /* lint */
 117 
 118         ENTRY_NP(dtrace_getfp)
 119         retl
 120         mov     %fp, %o0
 121         SET_SIZE(dtrace_getfp)
 122 
 123 #endif  /* lint */
 124 
 125 #if defined(lint) || defined(__lint)
 126 
 127 void
 128 dtrace_flush_user_windows(void)
 129 {}
 130 
 131 #else
 132 
 133         ENTRY_NP(dtrace_flush_user_windows)
 134         rdpr    %otherwin, %g1
 135         brz     %g1, 3f
 136         clr     %g2
 137 1:
 138         save    %sp, -WINDOWSIZE, %sp
 139         rdpr    %otherwin, %g1
 140         brnz    %g1, 1b
 141         add     %g2, 1, %g2
 142 2:
 143         sub     %g2, 1, %g2             ! restore back to orig window
 144         brnz    %g2, 2b
 145         restore
 146 3:
 147         retl
 148         nop
 149         SET_SIZE(dtrace_flush_user_windows)
 150 
 151 #endif  /* lint */
 152 
 153 #if defined(lint) || defined(__lint)
 154 
 155 uint32_t
 156 dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
 157 {
 158         uint32_t old;
 159 
 160         if ((old = *target) == cmp)
 161                 *target = new;
 162         return (old);
 163 }
 164 
 165 void *
 166 dtrace_casptr(void *target, void *cmp, void *new)
 167 {
 168         void *old;
 169 
 170         if ((old = *(void **)target) == cmp)
 171                 *(void **)target = new;
 172         return (old);
 173 }
 174 
 175 #else   /* lint */
 176 
 177         ENTRY(dtrace_cas32)
 178         cas     [%o0], %o1, %o2
 179         retl
 180         mov     %o2, %o0
 181         SET_SIZE(dtrace_cas32)
 182 
 183         ENTRY(dtrace_casptr)
 184         casn    [%o0], %o1, %o2
 185         retl
 186         mov     %o2, %o0
 187         SET_SIZE(dtrace_casptr)
 188 
 189 #endif  /* lint */
 190 
 191 #if defined(lint)
 192 
 193 /*ARGSUSED*/
 194 uintptr_t
 195 dtrace_caller(int aframes)
 196 {
 197         return (0);
 198 }
 199 
 200 #else   /* lint */
 201 
 202         ENTRY(dtrace_caller)
 203         sethi   %hi(nwin_minus_one), %g4
 204         ld      [%g4 + %lo(nwin_minus_one)], %g4
 205         rdpr    %canrestore, %g2
 206         cmp     %g2, %o0
 207         bl      %icc, 1f
 208         rdpr    %cwp, %g1
 209         sub     %g1, %o0, %g3
 210         brgez,a,pt %g3, 0f
 211         wrpr    %g3, %cwp
 212 
 213         !
 214         ! CWP minus the number of frames is negative; we must perform the
 215         ! arithmetic modulo MAXWIN.
 216         !
 217         add     %g4, %g3, %g3
 218         inc     %g3
 219         wrpr    %g3, %cwp
 220 0:
 221         mov     %i7, %g4
 222         wrpr    %g1, %cwp
 223         retl
 224         mov     %g4, %o0
 225 1:
 226         !
 227         ! The caller has been flushed to the stack.  This is unlikely
 228         ! (interrupts are disabled in dtrace_probe()), but possible (the 
 229         ! interrupt inducing the spill may have been taken before the
 230         ! call to dtrace_probe()).
 231         !
 232         retl
 233         mov     -1, %o0
 234         SET_SIZE(dtrace_caller)
 235 
 236 #endif
 237 
 238 #if defined(lint)
 239 
 240 /*ARGSUSED*/
 241 int
 242 dtrace_fish(int aframes, int reg, uintptr_t *regval)
 243 {
 244         return (0);
 245 }
 246 
 247 #else   /* lint */
 248 
 249         ENTRY(dtrace_fish)
 250 
 251         rd      %pc, %g5
 252         ba      0f
 253         add     %g5, 12, %g5
 254         mov     %l0, %g4
 255         mov     %l1, %g4
 256         mov     %l2, %g4
 257         mov     %l3, %g4
 258         mov     %l4, %g4
 259         mov     %l5, %g4
 260         mov     %l6, %g4
 261         mov     %l7, %g4
 262         mov     %i0, %g4
 263         mov     %i1, %g4
 264         mov     %i2, %g4
 265         mov     %i3, %g4
 266         mov     %i4, %g4
 267         mov     %i5, %g4
 268         mov     %i6, %g4
 269         mov     %i7, %g4
 270 0:
 271         sub     %o1, 16, %o1            ! Can only retrieve %l's and %i's
 272         sll     %o1, 2, %o1             ! Multiply by instruction size
 273         add     %g5, %o1, %g5           ! %g5 now contains the instr. to pick
 274 
 275         sethi   %hi(nwin_minus_one), %g4
 276         ld      [%g4 + %lo(nwin_minus_one)], %g4
 277 
 278         !
 279         ! First we need to see if the frame that we're fishing in is still 
 280         ! contained in the register windows.
 281         !
 282         rdpr    %canrestore, %g2
 283         cmp     %g2, %o0
 284         bl      %icc, 2f
 285         rdpr    %cwp, %g1
 286         sub     %g1, %o0, %g3
 287         brgez,a,pt %g3, 0f
 288         wrpr    %g3, %cwp
 289 
 290         !
 291         ! CWP minus the number of frames is negative; we must perform the
 292         ! arithmetic modulo MAXWIN.
 293         !
 294         add     %g4, %g3, %g3
 295         inc     %g3
 296         wrpr    %g3, %cwp
 297 0:
 298         jmp     %g5
 299         ba      1f
 300 1:
 301         wrpr    %g1, %cwp
 302         stn     %g4, [%o2]
 303         retl
 304         clr     %o0                     ! Success; return 0.
 305 2:
 306         !
 307         ! The frame that we're looking for has been flushed to the stack; the
 308         ! caller will be forced to 
 309         !
 310         retl
 311         add     %g2, 1, %o0             ! Failure; return deepest frame + 1
 312         SET_SIZE(dtrace_fish)
 313 
 314 #endif
 315 
 316 #if defined(lint)
 317 
 318 /*ARGSUSED*/
 319 void
 320 dtrace_copyin(uintptr_t uaddr, uintptr_t kaddr, size_t size,
 321     volatile uint16_t *flags)
 322 {}
 323 
 324 #else
 325 
 326         ENTRY(dtrace_copyin)
 327         tst     %o2
 328         bz      2f
 329         clr     %g1
 330         lduba   [%o0 + %g1]ASI_USER, %g2
 331 0:
 332         ! check for an error if the count is 4k-aligned
 333         andcc   %g1, 0xfff, %g0
 334         bnz,pt  %icc, 1f
 335         stub    %g2, [%o1 + %g1]
 336         lduh    [%o3], %g3
 337         andcc   %g3, CPU_DTRACE_BADADDR, %g0
 338         bnz,pn  %icc, 2f
 339         nop
 340 1:
 341         inc     %g1
 342         cmp     %g1, %o2
 343         bl,a    0b
 344         lduba   [%o0 + %g1]ASI_USER, %g2
 345 2:
 346         retl
 347         nop
 348 
 349         SET_SIZE(dtrace_copyin)
 350 
 351 #endif
 352 
 353 #if defined(lint)
 354 
 355 /*ARGSUSED*/
 356 void
 357 dtrace_copyinstr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
 358     volatile  uint16_t *flags)
 359 {}
 360 
 361 #else
 362 
 363         ENTRY(dtrace_copyinstr)
 364         tst     %o2
 365         bz      2f
 366         clr     %g1
 367         lduba   [%o0 + %g1]ASI_USER, %g2
 368 0:
 369         stub    %g2, [%o1 + %g1]                ! Store byte
 370 
 371         ! check for an error if the count is 4k-aligned
 372         andcc   %g1, 0xfff, %g0
 373         bnz,pt  %icc, 1f
 374         inc     %g1
 375         lduh    [%o3], %g3
 376         andcc   %g3, CPU_DTRACE_BADADDR, %g0
 377         bnz,pn  %icc, 2f
 378         nop
 379 1:
 380         cmp     %g2, 0                          ! Was that '\0'?
 381         be      2f                              ! If so, we're done
 382         cmp     %g1, %o2                        ! Compare to limit
 383         bl,a    0b                              ! If less, take another lap
 384         lduba   [%o0 + %g1]ASI_USER, %g2        !   delay: load user byte
 385 2:
 386         retl
 387         nop
 388 
 389         SET_SIZE(dtrace_copyinstr)
 390 
 391 #endif
 392 
 393 #if defined(lint)
 394 
 395 /*ARGSUSED*/
 396 void
 397 dtrace_copyout(uintptr_t kaddr, uintptr_t uaddr, size_t size,
 398     volatile  uint16_t *flags)
 399 {}
 400 
 401 #else
 402 
 403         ENTRY(dtrace_copyout)
 404         tst     %o2
 405         bz      2f
 406         clr     %g1
 407         ldub    [%o0 + %g1], %g2
 408 0:
 409         ! check for an error if the count is 4k-aligned
 410         andcc   %g1, 0xfff, %g0
 411         bnz,pt  %icc, 1f
 412         stba    %g2, [%o1 + %g1]ASI_USER
 413         lduh    [%o3], %g3
 414         andcc   %g3, CPU_DTRACE_BADADDR, %g0
 415         bnz,pn  %icc, 2f
 416         nop
 417 1:
 418         inc     %g1
 419         cmp     %g1, %o2
 420         bl,a    0b
 421         ldub    [%o0 + %g1], %g2
 422 2:
 423         retl
 424         nop
 425         SET_SIZE(dtrace_copyout)
 426 
 427 #endif
 428         
 429 #if defined(lint)
 430 
 431 /*ARGSUSED*/
 432 void
 433 dtrace_copyoutstr(uintptr_t kaddr, uintptr_t uaddr, size_t size,
 434     volatile  uint16_t *flags)
 435 {}
 436 
 437 #else
 438 
 439         ENTRY(dtrace_copyoutstr)
 440         tst     %o2
 441         bz      2f
 442         clr     %g1
 443         ldub    [%o0 + %g1], %g2
 444 0:
 445         stba    %g2, [%o1 + %g1]ASI_USER
 446 
 447         ! check for an error if the count is 4k-aligned
 448         andcc   %g1, 0xfff, %g0
 449         bnz,pt  %icc, 1f
 450         inc     %g1
 451         lduh    [%o3], %g3
 452         andcc   %g3, CPU_DTRACE_BADADDR, %g0
 453         bnz,pn  %icc, 2f
 454         nop
 455 1:
 456         cmp     %g2, 0
 457         be      2f
 458         cmp     %g1, %o2
 459         bl,a    0b
 460         ldub    [%o0 + %g1], %g2
 461 2:
 462         retl
 463         nop
 464         SET_SIZE(dtrace_copyoutstr)
 465 
 466 #endif
 467 
 468 #if defined(lint)
 469 
 470 /*ARGSUSED*/
 471 uintptr_t
 472 dtrace_fulword(void *addr)
 473 { return (0); }
 474 
 475 #else
 476 
 477         ENTRY(dtrace_fulword)
 478         clr     %o1
 479         ldna    [%o0]ASI_USER, %o1
 480         retl
 481         mov     %o1, %o0
 482         SET_SIZE(dtrace_fulword)
 483 
 484 #endif
 485 
 486 #if defined(lint)
 487 
 488 /*ARGSUSED*/
 489 uint8_t
 490 dtrace_fuword8(void *addr)
 491 { return (0); }
 492 
 493 #else
 494 
 495         ENTRY(dtrace_fuword8)
 496         clr     %o1
 497         lduba   [%o0]ASI_USER, %o1
 498         retl
 499         mov     %o1, %o0
 500         SET_SIZE(dtrace_fuword8)
 501 
 502 #endif
 503 
 504 #if defined(lint)
 505 
 506 /*ARGSUSED*/
 507 uint16_t
 508 dtrace_fuword16(void *addr)
 509 { return (0); }
 510 
 511 #else
 512 
 513         ENTRY(dtrace_fuword16)
 514         clr     %o1
 515         lduha   [%o0]ASI_USER, %o1
 516         retl
 517         mov     %o1, %o0
 518         SET_SIZE(dtrace_fuword16)
 519 
 520 #endif
 521 
 522 #if defined(lint)
 523 
 524 /*ARGSUSED*/
 525 uint32_t
 526 dtrace_fuword32(void *addr)
 527 { return (0); }
 528 
 529 #else
 530 
 531         ENTRY(dtrace_fuword32)
 532         clr     %o1
 533         lda     [%o0]ASI_USER, %o1
 534         retl
 535         mov     %o1, %o0
 536         SET_SIZE(dtrace_fuword32)
 537 
 538 #endif
 539 
 540 #if defined(lint)
 541 
 542 /*ARGSUSED*/
 543 uint64_t
 544 dtrace_fuword64(void *addr)
 545 { return (0); }
 546 
 547 #else
 548 
 549         ENTRY(dtrace_fuword64)
 550         clr     %o1
 551         ldxa    [%o0]ASI_USER, %o1
 552         retl
 553         mov     %o1, %o0
 554         SET_SIZE(dtrace_fuword64)
 555 
 556 #endif
 557 
 558 #if defined(lint)
 559 
 560 /*ARGSUSED*/
 561 int
 562 dtrace_getupcstack_top(uint64_t *pcstack, int pcstack_limit, uintptr_t *sp)
 563 { return (0); }
 564 
 565 #else
 566 
 567         /*
 568          * %g1  pcstack
 569          * %g2  current window
 570          * %g3  maxwin (nwindows - 1)
 571          * %g4  saved %cwp (so we can get back to the original window)
 572          * %g5  iteration count
 573          * %g6  saved %fp
 574          * 
 575          * %o0  pcstack / return value (iteration count)
 576          * %o1  pcstack_limit
 577          * %o2  last_fp
 578          */
 579 
 580         ENTRY(dtrace_getupcstack_top)
 581         mov     %o0, %g1                ! we need the pcstack pointer while
 582                                         ! we're visiting other windows
 583 
 584         rdpr    %otherwin, %g5          ! compute the number of iterations
 585         cmp     %g5, %o1                ! (windows to observe) by taking the
 586         movg    %icc, %o1, %g5          ! min of %otherwin and pcstack_limit
 587 
 588         brlez,a,pn %g5, 2f              ! return 0 if count <= 0
 589         clr     %o0
 590 
 591         sethi   %hi(nwin_minus_one), %g3 ! hang onto maxwin since we'll need
 592         ld      [%g3 + %lo(nwin_minus_one)], %g3 ! it for our modular arithmetic
 593 
 594         rdpr    %cwp, %g4               ! remember our window so we can return
 595         rdpr    %canrestore, %g2        ! compute the first non-user window
 596         subcc   %g4, %g2, %g2           ! current = %cwp - %canrestore
 597 
 598         bge,pt  %xcc, 1f                ! good to go if current is >= 0
 599         mov     %g5, %o0                ! we need to return the count
 600 
 601         add     %g2, %g3, %g2           ! normalize our current window if it's
 602         add     %g2, 1, %g2             ! less than zero
 603 
 604         ! note that while it's tempting, we can't execute restore to decrement
 605         ! the %cwp by one (mod nwindows) because we're in the user's windows
 606 1:
 607         deccc   %g2                     ! decrement the current window
 608         movl    %xcc, %g3, %g2          ! normalize if it's negative (-1)
 609 
 610         wrpr    %g2, %cwp               ! change windows
 611 
 612         stx     %i7, [%g1]              ! stash the return address in pcstack
 613 
 614         deccc   %g5                     ! decrement the count
 615         bnz,pt  %icc, 1b                ! we iterate until the count reaches 0
 616         add     %g1, 8, %g1             ! increment the pcstack pointer
 617 
 618         mov     %i6, %g6                ! stash the last frame pointer we
 619                                         ! encounter so the caller can
 620                                         ! continue the stack walk in memory
 621 
 622         wrpr    %g4, %cwp               ! change back to the original window
 623 
 624         stn     %g6, [%o2]              ! return the last frame pointer
 625 
 626 2:
 627         retl
 628         nop
 629         SET_SIZE(dtrace_getupcstack_top)
 630 
 631 #endif
 632 
 633 #if defined(lint)
 634 
 635 /*ARGSUSED*/
 636 int
 637 dtrace_getustackdepth_top(uintptr_t *sp)
 638 { return (0); }
 639 
 640 #else
 641 
 642         ENTRY(dtrace_getustackdepth_top)
 643         mov     %o0, %o2
 644         rdpr    %otherwin, %o0
 645 
 646         brlez,a,pn %o0, 2f              ! return 0 if there are no user wins
 647         clr     %o0
 648 
 649         rdpr    %cwp, %g4               ! remember our window so we can return
 650         rdpr    %canrestore, %g2        ! compute the first user window
 651         sub     %g4, %g2, %g2           ! current = %cwp - %canrestore -
 652         subcc   %g2, %o0, %g2           !     %otherwin
 653 
 654         bge,pt  %xcc, 1f                ! normalize the window if necessary
 655         sethi   %hi(nwin_minus_one), %g3
 656         ld      [%g3 + %lo(nwin_minus_one)], %g3
 657         add     %g2, %g3, %g2
 658         add     %g2, 1, %g2
 659 
 660 1:
 661         wrpr    %g2, %cwp               ! change to the first user window
 662         mov     %i6, %g6                ! stash the frame pointer
 663         wrpr    %g4, %cwp               ! change back to the original window
 664 
 665         stn     %g6, [%o2]              ! return the frame pointer
 666 
 667 2:
 668         retl
 669         nop
 670         SET_SIZE(dtrace_getustackdepth_top)
 671 
 672 #endif
 673 
 674 #if defined(lint) || defined(__lint)
 675 
 676 /* ARGSUSED */
 677 ulong_t
 678 dtrace_getreg_win(uint_t reg, uint_t depth)
 679 { return (0); }
 680 
 681 #else   /* lint */
 682 
 683         ENTRY(dtrace_getreg_win)
 684         sub     %o0, 16, %o0
 685         cmp     %o0, 16                 ! %o0 must begin in the range [16..32)
 686         blu,pt  %xcc, 1f
 687         nop
 688         retl
 689         clr     %o0
 690 
 691 1:
 692         set     dtrace_getreg_win_table, %g3
 693         sll     %o0, 2, %o0
 694         add     %g3, %o0, %g3
 695 
 696         rdpr    %canrestore, %o3
 697         rdpr    %cwp, %g2
 698 
 699         ! Set %cwp to be (%cwp - %canrestore - %o1) mod NWINDOWS
 700 
 701         sub     %g2, %o3, %o2           ! %o2 is %cwp - %canrestore
 702         subcc   %o2, %o1, %o4
 703         bge,a,pn %xcc, 2f
 704         wrpr    %o4, %cwp
 705 
 706         sethi   %hi(nwin_minus_one), %o3
 707         ld      [%o3 + %lo(nwin_minus_one)], %o3
 708 
 709         add     %o2, %o3, %o4
 710         wrpr    %o4, %cwp
 711 2:
 712         jmp     %g3
 713         ba      3f
 714 3:
 715         wrpr    %g2, %cwp
 716         retl
 717         mov     %g1, %o0
 718 
 719 dtrace_getreg_win_table:
 720         mov     %l0, %g1
 721         mov     %l1, %g1
 722         mov     %l2, %g1
 723         mov     %l3, %g1
 724         mov     %l4, %g1
 725         mov     %l5, %g1
 726         mov     %l6, %g1
 727         mov     %l7, %g1
 728         mov     %i0, %g1
 729         mov     %i1, %g1
 730         mov     %i2, %g1
 731         mov     %i3, %g1
 732         mov     %i4, %g1
 733         mov     %i5, %g1
 734         mov     %i6, %g1
 735         mov     %i7, %g1
 736         SET_SIZE(dtrace_getreg_win)
 737 
 738 #endif  /* lint */
 739 
 740 #if defined(lint) || defined(__lint)
 741 
 742 /* ARGSUSED */
 743 void
 744 dtrace_putreg_win(uint_t reg, ulong_t value)
 745 {}
 746 
 747 #else   /* lint */
 748 
 749         ENTRY(dtrace_putreg_win)
 750         sub     %o0, 16, %o0
 751         cmp     %o0, 16                 ! %o0 must be in the range [16..32)
 752         blu,pt  %xcc, 1f
 753         nop
 754         retl
 755         nop
 756 
 757 1:
 758         mov     %o1, %g1                ! move the value into a global register
 759 
 760         set     dtrace_putreg_table, %g3
 761         sll     %o0, 2, %o0
 762         add     %g3, %o0, %g3
 763 
 764         rdpr    %canrestore, %o3
 765         rdpr    %cwp, %g2
 766 
 767         ! Set %cwp to be (%cwp - %canrestore - 1) mod NWINDOWS
 768 
 769         sub     %g2, %o3, %o2           ! %o2 is %cwp - %canrestore
 770         subcc   %o2, 1, %o4
 771         bge,a,pn %xcc, 2f
 772         wrpr    %o4, %cwp
 773 
 774         sethi   %hi(nwin_minus_one), %o3
 775         ld      [%o3 + %lo(nwin_minus_one)], %o3
 776         add     %o2, %o3, %o4
 777         wrpr    %o4, %cwp
 778 2:
 779         jmp     %g3
 780         ba      3f
 781 3:
 782         wrpr    %g2, %cwp
 783         retl
 784         nop
 785 
 786 dtrace_putreg_table:
 787         mov     %g1, %l0
 788         mov     %g1, %l1
 789         mov     %g1, %l2
 790         mov     %g1, %l3
 791         mov     %g1, %l4
 792         mov     %g1, %l5
 793         mov     %g1, %l6
 794         mov     %g1, %l7
 795         mov     %g1, %i0
 796         mov     %g1, %i1
 797         mov     %g1, %i2
 798         mov     %g1, %i3
 799         mov     %g1, %i4
 800         mov     %g1, %i5
 801         mov     %g1, %i6
 802         mov     %g1, %i7
 803         SET_SIZE(dtrace_putreg_win)
 804 
 805 #endif  /* lint */
 806 
 807 #if defined(lint) || defined(__lint)
 808 
 809 /*ARGSUSED*/
 810 void
 811 dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which,
 812     int fault, int fltoffs, uintptr_t illval)
 813 {}
 814 
 815 #else   /* lint */
 816 
 817         ENTRY(dtrace_probe_error)
 818         save    %sp, -SA(MINFRAME), %sp
 819         sethi   %hi(dtrace_probeid_error), %l0
 820         ld      [%l0 + %lo(dtrace_probeid_error)], %o0
 821         mov     %i0, %o1
 822         mov     %i1, %o2
 823         mov     %i2, %o3
 824         mov     %i3, %o4
 825         call    dtrace_probe
 826         mov     %i4, %o5
 827         ret
 828         restore
 829         SET_SIZE(dtrace_probe_error)
 830 
 831 #endif