xref: /titanic_50/usr/src/stand/lib/sa/sparc/_setjmp.s (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate/*
2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate *
4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate * with the License.
8*7c478bd9Sstevel@tonic-gate *
9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate *
14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate *
20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate */
22*7c478bd9Sstevel@tonic-gate/*
23*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms.
25*7c478bd9Sstevel@tonic-gate */
26*7c478bd9Sstevel@tonic-gate
27*7c478bd9Sstevel@tonic-gate#ident	"%Z%%M%	%I%	%E% SMI"
28*7c478bd9Sstevel@tonic-gate
29*7c478bd9Sstevel@tonic-gate#if defined(lint)
30*7c478bd9Sstevel@tonic-gate
31*7c478bd9Sstevel@tonic-gatetypedef long *jmp_buf_ptr;
32*7c478bd9Sstevel@tonic-gate
33*7c478bd9Sstevel@tonic-gate#else	/* lint */
34*7c478bd9Sstevel@tonic-gate
35*7c478bd9Sstevel@tonic-gate#include <sys/asm_linkage.h>
36*7c478bd9Sstevel@tonic-gate
37*7c478bd9Sstevel@tonic-gate#endif	/* lint */
38*7c478bd9Sstevel@tonic-gate
39*7c478bd9Sstevel@tonic-gate/*
40*7c478bd9Sstevel@tonic-gate * _setjmp(buf_ptr)
41*7c478bd9Sstevel@tonic-gate * buf_ptr points to a five word array (jmp_buf). In the first is our
42*7c478bd9Sstevel@tonic-gate * return address, the second, is the callers SP.
43*7c478bd9Sstevel@tonic-gate * The rest is cleared by _setjmp
44*7c478bd9Sstevel@tonic-gate *
45*7c478bd9Sstevel@tonic-gate *		+----------------+
46*7c478bd9Sstevel@tonic-gate *   %i0->	|      pc        |
47*7c478bd9Sstevel@tonic-gate *		+----------------+
48*7c478bd9Sstevel@tonic-gate *		|      sp        |
49*7c478bd9Sstevel@tonic-gate *		+----------------+
50*7c478bd9Sstevel@tonic-gate *		|    sigmask     |
51*7c478bd9Sstevel@tonic-gate *		+----------------+
52*7c478bd9Sstevel@tonic-gate *		|   stagstack    |
53*7c478bd9Sstevel@tonic-gate *		|   structure    |
54*7c478bd9Sstevel@tonic-gate *		+----------------+
55*7c478bd9Sstevel@tonic-gate */
56*7c478bd9Sstevel@tonic-gate
57*7c478bd9Sstevel@tonic-gate#if defined(lint)
58*7c478bd9Sstevel@tonic-gate
59*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
60*7c478bd9Sstevel@tonic-gateint
61*7c478bd9Sstevel@tonic-gate_setjmp(jmp_buf_ptr buf_ptr)
62*7c478bd9Sstevel@tonic-gate{ return (0); }
63*7c478bd9Sstevel@tonic-gate
64*7c478bd9Sstevel@tonic-gate#else	/* lint */
65*7c478bd9Sstevel@tonic-gate
66*7c478bd9Sstevel@tonic-gate	PCVAL	=	0	! offsets in buf structure
67*7c478bd9Sstevel@tonic-gate	SPVAL	=	4
68*7c478bd9Sstevel@tonic-gate	SIGMASK	=	8
69*7c478bd9Sstevel@tonic-gate	SIGSTACK =	12
70*7c478bd9Sstevel@tonic-gate
71*7c478bd9Sstevel@tonic-gate	SS_SP	   =	0	! offset in sigstack structure
72*7c478bd9Sstevel@tonic-gate	SS_ONSTACK =	4
73*7c478bd9Sstevel@tonic-gate
74*7c478bd9Sstevel@tonic-gate	ENTRY(_setjmp)
75*7c478bd9Sstevel@tonic-gate	st	%o7, [%o0 + PCVAL] 	! return pc
76*7c478bd9Sstevel@tonic-gate	st	%sp, [%o0 + SPVAL] 	! save caller's sp
77*7c478bd9Sstevel@tonic-gate	clr	[%o0 + SIGMASK]		! clear the remainder of the jmp_buf
78*7c478bd9Sstevel@tonic-gate	clr	[%o0 + SIGSTACK + SS_SP]
79*7c478bd9Sstevel@tonic-gate	clr	[%o0 + SIGSTACK + SS_ONSTACK]
80*7c478bd9Sstevel@tonic-gate	retl
81*7c478bd9Sstevel@tonic-gate	clr	%o0
82*7c478bd9Sstevel@tonic-gate	SET_SIZE(_setjmp)
83*7c478bd9Sstevel@tonic-gate
84*7c478bd9Sstevel@tonic-gate#endif	/* lint */
85*7c478bd9Sstevel@tonic-gate
86*7c478bd9Sstevel@tonic-gate/*
87*7c478bd9Sstevel@tonic-gate * _longjmp(buf_ptr, val)
88*7c478bd9Sstevel@tonic-gate * buf_ptr points to an array which has been initialized by _setjmp.
89*7c478bd9Sstevel@tonic-gate * val is the value we wish to return to _setjmp's caller
90*7c478bd9Sstevel@tonic-gate *
91*7c478bd9Sstevel@tonic-gate * We will flush our registers by doing (nwindows-1) save instructions.
92*7c478bd9Sstevel@tonic-gate * This could be better done as a kernel call. This is necessary to
93*7c478bd9Sstevel@tonic-gate * ensure that the registers we want to pick up are stored in the stack.
94*7c478bd9Sstevel@tonic-gate * Then, we set fp from the saved fp and make ourselves a stack frame.
95*7c478bd9Sstevel@tonic-gate */
96*7c478bd9Sstevel@tonic-gate
97*7c478bd9Sstevel@tonic-gate#if defined(lint)
98*7c478bd9Sstevel@tonic-gate
99*7c478bd9Sstevel@tonic-gate/* ARGSUSED */
100*7c478bd9Sstevel@tonic-gatevoid
101*7c478bd9Sstevel@tonic-gate_longjmp(jmp_buf_ptr buf_ptr, int val)
102*7c478bd9Sstevel@tonic-gate{
103*7c478bd9Sstevel@tonic-gate	return;
104*7c478bd9Sstevel@tonic-gate}
105*7c478bd9Sstevel@tonic-gate
106*7c478bd9Sstevel@tonic-gate#else	/* lint */
107*7c478bd9Sstevel@tonic-gate
108*7c478bd9Sstevel@tonic-gate	ENTRY(_longjmp)
109*7c478bd9Sstevel@tonic-gate	save	%sp, -WINDOWSIZE, %sp
110*7c478bd9Sstevel@tonic-gate	!
111*7c478bd9Sstevel@tonic-gate	! flush all register windows to the stack.
112*7c478bd9Sstevel@tonic-gate	!
113*7c478bd9Sstevel@tonic-gate	set	nwindows, %g7
114*7c478bd9Sstevel@tonic-gate	ld	[%g7], %g7
115*7c478bd9Sstevel@tonic-gate	sub	%g7, 2, %g6
116*7c478bd9Sstevel@tonic-gate1:
117*7c478bd9Sstevel@tonic-gate	deccc	%g6			! all windows done?
118*7c478bd9Sstevel@tonic-gate	bnz	1b
119*7c478bd9Sstevel@tonic-gate	save	%sp, -WINDOWSIZE, %sp
120*7c478bd9Sstevel@tonic-gate	sub	%g7, 2, %g6
121*7c478bd9Sstevel@tonic-gate2:
122*7c478bd9Sstevel@tonic-gate	deccc	%g6			! all windows done?
123*7c478bd9Sstevel@tonic-gate	bnz	2b
124*7c478bd9Sstevel@tonic-gate	restore				! delay slot, increment CWP
125*7c478bd9Sstevel@tonic-gate
126*7c478bd9Sstevel@tonic-gate	ld	[%i0 + SPVAL], %fp	! build new stack frame
127*7c478bd9Sstevel@tonic-gate	sub	%fp, -SA(MINFRAME), %sp	! establish new save area
128*7c478bd9Sstevel@tonic-gate	ld	[%i0 + PCVAL], %i7	! get new return pc
129*7c478bd9Sstevel@tonic-gate	ret
130*7c478bd9Sstevel@tonic-gate	restore	%i1, 0, %o0		! return (val)
131*7c478bd9Sstevel@tonic-gate	SET_SIZE(_longjmp)
132*7c478bd9Sstevel@tonic-gate
133*7c478bd9Sstevel@tonic-gate#endif	/* lint */
134