xref: /csrg-svn/lib/libc/mips/gen/setjmp.s (revision 52708)
1*52708Sbostic/*-
2*52708Sbostic * Copyright (c) 1991 The Regents of the University of California.
3*52708Sbostic * All rights reserved.
4*52708Sbostic *
5*52708Sbostic * This code is derived from software contributed to Berkeley by
6*52708Sbostic * Ralph Campbell.
7*52708Sbostic *
8*52708Sbostic * %sccs.include.redist.c%
9*52708Sbostic */
10*52708Sbostic
11*52708Sbostic#if defined(LIBC_SCCS) && !defined(lint)
12*52708Sbostic	ASMSTR("@(#)setjmp.s	5.1 (Berkeley) 02/29/92")
13*52708Sbostic#endif /* LIBC_SCCS and not lint */
14*52708Sbostic
15*52708Sbostic#include <sys/syscall.h>
16*52708Sbostic#include "DEFS.h"
17*52708Sbostic
18*52708Sbostic/*
19*52708Sbostic * C library -- setjmp, longjmp
20*52708Sbostic *
21*52708Sbostic *	longjmp(a,v)
22*52708Sbostic * will generate a "return(v)" from
23*52708Sbostic * the last call to
24*52708Sbostic *	setjmp(a)
25*52708Sbostic * by restoring registers from the stack,
26*52708Sbostic * and a struct sigcontext, see <signal.h>
27*52708Sbostic */
28*52708Sbostic
29*52708Sbostic#define SETJMP_FRAME_SIZE	(STAND_FRAME_SIZE + 8)
30*52708Sbostic
31*52708SbosticNON_LEAF(setjmp, SETJMP_FRAME_SIZE, ra)
32*52708Sbostic	subu	sp, sp, SETJMP_FRAME_SIZE	# allocate stack frame
33*52708Sbostic	.mask	0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE)
34*52708Sbostic	sw	ra, STAND_RA_OFFSET(sp)		# save state
35*52708Sbostic	sw	a0, SETJMP_FRAME_SIZE(sp)
36*52708Sbostic	move	a0, zero			# get current signal mask
37*52708Sbostic	jal	sigblock
38*52708Sbostic	lw	v1, SETJMP_FRAME_SIZE(sp)	# v1 = jmpbuf
39*52708Sbostic	sw	v0, (1 * 4)(v1)			# save sc_mask = sigblock(0)
40*52708Sbostic	move	a0, zero
41*52708Sbostic	addu	a1, sp, STAND_FRAME_SIZE	# pointer to struct sigstack
42*52708Sbostic	jal	sigstack
43*52708Sbostic	lw	a0, SETJMP_FRAME_SIZE(sp)	# restore jmpbuf
44*52708Sbostic	lw	v1, STAND_FRAME_SIZE+4(sp)	# get old ss_onstack
45*52708Sbostic	sw	v1, 0(a0)			# save it in sc_onstack
46*52708Sbostic	lw	ra, STAND_RA_OFFSET(sp)
47*52708Sbostic	addu	sp, sp, SETJMP_FRAME_SIZE
48*52708Sbostic	blt	v0, zero, botch			# check for sigstack() error
49*52708Sbostic	sw	ra, (2 * 4)(a0)			# sc_pc = return address
50*52708Sbostic	li	v0, 0xACEDBADE			# sigcontext magic number
51*52708Sbostic	sw	v0, ((ZERO + 3) * 4)(a0)	#   saved in sc_regs[0]
52*52708Sbostic	sw	s0, ((S0 + 3) * 4)(a0)
53*52708Sbostic	sw	s1, ((S1 + 3) * 4)(a0)
54*52708Sbostic	sw	s2, ((S2 + 3) * 4)(a0)
55*52708Sbostic	sw	s3, ((S3 + 3) * 4)(a0)
56*52708Sbostic	sw	s4, ((S4 + 3) * 4)(a0)
57*52708Sbostic	sw	s5, ((S5 + 3) * 4)(a0)
58*52708Sbostic	sw	s6, ((S6 + 3) * 4)(a0)
59*52708Sbostic	sw	s7, ((S7 + 3) * 4)(a0)
60*52708Sbostic	sw	gp, ((GP + 3) * 4)(a0)
61*52708Sbostic	sw	sp, ((SP + 3) * 4)(a0)
62*52708Sbostic	sw	s8, ((S8 + 3) * 4)(a0)
63*52708Sbostic	li	v0, 1				# be nice if we could tell
64*52708Sbostic	sw	v0, (37 * 4)(a0)		# sc_fpused = 1
65*52708Sbostic	cfc1	v0, $31
66*52708Sbostic	swc1	$f20, ((20 + 38) * 4)(a0)
67*52708Sbostic	swc1	$f21, ((21 + 38) * 4)(a0)
68*52708Sbostic	swc1	$f22, ((22 + 38) * 4)(a0)
69*52708Sbostic	swc1	$f23, ((23 + 38) * 4)(a0)
70*52708Sbostic	swc1	$f24, ((24 + 38) * 4)(a0)
71*52708Sbostic	swc1	$f25, ((25 + 38) * 4)(a0)
72*52708Sbostic	swc1	$f26, ((26 + 38) * 4)(a0)
73*52708Sbostic	swc1	$f27, ((27 + 38) * 4)(a0)
74*52708Sbostic	swc1	$f28, ((28 + 38) * 4)(a0)
75*52708Sbostic	swc1	$f29, ((29 + 38) * 4)(a0)
76*52708Sbostic	swc1	$f30, ((30 + 38) * 4)(a0)
77*52708Sbostic	swc1	$f31, ((31 + 38) * 4)(a0)
78*52708Sbostic	sw	v0, ((32 + 38) * 4)(a0)
79*52708Sbostic	move	v0, zero
80*52708Sbostic	j	ra
81*52708SbosticEND(setjmp)
82*52708Sbostic
83*52708SbosticLEAF(longjmp)
84*52708Sbostic	sw	a1, ((V0 + 3) * 4)(a0)	# save return value in sc_regs[V0]
85*52708Sbostic	li	v0, SYS_sigreturn
86*52708Sbostic	syscall
87*52708Sbosticbotch:
88*52708Sbostic	jal	longjmperror
89*52708Sbostic	jal	abort
90*52708SbosticEND(longjmp)
91