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#include <sys/syscall.h> 12#include <machine/reg.h> 13#include "DEFS.h" 14 15#if defined(LIBC_SCCS) && !defined(lint) 16 ASMSTR("@(#)setjmp.s 5.3 (Berkeley) 03/07/92") 17#endif /* LIBC_SCCS and not lint */ 18 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 30#define SETJMP_FRAME_SIZE (STAND_FRAME_SIZE + 8) 31 32NON_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 42 addu a1, sp, STAND_FRAME_SIZE # pointer to struct sigstack 43 jal sigstack 44 lw a0, SETJMP_FRAME_SIZE(sp) # restore jmpbuf 45 lw v1, STAND_FRAME_SIZE+4(sp) # get old ss_onstack 46 sw v1, 0(a0) # save it in sc_onstack 47 lw ra, STAND_RA_OFFSET(sp) 48 addu sp, sp, SETJMP_FRAME_SIZE 49 blt v0, zero, botch # check for sigstack() error 50 sw ra, (2 * 4)(a0) # sc_pc = return address 51 li v0, 0xACEDBADE # sigcontext magic number 52 sw v0, ((ZERO + 3) * 4)(a0) # saved in sc_regs[0] 53 sw s0, ((S0 + 3) * 4)(a0) 54 sw s1, ((S1 + 3) * 4)(a0) 55 sw s2, ((S2 + 3) * 4)(a0) 56 sw s3, ((S3 + 3) * 4)(a0) 57 sw s4, ((S4 + 3) * 4)(a0) 58 sw s5, ((S5 + 3) * 4)(a0) 59 sw s6, ((S6 + 3) * 4)(a0) 60 sw s7, ((S7 + 3) * 4)(a0) 61 sw gp, ((GP + 3) * 4)(a0) 62 sw sp, ((SP + 3) * 4)(a0) 63 sw s8, ((S8 + 3) * 4)(a0) 64 li v0, 1 # be nice if we could tell 65 sw v0, (37 * 4)(a0) # sc_fpused = 1 66 cfc1 v0, $31 67 swc1 $f20, ((20 + 38) * 4)(a0) 68 swc1 $f21, ((21 + 38) * 4)(a0) 69 swc1 $f22, ((22 + 38) * 4)(a0) 70 swc1 $f23, ((23 + 38) * 4)(a0) 71 swc1 $f24, ((24 + 38) * 4)(a0) 72 swc1 $f25, ((25 + 38) * 4)(a0) 73 swc1 $f26, ((26 + 38) * 4)(a0) 74 swc1 $f27, ((27 + 38) * 4)(a0) 75 swc1 $f28, ((28 + 38) * 4)(a0) 76 swc1 $f29, ((29 + 38) * 4)(a0) 77 swc1 $f30, ((30 + 38) * 4)(a0) 78 swc1 $f31, ((31 + 38) * 4)(a0) 79 sw v0, ((32 + 38) * 4)(a0) 80 move v0, zero 81 j ra 82END(setjmp) 83 84LEAF(longjmp) 85 sw a1, ((V0 + 3) * 4)(a0) # save return value in sc_regs[V0] 86 li v0, SYS_sigreturn 87 syscall 88botch: 89 jal longjmperror 90 jal abort 91END(longjmp) 92