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