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