xref: /netbsd-src/lib/libc/compat/arch/alpha/gen/compat_setjmp.S (revision 2a8eed4fde034413bbd2c73fbcf4983cbfdeded7)
1*2a8eed4fSthorpej/* $NetBSD: compat_setjmp.S,v 1.3 2021/05/25 00:14:41 thorpej Exp $ */
2153a0d26Sdrochner
3153a0d26Sdrochner/*
4153a0d26Sdrochner * Copyright (c) 1994, 1995 Carnegie-Mellon University.
5153a0d26Sdrochner * All rights reserved.
6153a0d26Sdrochner *
7153a0d26Sdrochner * Author: Chris G. Demetriou
8153a0d26Sdrochner *
9153a0d26Sdrochner * Permission to use, copy, modify and distribute this software and
10153a0d26Sdrochner * its documentation is hereby granted, provided that both the copyright
11153a0d26Sdrochner * notice and this permission notice appear in all copies of the
12153a0d26Sdrochner * software, derivative works or modified versions, and any portions
13153a0d26Sdrochner * thereof, and that both notices appear in supporting documentation.
14153a0d26Sdrochner *
15153a0d26Sdrochner * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
16153a0d26Sdrochner * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
17153a0d26Sdrochner * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
18153a0d26Sdrochner *
19153a0d26Sdrochner * Carnegie Mellon requests users of this software to return to
20153a0d26Sdrochner *
21153a0d26Sdrochner *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
22153a0d26Sdrochner *  School of Computer Science
23153a0d26Sdrochner *  Carnegie Mellon University
24153a0d26Sdrochner *  Pittsburgh PA 15213-3890
25153a0d26Sdrochner *
26153a0d26Sdrochner * any improvements or extensions that they make and grant Carnegie the
27153a0d26Sdrochner * rights to redistribute these changes.
28153a0d26Sdrochner */
29153a0d26Sdrochner
30153a0d26Sdrochner#include <machine/asm.h>
31153a0d26Sdrochner
32153a0d26Sdrochner/*
33153a0d26Sdrochner * C library -- setjmp, longjmp
34153a0d26Sdrochner *
35153a0d26Sdrochner *	longjmp(a,v)
36153a0d26Sdrochner * will generate a "return(v)" from
37153a0d26Sdrochner * the last call to
38153a0d26Sdrochner *	setjmp(a)
39153a0d26Sdrochner * by restoring registers from the stack,
40153a0d26Sdrochner * and the previous signal state.
41153a0d26Sdrochner */
42153a0d26Sdrochner
43153a0d26Sdrochner	.set	noreorder
44153a0d26Sdrochner
45153a0d26SdrochnerLEAF(setjmp, 1)
46153a0d26Sdrochner	LDGP(pv)
47153a0d26Sdrochner	stq	ra, (2 * 8)(a0)			/* sc_pc = return address */
48153a0d26Sdrochner	stq	s0, (( 9 + 4) * 8)(a0)		/* saved bits of sc_regs */
49153a0d26Sdrochner	stq	s1, ((10 + 4) * 8)(a0)
50153a0d26Sdrochner	stq	s2, ((11 + 4) * 8)(a0)
51153a0d26Sdrochner	stq	s3, ((12 + 4) * 8)(a0)
52153a0d26Sdrochner	stq	s4, ((13 + 4) * 8)(a0)
53153a0d26Sdrochner	stq	s5, ((14 + 4) * 8)(a0)
54153a0d26Sdrochner	stq	s6, ((15 + 4) * 8)(a0)
55153a0d26Sdrochner	stq	ra, ((26 + 4) * 8)(a0)
56153a0d26Sdrochner	stq	sp, ((30 + 4) * 8)(a0)
57153a0d26Sdrochner
58153a0d26Sdrochner	/*
59153a0d26Sdrochner	 * get signal information
60153a0d26Sdrochner	 */
61153a0d26Sdrochner	mov	a0, s0				/* squirrel away ptr to sc */
62153a0d26Sdrochner
63153a0d26Sdrochner	/* see what's blocked */
64153a0d26Sdrochner	mov	zero, a0
65153a0d26Sdrochner	CALL(sigblock)				/* see what's blocked */
66153a0d26Sdrochner	stq	v0, (1 * 8)(s0)			/* and remember it in sc_mask */
67153a0d26Sdrochner
68153a0d26Sdrochner	lda	sp, -24(sp)			/* sizeof struct sigaltstack */
69153a0d26Sdrochner	mov	zero, a0
70153a0d26Sdrochner	mov	sp, a1
71153a0d26Sdrochner	CALL(__sigaltstack14)
72153a0d26Sdrochner	ldl	t0, 16(sp)			/* offset of ss_flags */
73153a0d26Sdrochner	lda	sp, 24(sp)			/* sizeof struct sigaltstack */
74153a0d26Sdrochner	ldq	ra, ((26 + 4) * 8)(s0)		/* restore return address */
75153a0d26Sdrochner	blt	v0, botch			/* check for error */
76153a0d26Sdrochner	and	t0, 0x1, t0			/* get SA_ONSTACK flag */
77153a0d26Sdrochner	stq	t0, (0 * 8)(s0)			/* and save it in sc_onstack */
78153a0d26Sdrochner	/*
79153a0d26Sdrochner	 * Restore old s0 and a0, and continue saving registers
80153a0d26Sdrochner	 */
81153a0d26Sdrochner	mov	s0, a0
82153a0d26Sdrochner	ldq	s0, (( 9 + 4) * 8)(a0)
83153a0d26Sdrochner
84eb850bdaSchristos	ldq	t0, magic 			/* sigcontext magic number */
85153a0d26Sdrochner	stq	t0, ((31 + 4) * 8)(a0)		/* magic in sc_regs[31] */
86153a0d26Sdrochner	/* Too bad we can't check if we actually used FP */
87153a0d26Sdrochner	ldiq	t0, 1
88153a0d26Sdrochner	stq	t0, (36 * 8)(a0)		/* say we've used FP.  */
89153a0d26Sdrochner	stt	fs0, ((2 + 37) * 8)(a0)		/* saved bits of sc_fpregs */
90153a0d26Sdrochner	stt	fs1, ((3 + 37) * 8)(a0)
91153a0d26Sdrochner	stt	fs2, ((4 + 37) * 8)(a0)
92153a0d26Sdrochner	stt	fs3, ((5 + 37) * 8)(a0)
93153a0d26Sdrochner	stt	fs4, ((6 + 37) * 8)(a0)
94153a0d26Sdrochner	stt	fs5, ((7 + 37) * 8)(a0)
95153a0d26Sdrochner	stt	fs6, ((8 + 37) * 8)(a0)
96153a0d26Sdrochner	stt	fs7, ((9 + 37) * 8)(a0)
97153a0d26Sdrochner	mf_fpcr	ft0				/* get FP control reg */
98153a0d26Sdrochner	stt	ft0, (69 * 8)(a0)		/* and store it in sc_fpcr */
99153a0d26Sdrochner	stq	zero, (70 * 8)(a0)		/* FP software control XXX */
100153a0d26Sdrochner	stq	zero, (71 * 8)(a0)		/* sc_reserved[0] */
101153a0d26Sdrochner	stq	zero, (72 * 8)(a0)		/* sc_reserved[1] */
102153a0d26Sdrochner	stq	zero, (73 * 8)(a0)		/* sc_xxx[0] */
103153a0d26Sdrochner	stq	zero, (74 * 8)(a0)		/* sc_xxx[1] */
104153a0d26Sdrochner	stq	zero, (75 * 8)(a0)		/* sc_xxx[2] */
105153a0d26Sdrochner	stq	zero, (76 * 8)(a0)		/* sc_xxx[3] */
106153a0d26Sdrochner	stq	zero, (77 * 8)(a0)		/* sc_xxx[4] */
107153a0d26Sdrochner	stq	zero, (78 * 8)(a0)		/* sc_xxx[5] */
108153a0d26Sdrochner	stq	zero, (79 * 8)(a0)		/* sc_xxx[6] */
109153a0d26Sdrochner	stq	zero, (80 * 8)(a0)		/* sc_xxx[7] */
110153a0d26Sdrochner
111153a0d26Sdrochner	mov	zero, v0			/* return zero */
112153a0d26Sdrochner	RET
113153a0d26SdrochnerEND(setjmp)
114153a0d26Sdrochner
115153a0d26SdrochnerLEAF(longjmp, 2)
116153a0d26Sdrochner	LDGP(pv)
117*2a8eed4fSthorpej	bne	a1, 1f				/* val != 0, just go */
118*2a8eed4fSthorpej	ldiq	a1, 1				/* val = 1 otherwise */
119*2a8eed4fSthorpej1:	stq	a1, (( 0 + 4) * 8)(a0)		/* save return value */
120153a0d26Sdrochner	CALL(sigreturn)				/* use sigreturn to return */
121153a0d26Sdrochner
122153a0d26Sdrochnerbotch:
123153a0d26Sdrochner	CALL(longjmperror)
124153a0d26Sdrochner	CALL(abort)
125153a0d26Sdrochner	RET					/* "can't" get here... */
126eb850bdaSchristosmagic:
127eb850bdaSchristos	.quad	0xacedbade			/* sigcontext magic number */
128153a0d26SdrochnerEND(longjmp)
129