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) 02/29/92") 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 31NON_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 81END(setjmp) 82 83LEAF(longjmp) 84 sw a1, ((V0 + 3) * 4)(a0) # save return value in sc_regs[V0] 85 li v0, SYS_sigreturn 86 syscall 87botch: 88 jal longjmperror 89 jal abort 90END(longjmp) 91