xref: /titanic_52/usr/src/stand/lib/sa/sparc/_setjmp.s (revision 1cb6af97c6f66f456d4f726ef056e1ebc0f73305)
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#ident	"%Z%%M%	%I%	%E% SMI"
28
29#if defined(lint)
30
31typedef long *jmp_buf_ptr;
32
33#else	/* lint */
34
35#include <sys/asm_linkage.h>
36
37#endif	/* lint */
38
39/*
40 * _setjmp(buf_ptr)
41 * buf_ptr points to a five word array (jmp_buf). In the first is our
42 * return address, the second, is the callers SP.
43 * The rest is cleared by _setjmp
44 *
45 *		+----------------+
46 *   %i0->	|      pc        |
47 *		+----------------+
48 *		|      sp        |
49 *		+----------------+
50 *		|    sigmask     |
51 *		+----------------+
52 *		|   stagstack    |
53 *		|   structure    |
54 *		+----------------+
55 */
56
57#if defined(lint)
58
59/* ARGSUSED */
60int
61_setjmp(jmp_buf_ptr buf_ptr)
62{ return (0); }
63
64#else	/* lint */
65
66	PCVAL	=	0	! offsets in buf structure
67	SPVAL	=	4
68	SIGMASK	=	8
69	SIGSTACK =	12
70
71	SS_SP	   =	0	! offset in sigstack structure
72	SS_ONSTACK =	4
73
74	ENTRY(_setjmp)
75	st	%o7, [%o0 + PCVAL] 	! return pc
76	st	%sp, [%o0 + SPVAL] 	! save caller's sp
77	clr	[%o0 + SIGMASK]		! clear the remainder of the jmp_buf
78	clr	[%o0 + SIGSTACK + SS_SP]
79	clr	[%o0 + SIGSTACK + SS_ONSTACK]
80	retl
81	clr	%o0
82	SET_SIZE(_setjmp)
83
84#endif	/* lint */
85
86/*
87 * _longjmp(buf_ptr, val)
88 * buf_ptr points to an array which has been initialized by _setjmp.
89 * val is the value we wish to return to _setjmp's caller
90 *
91 * We will flush our registers by doing (nwindows-1) save instructions.
92 * This could be better done as a kernel call. This is necessary to
93 * ensure that the registers we want to pick up are stored in the stack.
94 * Then, we set fp from the saved fp and make ourselves a stack frame.
95 */
96
97#if defined(lint)
98
99/* ARGSUSED */
100void
101_longjmp(jmp_buf_ptr buf_ptr, int val)
102{
103	return;
104}
105
106#else	/* lint */
107
108	ENTRY(_longjmp)
109	save	%sp, -WINDOWSIZE, %sp
110	!
111	! flush all register windows to the stack.
112	!
113	set	nwindows, %g7
114	ld	[%g7], %g7
115	sub	%g7, 2, %g6
1161:
117	deccc	%g6			! all windows done?
118	bnz	1b
119	save	%sp, -WINDOWSIZE, %sp
120	sub	%g7, 2, %g6
1212:
122	deccc	%g6			! all windows done?
123	bnz	2b
124	restore				! delay slot, increment CWP
125
126	ld	[%i0 + SPVAL], %fp	! build new stack frame
127	sub	%fp, -SA(MINFRAME), %sp	! establish new save area
128	ld	[%i0 + PCVAL], %i7	! get new return pc
129	ret
130	restore	%i1, 0, %o0		! return (val)
131	SET_SIZE(_longjmp)
132
133#endif	/* lint */
134