xref: /netbsd-src/lib/libc/compat/arch/sparc64/gen/compat_setjmp.S (revision 180e99b5f32641261bbc52895e59da5577dfece6)
1*180e99b5Schristos/*	$NetBSD: compat_setjmp.S,v 1.1 2005/10/16 04:41:34 christos Exp $	*/
2*180e99b5Schristos
3*180e99b5Schristos/*
4*180e99b5Schristos * Copyright (c) 1992, 1993
5*180e99b5Schristos *	The Regents of the University of California.  All rights reserved.
6*180e99b5Schristos *
7*180e99b5Schristos * This software was developed by the Computer Systems Engineering group
8*180e99b5Schristos * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
9*180e99b5Schristos * contributed to Berkeley.
10*180e99b5Schristos *
11*180e99b5Schristos * Redistribution and use in source and binary forms, with or without
12*180e99b5Schristos * modification, are permitted provided that the following conditions
13*180e99b5Schristos * are met:
14*180e99b5Schristos * 1. Redistributions of source code must retain the above copyright
15*180e99b5Schristos *    notice, this list of conditions and the following disclaimer.
16*180e99b5Schristos * 2. Redistributions in binary form must reproduce the above copyright
17*180e99b5Schristos *    notice, this list of conditions and the following disclaimer in the
18*180e99b5Schristos *    documentation and/or other materials provided with the distribution.
19*180e99b5Schristos * 3. Neither the name of the University nor the names of its contributors
20*180e99b5Schristos *    may be used to endorse or promote products derived from this software
21*180e99b5Schristos *    without specific prior written permission.
22*180e99b5Schristos *
23*180e99b5Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24*180e99b5Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25*180e99b5Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26*180e99b5Schristos * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27*180e99b5Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28*180e99b5Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29*180e99b5Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30*180e99b5Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31*180e99b5Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32*180e99b5Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33*180e99b5Schristos * SUCH DAMAGE.
34*180e99b5Schristos *
35*180e99b5Schristos * from: Header: setjmp.s,v 1.2 92/06/25 03:18:43 torek Exp
36*180e99b5Schristos */
37*180e99b5Schristos
38*180e99b5Schristos#define _LOCORE
39*180e99b5Schristos#include <machine/asm.h>
40*180e99b5Schristos#include <machine/frame.h>
41*180e99b5Schristos#if defined(LIBC_SCCS) && !defined(lint)
42*180e99b5Schristos#if 0
43*180e99b5Schristos	.asciz "@(#)setjmp.s	8.1 (Berkeley) 6/4/93"
44*180e99b5Schristos#else
45*180e99b5Schristos	RCSID("$NetBSD: compat_setjmp.S,v 1.1 2005/10/16 04:41:34 christos Exp $")
46*180e99b5Schristos#endif
47*180e99b5Schristos#endif /* LIBC_SCCS and not lint */
48*180e99b5Schristos
49*180e99b5Schristos/*
50*180e99b5Schristos * C library -- setjmp, longjmp
51*180e99b5Schristos *
52*180e99b5Schristos *	longjmp(a,v)
53*180e99b5Schristos * will generate a "return(v)" from
54*180e99b5Schristos * the last call to
55*180e99b5Schristos *	setjmp(a)
56*180e99b5Schristos * by restoring registers from the stack,
57*180e99b5Schristos * and a struct sigcontext, see <signal.h>
58*180e99b5Schristos */
59*180e99b5Schristos
60*180e99b5Schristos#include "SYS.h"
61*180e99b5Schristos
62*180e99b5Schristos#define STACK_T_SZ
63*180e99b5SchristosENTRY(setjmp)
64*180e99b5Schristos	/*
65*180e99b5Schristos	 * We use the part of the sigcontext structure, the sp, pc, and npc fields,
66*180e99b5Schristos	 * for the sigstack call so we don't need to get our own stackframe.  It
67*180e99b5Schristos	 * won't be filled out till later anyway.
68*180e99b5Schristos	 */
69*180e99b5Schristos	mov	%o0, %o3		/* Save our jmp_buf in %o3 */
70*180e99b5Schristos	mov	%o0, %o2		/* build sigcontext in [%o2] */
71*180e99b5Schristos	mov	1, %o0			/* SIG_BLOCK */
72*180e99b5Schristos	mov	SYS_compat_13_sigprocmask13, %g1
73*180e99b5Schristos	clr	%o1			/* sigprocmask(SIG_BLOCK, (sigset_t *)NULL, (sigset_t *)a) */
74*180e99b5Schristos	t	ST_SYSCALL
75*180e99b5Schristos
76*180e99b5Schristos	st	%o0, [%o3 + 0x04]	/* sc.sc_mask = current mask; */
77*180e99b5Schristos	mov	SYS___sigaltstack14, %g1
78*180e99b5Schristos	clr	%o0			/* sigstack(NULL, &foo) */
79*180e99b5Schristos	add	%o3, 0x38, %o1		/* (foo being the sigcontext14 sc_mask) */
80*180e99b5Schristos	t	ST_SYSCALL
81*180e99b5Schristos
82*180e99b5Schristos	lduw	[%o3 + 0x38+0x10], %o0	/* foo.ss_flags */
83*180e99b5Schristos	and	%o0, 1, %o1		/* onstack = foo.ss_flags & 1; */
84*180e99b5Schristos	st	%o0, [%o3 + 0x00]	/* sc.sc_onstack = current onstack; */
85*180e99b5Schristos	stx	%sp, [%o3 + 0x08]	/* sc.sc_sp = sp (both ours and caller's) */
86*180e99b5Schristos	add	%o7, 8, %o0
87*180e99b5Schristos	stx	%o0, [%o3 + 0x10]	/* sc.sc_pc = return_pc */
88*180e99b5Schristos	add	%o7, 12, %o0
89*180e99b5Schristos	stx	%o0, [%o3 + 0x18]	/* sc.sc_npc = return_pc + 4 */
90*180e99b5Schristos	stx	%g0, [%o3 + 0x20]	/* sc.sc_psr = (clean psr) */
91*180e99b5Schristos	stx	%fp, [%o3 + 0x28]	/* sc.sc_g1 = %fp (misuse, but what the heck) */
92*180e99b5Schristos					/* sc.sc_o0 = random(), set in longjmp */
93*180e99b5Schristos	retl				/* return 0 */
94*180e99b5Schristos	 clr	%o0
95*180e99b5Schristos
96*180e99b5Schristos/*
97*180e99b5Schristos * All we need to do here is force sigreturn to load a new stack pointer,
98*180e99b5Schristos * new <pc,npc>, and appropriate %o0 return value from the sigcontext built
99*180e99b5Schristos * in setjmp.  The %i and %l registers will be reloaded from the place to
100*180e99b5Schristos * which %sp points, due to sigreturn() semantics (sigreturn does not modify
101*180e99b5Schristos * the window pointer in the psr, hence it must force all windows to reload).
102*180e99b5Schristos */
103*180e99b5SchristosENTRY(longjmp)
104*180e99b5Schristos	save	%sp, -CC64FSZ, %sp
105*180e99b5Schristos	ldx	[%i0 + 0x08], %o2	/* make sure sc->sc_sp, sc->sc_fp nonzero */
106*180e99b5Schristos	ldx	[%i0 + 0x28], %o3
107*180e99b5Schristos	orcc	%o2, %o3, %g0
108*180e99b5Schristos	bz,pn	%xcc, Lbotch
109*180e99b5Schristos	 movrz	%i1, 1, %i1		/* if (v == 0) v = 1; */
110*180e99b5Schristos	st	%i1, [%i0 + 0x30]	/* sc.sc_o0 = v; */
111*180e99b5Schristos	mov	SYS_compat_13_sigreturn13, %g1
112*180e99b5Schristos	mov	%i0, %o0
113*180e99b5Schristos	t	ST_SYSCALL		/* sigreturn(scp); */
114*180e99b5Schristos
115*180e99b5SchristosLbotch:
116*180e99b5Schristos	/* oops, caller botched it */
117*180e99b5Schristos	call	_C_LABEL(longjmperror)
118*180e99b5Schristos	 nop
119*180e99b5Schristos	unimp	0
120