17c478bdstevel@tonic-gate/*
27c478bdstevel@tonic-gate * CDDL HEADER START
37c478bdstevel@tonic-gate *
47c478bdstevel@tonic-gate * The contents of this file are subject to the terms of the
52840650sudheer * Common Development and Distribution License (the "License").
62840650sudheer * You may not use this file except in compliance with the License.
77c478bdstevel@tonic-gate *
87c478bdstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bdstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bdstevel@tonic-gate * See the License for the specific language governing permissions
117c478bdstevel@tonic-gate * and limitations under the License.
127c478bdstevel@tonic-gate *
137c478bdstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bdstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bdstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bdstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bdstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bdstevel@tonic-gate *
197c478bdstevel@tonic-gate * CDDL HEADER END
207c478bdstevel@tonic-gate */
217c478bdstevel@tonic-gate/*
222840650sudheer * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
237c478bdstevel@tonic-gate * Use is subject to license terms.
247c478bdstevel@tonic-gate */
257c478bdstevel@tonic-gate
267c478bdstevel@tonic-gate#include <sys/asm_linkage.h>
277c478bdstevel@tonic-gate#include <sys/privregs.h>
287c478bdstevel@tonic-gate#include <sys/fsr.h>
297c478bdstevel@tonic-gate#include <sys/asi.h>
302840650sudheer#include "assym.h"
317c478bdstevel@tonic-gate
327c478bdstevel@tonic-gate	ENTRY_NP(dtrace_getipl)
337c478bdstevel@tonic-gate	retl
347c478bdstevel@tonic-gate	rdpr	%pil, %o0
357c478bdstevel@tonic-gate	SET_SIZE(dtrace_getipl)
367c478bdstevel@tonic-gate
377c478bdstevel@tonic-gate	ENTRY_NP(dtrace_getotherwin)
387c478bdstevel@tonic-gate	retl
397c478bdstevel@tonic-gate	rdpr	%otherwin, %o0
407c478bdstevel@tonic-gate	SET_SIZE(dtrace_getotherwin)
417c478bdstevel@tonic-gate
427c478bdstevel@tonic-gate	ENTRY_NP(dtrace_getfprs)
437c478bdstevel@tonic-gate	retl
447c478bdstevel@tonic-gate	rd	%fprs, %o0
457c478bdstevel@tonic-gate	SET_SIZE(dtrace_getfprs)
467c478bdstevel@tonic-gate
477c478bdstevel@tonic-gate	ENTRY_NP(dtrace_getfsr)
487c478bdstevel@tonic-gate	rdpr	%pstate, %o1
497c478bdstevel@tonic-gate	andcc	%o1, PSTATE_PEF, %g0
507c478bdstevel@tonic-gate	bz,pn	%xcc, 1f
517c478bdstevel@tonic-gate	nop
527c478bdstevel@tonic-gate	rd	%fprs, %o1
537c478bdstevel@tonic-gate	andcc	%o1, FPRS_FEF, %g0
547c478bdstevel@tonic-gate	bz,pn	%xcc, 1f
557c478bdstevel@tonic-gate	nop
567c478bdstevel@tonic-gate	retl
577c478bdstevel@tonic-gate	stx	%fsr, [%o0]
587c478bdstevel@tonic-gate1:
597c478bdstevel@tonic-gate	retl
607c478bdstevel@tonic-gate	stx	%g0, [%o0]
617c478bdstevel@tonic-gate	SET_SIZE(dtrace_getfsr)
627c478bdstevel@tonic-gate
637c478bdstevel@tonic-gate	ENTRY_NP(dtrace_getfp)
647c478bdstevel@tonic-gate	retl
657c478bdstevel@tonic-gate	mov	%fp, %o0
667c478bdstevel@tonic-gate	SET_SIZE(dtrace_getfp)
677c478bdstevel@tonic-gate
687c478bdstevel@tonic-gate	ENTRY_NP(dtrace_flush_user_windows)
697c478bdstevel@tonic-gate	rdpr	%otherwin, %g1
707c478bdstevel@tonic-gate	brz	%g1, 3f
717c478bdstevel@tonic-gate	clr	%g2
727c478bdstevel@tonic-gate1:
737c478bdstevel@tonic-gate	save	%sp, -WINDOWSIZE, %sp
747c478bdstevel@tonic-gate	rdpr	%otherwin, %g1
757c478bdstevel@tonic-gate	brnz	%g1, 1b
767c478bdstevel@tonic-gate	add	%g2, 1, %g2
777c478bdstevel@tonic-gate2:
787c478bdstevel@tonic-gate	sub	%g2, 1, %g2		! restore back to orig window
797c478bdstevel@tonic-gate	brnz	%g2, 2b
807c478bdstevel@tonic-gate	restore
817c478bdstevel@tonic-gate3:
827c478bdstevel@tonic-gate	retl
837c478bdstevel@tonic-gate	nop
847c478bdstevel@tonic-gate	SET_SIZE(dtrace_flush_user_windows)
857c478bdstevel@tonic-gate
867c478bdstevel@tonic-gate	ENTRY(dtrace_cas32)
877c478bdstevel@tonic-gate	cas	[%o0], %o1, %o2
887c478bdstevel@tonic-gate	retl
897c478bdstevel@tonic-gate	mov	%o2, %o0
907c478bdstevel@tonic-gate	SET_SIZE(dtrace_cas32)
917c478bdstevel@tonic-gate
927c478bdstevel@tonic-gate	ENTRY(dtrace_casptr)
937c478bdstevel@tonic-gate	casn	[%o0], %o1, %o2
947c478bdstevel@tonic-gate	retl
957c478bdstevel@tonic-gate	mov	%o2, %o0
967c478bdstevel@tonic-gate	SET_SIZE(dtrace_casptr)
977c478bdstevel@tonic-gate
987c478bdstevel@tonic-gate	ENTRY(dtrace_caller)
997c478bdstevel@tonic-gate	sethi	%hi(nwin_minus_one), %g4
1007c478bdstevel@tonic-gate	ld	[%g4 + %lo(nwin_minus_one)], %g4
1017c478bdstevel@tonic-gate	rdpr	%canrestore, %g2
1027c478bdstevel@tonic-gate	cmp	%g2, %o0
1037c478bdstevel@tonic-gate	bl	%icc, 1f
1047c478bdstevel@tonic-gate	rdpr	%cwp, %g1
1057c478bdstevel@tonic-gate	sub	%g1, %o0, %g3
1067c478bdstevel@tonic-gate	brgez,a,pt %g3, 0f
1077c478bdstevel@tonic-gate	wrpr	%g3, %cwp
1087c478bdstevel@tonic-gate
1097c478bdstevel@tonic-gate	!
1107c478bdstevel@tonic-gate	! CWP minus the number of frames is negative; we must perform the
1117c478bdstevel@tonic-gate	! arithmetic modulo MAXWIN.
1127c478bdstevel@tonic-gate	!
1137c478bdstevel@tonic-gate	add	%g4, %g3, %g3
1147c478bdstevel@tonic-gate	inc	%g3
1157c478bdstevel@tonic-gate	wrpr	%g3, %cwp
1167c478bdstevel@tonic-gate0:
1177c478bdstevel@tonic-gate	mov	%i7, %g4
1187c478bdstevel@tonic-gate	wrpr	%g1, %cwp
1197c478bdstevel@tonic-gate	retl
1207c478bdstevel@tonic-gate	mov	%g4, %o0
1217c478bdstevel@tonic-gate1:
1227c478bdstevel@tonic-gate	!
1237c478bdstevel@tonic-gate	! The caller has been flushed to the stack.  This is unlikely
1247c478bdstevel@tonic-gate	! (interrupts are disabled in dtrace_probe()), but possible (the
1257c478bdstevel@tonic-gate	! interrupt inducing the spill may have been taken before the
1267c478bdstevel@tonic-gate	! call to dtrace_probe()).
1277c478bdstevel@tonic-gate	!
1287c478bdstevel@tonic-gate	retl
1297c478bdstevel@tonic-gate	mov	-1, %o0
1307c478bdstevel@tonic-gate	SET_SIZE(dtrace_caller)
1317c478bdstevel@tonic-gate
1327c478bdstevel@tonic-gate	ENTRY(dtrace_fish)
1337c478bdstevel@tonic-gate
1347c478bdstevel@tonic-gate	rd	%pc, %g5
1357c478bdstevel@tonic-gate	ba	0f
1367c478bdstevel@tonic-gate	add	%g5, 12, %g5
1377c478bdstevel@tonic-gate	mov	%l0, %g4
1387c478bdstevel@tonic-gate	mov	%l1, %g4
1397c478bdstevel@tonic-gate	mov	%l2, %g4
1407c478bdstevel@tonic-gate	mov	%l3, %g4
1417c478bdstevel@tonic-gate	mov	%l4, %g4
1427c478bdstevel@tonic-gate	mov	%l5, %g4
1437c478bdstevel@tonic-gate	mov	%l6, %g4
1447c478bdstevel@tonic-gate	mov	%l7, %g4
1457c478bdstevel@tonic-gate	mov	%i0, %g4
1467c478bdstevel@tonic-gate	mov	%i1, %g4
1477c478bdstevel@tonic-gate	mov	%i2, %g4
1487c478bdstevel@tonic-gate	mov	%i3, %g4
1497c478bdstevel@tonic-gate	mov	%i4, %g4
1507c478bdstevel@tonic-gate	mov	%i5, %g4
1517c478bdstevel@tonic-gate	mov	%i6, %g4
1527c478bdstevel@tonic-gate	mov	%i7, %g4
1537c478bdstevel@tonic-gate0:
1547c478bdstevel@tonic-gate	sub	%o1, 16, %o1		! Can only retrieve %l's and %i's
1557c478bdstevel@tonic-gate	sll	%o1, 2, %o1		! Multiply by instruction size
1567c478bdstevel@tonic-gate	add	%g5, %o1, %g5		! %g5 now contains the instr. to pick
1577c478bdstevel@tonic-gate
1587c478bdstevel@tonic-gate	sethi	%hi(nwin_minus_one), %g4
1597c478bdstevel@tonic-gate	ld	[%g4 + %lo(nwin_minus_one)], %g4
1607c478bdstevel@tonic-gate
1617c478bdstevel@tonic-gate	!
1627c478bdstevel@tonic-gate	! First we need to see if the frame that we're fishing in is still
1637c478bdstevel@tonic-gate	! contained in the register windows.
1647c478bdstevel@tonic-gate	!
1657c478bdstevel@tonic-gate	rdpr	%canrestore, %g2
1667c478bdstevel@tonic-gate	cmp	%g2, %o0
1677c478bdstevel@tonic-gate	bl	%icc, 2f
1687c478bdstevel@tonic-gate	rdpr	%cwp, %g1
1697c478bdstevel@tonic-gate	sub	%g1, %o0, %g3
1707c478bdstevel@tonic-gate	brgez,a,pt %g3, 0f
1717c478bdstevel@tonic-gate	wrpr	%g3, %cwp
1727c478bdstevel@tonic-gate
1737c478bdstevel@tonic-gate	!
1747c478bdstevel@tonic-gate	! CWP minus the number of frames is negative; we must perform the
1757c478bdstevel@tonic-gate	! arithmetic modulo MAXWIN.
1767c478bdstevel@tonic-gate	!
1777c478bdstevel@tonic-gate	add	%g4, %g3, %g3
1787c478bdstevel@tonic-gate	inc	%g3
1797c478bdstevel@tonic-gate	wrpr	%g3, %cwp
1807c478bdstevel@tonic-gate0:
1817c478bdstevel@tonic-gate	jmp	%g5
1827c478bdstevel@tonic-gate	ba	1f
1837c478bdstevel@tonic-gate1:
1847c478bdstevel@tonic-gate	wrpr	%g1, %cwp
1857c478bdstevel@tonic-gate	stn	%g4, [%o2]
1867c478bdstevel@tonic-gate	retl
1877c478bdstevel@tonic-gate	clr	%o0			! Success; return 0.
1887c478bdstevel@tonic-gate2:
1897c478bdstevel@tonic-gate	!
1907c478bdstevel@tonic-gate	! The frame that we're looking for has been flushed to the stack; the
1917c478bdstevel@tonic-gate	! caller will be forced to
1927c478bdstevel@tonic-gate	!
1937c478bdstevel@tonic-gate	retl
1947c478bdstevel@tonic-gate	add	%g2, 1, %o0		! Failure; return deepest frame + 1
1957c478bdstevel@tonic-gate	SET_SIZE(dtrace_fish)
1967c478bdstevel@tonic-gate
1977c478bdstevel@tonic-gate	ENTRY(dtrace_copyin)
1987c478bdstevel@tonic-gate	tst	%o2
1992840650sudheer	bz	2f
2007c478bdstevel@tonic-gate	clr	%g1
2017c478bdstevel@tonic-gate	lduba	[%o0 + %g1]ASI_USER, %g2
2027c478bdstevel@tonic-gate0:
2032840650sudheer	! check for an error if the count is 4k-aligned
2042840650sudheer	andcc	%g1, 0xfff, %g0
2052840650sudheer	bnz,pt	%icc, 1f
2067c478bdstevel@tonic-gate	stub	%g2, [%o1 + %g1]
2072840650sudheer	lduh	[%o3], %g3
2082840650sudheer	andcc	%g3, CPU_DTRACE_BADADDR, %g0
2092840650sudheer	bnz,pn	%icc, 2f
2102840650sudheer	nop
2112840650sudheer1:
2127c478bdstevel@tonic-gate	inc	%g1
2137c478bdstevel@tonic-gate	cmp	%g1, %o2
2147c478bdstevel@tonic-gate	bl,a	0b
2157c478bdstevel@tonic-gate	lduba	[%o0 + %g1]ASI_USER, %g2
2162840650sudheer2:
2177c478bdstevel@tonic-gate	retl
2187c478bdstevel@tonic-gate	nop
2197c478bdstevel@tonic-gate
2207c478bdstevel@tonic-gate	SET_SIZE(dtrace_copyin)
2217c478bdstevel@tonic-gate
2227c478bdstevel@tonic-gate	ENTRY(dtrace_copyinstr)
2237c478bdstevel@tonic-gate	tst	%o2
2242840650sudheer	bz	2f
2257c478bdstevel@tonic-gate	clr	%g1
2267c478bdstevel@tonic-gate	lduba	[%o0 + %g1]ASI_USER, %g2
2277c478bdstevel@tonic-gate0:
2287c478bdstevel@tonic-gate	stub	%g2, [%o1 + %g1]		! Store byte
2292840650sudheer
2302840650sudheer	! check for an error if the count is 4k-aligned
2312840650sudheer	andcc	%g1, 0xfff, %g0
2322840650sudheer	bnz,pt	%icc, 1f
2332840650sudheer	inc	%g1
2342840650sudheer	lduh	[%o3], %g3
2352840650sudheer	andcc	%g3, CPU_DTRACE_BADADDR, %g0
2362840650sudheer	bnz,pn	%icc, 2f
2372840650sudheer	nop
2382840650sudheer1:
2397c478bdstevel@tonic-gate	cmp	%g2, 0				! Was that '\0'?
2402840650sudheer	be	2f				! If so, we're done
2417c478bdstevel@tonic-gate	cmp	%g1, %o2			! Compare to limit
2427c478bdstevel@tonic-gate	bl,a	0b				! If less, take another lap
2437c478bdstevel@tonic-gate	lduba	[%o0 + %g1]ASI_USER, %g2	!   delay: load user byte
2442840650sudheer2:
2457c478bdstevel@tonic-gate	retl
2467c478bdstevel@tonic-gate	nop
2477c478bdstevel@tonic-gate
2487c478bdstevel@tonic-gate	SET_SIZE(dtrace_copyinstr)
2497c478bdstevel@tonic-gate
2507c478bdstevel@tonic-gate	ENTRY(dtrace_copyout)
2517c478bdstevel@tonic-gate	tst	%o2
2522840650sudheer	bz	2f
2537c478bdstevel@tonic-gate	clr	%g1
2547c478bdstevel@tonic-gate	ldub	[%o0 + %g1], %g2
2557c478bdstevel@tonic-gate0:
2562840650sudheer	! check for an error if the count is 4k-aligned
2572840650sudheer	andcc	%g1, 0xfff, %g0
2582840650sudheer	bnz,pt	%icc, 1f
2597c478bdstevel@tonic-gate	stba	%g2, [%o1 + %g1]ASI_USER
2602840650sudheer	lduh	[%o3], %g3
2612840650sudheer	andcc	%g3, CPU_DTRACE_BADADDR, %g0
2622840650sudheer	bnz,pn	%icc, 2f
2632840650sudheer	nop
2642840650sudheer1:
2657c478bdstevel@tonic-gate	inc	%g1
2667c478bdstevel@tonic-gate	cmp	%g1, %o2
2677c478bdstevel@tonic-gate	bl,a	0b
2687c478bdstevel@tonic-gate	ldub	[%o0 + %g1], %g2
2692840650sudheer2:
2707c478bdstevel@tonic-gate	retl
2717c478bdstevel@tonic-gate	nop
2727c478bdstevel@tonic-gate	SET_SIZE(dtrace_copyout)
2737c478bdstevel@tonic-gate
2747c478bdstevel@tonic-gate	ENTRY(dtrace_copyoutstr)
2757c478bdstevel@tonic-gate	tst	%o2
2762840650sudheer	bz	2f
2777c478bdstevel@tonic-gate	clr	%g1
2787c478bdstevel@tonic-gate	ldub	[%o0 + %g1], %g2
2797c478bdstevel@tonic-gate0:
2807c478bdstevel@tonic-gate	stba	%g2, [%o1 + %g1]ASI_USER
2812840650sudheer
2822840650sudheer	! check for an error if the count is 4k-aligned
2832840650sudheer	andcc	%g1, 0xfff, %g0
2842840650sudheer	bnz,pt  %icc, 1f
2857c478bdstevel@tonic-gate	inc	%g1
2862840650sudheer	lduh	[%o3], %g3
2872840650sudheer	andcc	%g3, CPU_DTRACE_BADADDR, %g0
2882840650sudheer	bnz,pn	%icc, 2f
2892840650sudheer	nop
2902840650sudheer1:
2912840650sudheer	cmp	%g2, 0
2922840650sudheer	be	2f
2937c478bdstevel@tonic-gate	cmp	%g1, %o2
2947c478bdstevel@tonic-gate	bl,a	0b
2957c478bdstevel@tonic-gate	ldub	[%o0 + %g1], %g2
2962840650sudheer2:
2977c478bdstevel@tonic-gate	retl
2987c478bdstevel@tonic-gate	nop
2997c478bdstevel@tonic-gate	SET_SIZE(dtrace_copyoutstr)
3007c478bdstevel@tonic-gate
3017c478bdstevel@tonic-gate	ENTRY(dtrace_fulword)
3027c478bdstevel@tonic-gate	clr	%o1
3037c478bdstevel@tonic-gate	ldna	[%o0]ASI_USER, %o1
3047c478bdstevel@tonic-gate	retl
3057c478bdstevel@tonic-gate	mov	%o1, %o0
3067c478bdstevel@tonic-gate	SET_SIZE(dtrace_fulword)
3077c478bdstevel@tonic-gate
3087c478bdstevel@tonic-gate	ENTRY(dtrace_fuword8)
3097c478bdstevel@tonic-gate	clr	%o1
3107c478bdstevel@tonic-gate	lduba	[%o0]ASI_USER, %o1
3117c478bdstevel@tonic-gate	retl
3127c478bdstevel@tonic-gate	mov	%o1, %o0
3137c478bdstevel@tonic-gate	SET_SIZE(dtrace_fuword8)
3147c478bdstevel@tonic-gate
3157c478bdstevel@tonic-gate	ENTRY(dtrace_fuword16)
3167c478bdstevel@tonic-gate	clr	%o1
3177c478bdstevel@tonic-gate	lduha	[%o0]ASI_USER, %o1
3187c478bdstevel@tonic-gate	retl
3197c478bdstevel@tonic-gate	mov	%o1, %o0
3207c478bdstevel@tonic-gate	SET_SIZE(dtrace_fuword16)
3217c478bdstevel@tonic-gate
3227c478bdstevel@tonic-gate	ENTRY(dtrace_fuword32)
3237c478bdstevel@tonic-gate	clr	%o1
3247c478bdstevel@tonic-gate	lda	[%o0]ASI_USER, %o1
3257c478bdstevel@tonic-gate	retl
3267c478bdstevel@tonic-gate	mov	%o1, %o0
3277c478bdstevel@tonic-gate	SET_SIZE(dtrace_fuword32)
3287c478bdstevel@tonic-gate
3297c478bdstevel@tonic-gate	ENTRY(dtrace_fuword64)
3307c478bdstevel@tonic-gate	clr	%o1
3317c478bdstevel@tonic-gate	ldxa	[%o0]ASI_USER, %o1
3327c478bdstevel@tonic-gate	retl
3337c478bdstevel@tonic-gate	mov	%o1, %o0
3347c478bdstevel@tonic-gate	SET_SIZE(dtrace_fuword64)
3357c478bdstevel@tonic-gate
3367c478bdstevel@tonic-gate	/*
3377c478bdstevel@tonic-gate	 * %g1	pcstack
3387c478bdstevel@tonic-gate	 * %g2	current window
3397c478bdstevel@tonic-gate	 * %g3	maxwin (nwindows - 1)
3407c478bdstevel@tonic-gate	 * %g4	saved %cwp (so we can get back to the original window)
3417c478bdstevel@tonic-gate	 * %g5	iteration count
3427c478bdstevel@tonic-gate	 * %g6	saved %fp
3437c478bdstevel@tonic-gate	 *
3447c478bdstevel@tonic-gate	 * %o0	pcstack / return value (iteration count)
3457c478bdstevel@tonic-gate	 * %o1	pcstack_limit
3467c478bdstevel@tonic-gate	 * %o2	last_fp
3477c478bdstevel@tonic-gate	 */
3487c478bdstevel@tonic-gate
3497c478bdstevel@tonic-gate	ENTRY(dtrace_getupcstack_top)
3507c478bdstevel@tonic-gate	mov	%o0, %g1		! we need the pcstack pointer while
3517c478bdstevel@tonic-gate					! we're visiting other windows
3527c478bdstevel@tonic-gate
3537c478bdstevel@tonic-gate	rdpr	%otherwin, %g5		! compute the number of iterations
3547c478bdstevel@tonic-gate	cmp	%g5, %o1		! (windows to observe) by taking the
3557c478bdstevel@tonic-gate	movg	%icc, %o1, %g5		! min of %otherwin and pcstack_limit
3567c478bdstevel@tonic-gate
3577c478bdstevel@tonic-gate	brlez,a,pn %g5, 2f		! return 0 if count <= 0
3587c478bdstevel@tonic-gate	clr	%o0
3597c478bdstevel@tonic-gate
3607c478bdstevel@tonic-gate	sethi	%hi(nwin_minus_one), %g3 ! hang onto maxwin since we'll need
3617c478bdstevel@tonic-gate	ld	[%g3 + %lo(nwin_minus_one)], %g3 ! it for our modular arithmetic
3627c478bdstevel@tonic-gate
3637c478bdstevel@tonic-gate	rdpr	%cwp, %g4		! remember our window so we can return
3647c478bdstevel@tonic-gate	rdpr	%canrestore, %g2	! compute the first non-user window
3650b38a8bahl	subcc	%g4, %g2, %g2		! current = %cwp - %canrestore
3667c478bdstevel@tonic-gate
3677c478bdstevel@tonic-gate	bge,pt	%xcc, 1f		! good to go if current is >= 0
3687c478bdstevel@tonic-gate	mov	%g5, %o0		! we need to return the count
3697c478bdstevel@tonic-gate
3707c478bdstevel@tonic-gate	add	%g2, %g3, %g2		! normalize our current window if it's
3717c478bdstevel@tonic-gate	add	%g2, 1, %g2		! less than zero
3727c478bdstevel@tonic-gate
3737c478bdstevel@tonic-gate	! note that while it's tempting, we can't execute restore to decrement
3747c478bdstevel@tonic-gate	! the %cwp by one (mod nwindows) because we're in the user's windows
3757c478bdstevel@tonic-gate1:
3767c478bdstevel@tonic-gate	deccc	%g2			! decrement the current window
3777c478bdstevel@tonic-gate	movl	%xcc, %g3, %g2		! normalize if it's negative (-1)
3787c478bdstevel@tonic-gate
3797c478bdstevel@tonic-gate	wrpr	%g2, %cwp		! change windows
3807c478bdstevel@tonic-gate
3817c478bdstevel@tonic-gate	stx	%i7, [%g1]		! stash the return address in pcstack
3827c478bdstevel@tonic-gate
3837c478bdstevel@tonic-gate	deccc	%g5			! decrement the count
3847c478bdstevel@tonic-gate	bnz,pt	%icc, 1b		! we iterate until the count reaches 0
3857c478bdstevel@tonic-gate	add	%g1, 8, %g1		! increment the pcstack pointer
3867c478bdstevel@tonic-gate
3877c478bdstevel@tonic-gate	mov	%i6, %g6		! stash the last frame pointer we
3887c478bdstevel@tonic-gate					! encounter so the caller can
3897c478bdstevel@tonic-gate					! continue the stack walk in memory
3907c478bdstevel@tonic-gate
3917c478bdstevel@tonic-gate	wrpr	%g4, %cwp		! change back to the original window
3927c478bdstevel@tonic-gate
3937c478bdstevel@tonic-gate	stn	%g6, [%o2]		! return the last frame pointer
3947c478bdstevel@tonic-gate
3957c478bdstevel@tonic-gate2:
3967c478bdstevel@tonic-gate	retl
3977c478bdstevel@tonic-gate	nop
3987c478bdstevel@tonic-gate	SET_SIZE(dtrace_getupcstack_top)
3997c478bdstevel@tonic-gate
4000b38a8bahl	ENTRY(dtrace_getustackdepth_top)
4010b38a8bahl	mov	%o0, %o2
4020b38a8bahl	rdpr	%otherwin, %o0
4030b38a8bahl
4040b38a8bahl	brlez,a,pn %o0, 2f		! return 0 if there are no user wins
4050b38a8bahl	clr	%o0
4060b38a8bahl
4070b38a8bahl	rdpr	%cwp, %g4		! remember our window so we can return
4080b38a8bahl	rdpr	%canrestore, %g2	! compute the first user window
4090b38a8bahl	sub	%g4, %g2, %g2		! current = %cwp - %canrestore -
4100b38a8bahl	subcc	%g2, %o0, %g2		!     %otherwin
4110b38a8bahl
4120b38a8bahl	bge,pt	%xcc, 1f		! normalize the window if necessary
4130b38a8bahl	sethi	%hi(nwin_minus_one), %g3
4140b38a8bahl	ld	[%g3 + %lo(nwin_minus_one)], %g3
4150b38a8bahl	add	%g2, %g3, %g2
4160b38a8bahl	add	%g2, 1, %g2
4170b38a8bahl
4180b38a8bahl1:
4190b38a8bahl	wrpr	%g2, %cwp		! change to the first user window
4200b38a8bahl	mov	%i6, %g6		! stash the frame pointer
4210b38a8bahl	wrpr	%g4, %cwp		! change back to the original window
4220b38a8bahl
4230b38a8bahl	stn	%g6, [%o2]		! return the frame pointer
4240b38a8bahl
4250b38a8bahl2:
4260b38a8bahl	retl
4270b38a8bahl	nop
4280b38a8bahl	SET_SIZE(dtrace_getustackdepth_top)
4290b38a8bahl
4307c478bdstevel@tonic-gate	ENTRY(dtrace_getreg_win)
4317c478bdstevel@tonic-gate	sub	%o0, 16, %o0
4327c478bdstevel@tonic-gate	cmp	%o0, 16			! %o0 must begin in the range [16..32)
4337c478bdstevel@tonic-gate	blu,pt	%xcc, 1f
4347c478bdstevel@tonic-gate	nop
4357c478bdstevel@tonic-gate	retl
4367c478bdstevel@tonic-gate	clr	%o0
4377c478bdstevel@tonic-gate
4387c478bdstevel@tonic-gate1:
4397c478bdstevel@tonic-gate	set	dtrace_getreg_win_table, %g3
4407c478bdstevel@tonic-gate	sll	%o0, 2, %o0
4417c478bdstevel@tonic-gate	add	%g3, %o0, %g3
4427c478bdstevel@tonic-gate
4437c478bdstevel@tonic-gate	rdpr	%canrestore, %o3
4447c478bdstevel@tonic-gate	rdpr	%cwp, %g2
4457c478bdstevel@tonic-gate
4467c478bdstevel@tonic-gate	! Set %cwp to be (%cwp - %canrestore - %o1) mod NWINDOWS
4477c478bdstevel@tonic-gate
4487c478bdstevel@tonic-gate	sub	%g2, %o3, %o2		! %o2 is %cwp - %canrestore
4497c478bdstevel@tonic-gate	subcc	%o2, %o1, %o4
4507c478bdstevel@tonic-gate	bge,a,pn %xcc, 2f
4517c478bdstevel@tonic-gate	wrpr	%o4, %cwp
4527c478bdstevel@tonic-gate
4537c478bdstevel@tonic-gate	sethi	%hi(nwin_minus_one), %o3
4547c478bdstevel@tonic-gate	ld	[%o3 + %lo(nwin_minus_one)], %o3
4557c478bdstevel@tonic-gate
4567c478bdstevel@tonic-gate	add	%o2, %o3, %o4
4577c478bdstevel@tonic-gate	wrpr	%o4, %cwp
4587c478bdstevel@tonic-gate2:
4597c478bdstevel@tonic-gate	jmp	%g3
4607c478bdstevel@tonic-gate	ba	3f
4617c478bdstevel@tonic-gate3:
4627c478bdstevel@tonic-gate	wrpr	%g2, %cwp
4637c478bdstevel@tonic-gate	retl
4647c478bdstevel@tonic-gate	mov	%g1, %o0
4657c478bdstevel@tonic-gate
4667c478bdstevel@tonic-gatedtrace_getreg_win_table:
4677c478bdstevel@tonic-gate	mov	%l0, %g1
4687c478bdstevel@tonic-gate	mov	%l1, %g1
4697c478bdstevel@tonic-gate	mov	%l2, %g1
4707c478bdstevel@tonic-gate	mov	%l3, %g1
4717c478bdstevel@tonic-gate	mov	%l4, %g1
4727c478bdstevel@tonic-gate	mov	%l5, %g1
4737c478bdstevel@tonic-gate	mov	%l6, %g1
4747c478bdstevel@tonic-gate	mov	%l7, %g1
4757c478bdstevel@tonic-gate	mov	%i0, %g1
4767c478bdstevel@tonic-gate	mov	%i1, %g1
4777c478bdstevel@tonic-gate	mov	%i2, %g1
4787c478bdstevel@tonic-gate	mov	%i3, %g1
4797c478bdstevel@tonic-gate	mov	%i4, %g1
4807c478bdstevel@tonic-gate	mov	%i5, %g1
4817c478bdstevel@tonic-gate	mov	%i6, %g1
4827c478bdstevel@tonic-gate	mov	%i7, %g1
4837c478bdstevel@tonic-gate	SET_SIZE(dtrace_getreg_win)
4847c478bdstevel@tonic-gate
4857c478bdstevel@tonic-gate	ENTRY(dtrace_putreg_win)
4867c478bdstevel@tonic-gate	sub	%o0, 16, %o0
4877c478bdstevel@tonic-gate	cmp	%o0, 16			! %o0 must be in the range [16..32)
4887c478bdstevel@tonic-gate	blu,pt	%xcc, 1f
4897c478bdstevel@tonic-gate	nop
4907c478bdstevel@tonic-gate	retl
4917c478bdstevel@tonic-gate	nop
4927c478bdstevel@tonic-gate
4937c478bdstevel@tonic-gate1:
4947c478bdstevel@tonic-gate	mov	%o1, %g1		! move the value into a global register
4957c478bdstevel@tonic-gate
4967c478bdstevel@tonic-gate	set	dtrace_putreg_table, %g3
4977c478bdstevel@tonic-gate	sll	%o0, 2, %o0
4987c478bdstevel@tonic-gate	add	%g3, %o0, %g3
4997c478bdstevel@tonic-gate
5007c478bdstevel@tonic-gate	rdpr	%canrestore, %o3
5017c478bdstevel@tonic-gate	rdpr	%cwp, %g2
5027c478bdstevel@tonic-gate
5037c478bdstevel@tonic-gate	! Set %cwp to be (%cwp - %canrestore - 1) mod NWINDOWS
5047c478bdstevel@tonic-gate
5057c478bdstevel@tonic-gate	sub	%g2, %o3, %o2		! %o2 is %cwp - %canrestore
5067c478bdstevel@tonic-gate	subcc	%o2, 1, %o4
5077c478bdstevel@tonic-gate	bge,a,pn %xcc, 2f
5087c478bdstevel@tonic-gate	wrpr	%o4, %cwp
5097c478bdstevel@tonic-gate
5107c478bdstevel@tonic-gate	sethi	%hi(nwin_minus_one), %o3
5117c478bdstevel@tonic-gate	ld	[%o3 + %lo(nwin_minus_one)], %o3
5127c478bdstevel@tonic-gate	add	%o2, %o3, %o4
5137c478bdstevel@tonic-gate	wrpr	%o4, %cwp
5147c478bdstevel@tonic-gate2:
5157c478bdstevel@tonic-gate	jmp	%g3
5167c478bdstevel@tonic-gate	ba	3f
5177c478bdstevel@tonic-gate3:
5187c478bdstevel@tonic-gate	wrpr	%g2, %cwp
5197c478bdstevel@tonic-gate	retl
5207c478bdstevel@tonic-gate	nop
5217c478bdstevel@tonic-gate
5227c478bdstevel@tonic-gatedtrace_putreg_table:
5237c478bdstevel@tonic-gate	mov	%g1, %l0
5247c478bdstevel@tonic-gate	mov	%g1, %l1
5257c478bdstevel@tonic-gate	mov	%g1, %l2
5267c478bdstevel@tonic-gate	mov	%g1, %l3
5277c478bdstevel@tonic-gate	mov	%g1, %l4
5287c478bdstevel@tonic-gate	mov	%g1, %l5
5297c478bdstevel@tonic-gate	mov	%g1, %l6
5307c478bdstevel@tonic-gate	mov	%g1, %l7
5317c478bdstevel@tonic-gate	mov	%g1, %i0
5327c478bdstevel@tonic-gate	mov	%g1, %i1
5337c478bdstevel@tonic-gate	mov	%g1, %i2
5347c478bdstevel@tonic-gate	mov	%g1, %i3
5357c478bdstevel@tonic-gate	mov	%g1, %i4
5367c478bdstevel@tonic-gate	mov	%g1, %i5
5377c478bdstevel@tonic-gate	mov	%g1, %i6
5387c478bdstevel@tonic-gate	mov	%g1, %i7
5397c478bdstevel@tonic-gate	SET_SIZE(dtrace_putreg_win)
5407c478bdstevel@tonic-gate
5417c478bdstevel@tonic-gate	ENTRY(dtrace_probe_error)
5427c478bdstevel@tonic-gate	save	%sp, -SA(MINFRAME), %sp
5437c478bdstevel@tonic-gate	sethi	%hi(dtrace_probeid_error), %l0
5447c478bdstevel@tonic-gate	ld	[%l0 + %lo(dtrace_probeid_error)], %o0
5457c478bdstevel@tonic-gate	mov	%i0, %o1
5467c478bdstevel@tonic-gate	mov	%i1, %o2
5477c478bdstevel@tonic-gate	mov	%i2, %o3
5487c478bdstevel@tonic-gate	mov	%i3, %o4
5497c478bdstevel@tonic-gate	call	dtrace_probe
5507c478bdstevel@tonic-gate	mov	%i4, %o5
5517c478bdstevel@tonic-gate	ret
5527c478bdstevel@tonic-gate	restore
5537c478bdstevel@tonic-gate	SET_SIZE(dtrace_probe_error)
5547c478bdstevel@tonic-gate
555