152708Sbostic/*- 252708Sbostic * Copyright (c) 1991 The Regents of the University of California. 352708Sbostic * All rights reserved. 452708Sbostic * 552708Sbostic * This code is derived from software contributed to Berkeley by 652708Sbostic * Ralph Campbell. 752708Sbostic * 852708Sbostic * %sccs.include.redist.c% 952708Sbostic */ 1052708Sbostic 11*52739Sbostic#include <sys/syscall.h> 12*52739Sbostic#include "DEFS.h" 13*52739Sbostic 1452708Sbostic#if defined(LIBC_SCCS) && !defined(lint) 15*52739Sbostic ASMSTR("@(#)setjmp.s 5.2 (Berkeley) 02/29/92") 1652708Sbostic#endif /* LIBC_SCCS and not lint */ 1752708Sbostic 1852708Sbostic/* 1952708Sbostic * C library -- setjmp, longjmp 2052708Sbostic * 2152708Sbostic * longjmp(a,v) 2252708Sbostic * will generate a "return(v)" from 2352708Sbostic * the last call to 2452708Sbostic * setjmp(a) 2552708Sbostic * by restoring registers from the stack, 2652708Sbostic * and a struct sigcontext, see <signal.h> 2752708Sbostic */ 2852708Sbostic 2952708Sbostic#define SETJMP_FRAME_SIZE (STAND_FRAME_SIZE + 8) 3052708Sbostic 3152708SbosticNON_LEAF(setjmp, SETJMP_FRAME_SIZE, ra) 3252708Sbostic subu sp, sp, SETJMP_FRAME_SIZE # allocate stack frame 3352708Sbostic .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) 3452708Sbostic sw ra, STAND_RA_OFFSET(sp) # save state 3552708Sbostic sw a0, SETJMP_FRAME_SIZE(sp) 3652708Sbostic move a0, zero # get current signal mask 3752708Sbostic jal sigblock 3852708Sbostic lw v1, SETJMP_FRAME_SIZE(sp) # v1 = jmpbuf 3952708Sbostic sw v0, (1 * 4)(v1) # save sc_mask = sigblock(0) 4052708Sbostic move a0, zero 4152708Sbostic addu a1, sp, STAND_FRAME_SIZE # pointer to struct sigstack 4252708Sbostic jal sigstack 4352708Sbostic lw a0, SETJMP_FRAME_SIZE(sp) # restore jmpbuf 4452708Sbostic lw v1, STAND_FRAME_SIZE+4(sp) # get old ss_onstack 4552708Sbostic sw v1, 0(a0) # save it in sc_onstack 4652708Sbostic lw ra, STAND_RA_OFFSET(sp) 4752708Sbostic addu sp, sp, SETJMP_FRAME_SIZE 4852708Sbostic blt v0, zero, botch # check for sigstack() error 4952708Sbostic sw ra, (2 * 4)(a0) # sc_pc = return address 5052708Sbostic li v0, 0xACEDBADE # sigcontext magic number 5152708Sbostic sw v0, ((ZERO + 3) * 4)(a0) # saved in sc_regs[0] 5252708Sbostic sw s0, ((S0 + 3) * 4)(a0) 5352708Sbostic sw s1, ((S1 + 3) * 4)(a0) 5452708Sbostic sw s2, ((S2 + 3) * 4)(a0) 5552708Sbostic sw s3, ((S3 + 3) * 4)(a0) 5652708Sbostic sw s4, ((S4 + 3) * 4)(a0) 5752708Sbostic sw s5, ((S5 + 3) * 4)(a0) 5852708Sbostic sw s6, ((S6 + 3) * 4)(a0) 5952708Sbostic sw s7, ((S7 + 3) * 4)(a0) 6052708Sbostic sw gp, ((GP + 3) * 4)(a0) 6152708Sbostic sw sp, ((SP + 3) * 4)(a0) 6252708Sbostic sw s8, ((S8 + 3) * 4)(a0) 6352708Sbostic li v0, 1 # be nice if we could tell 6452708Sbostic sw v0, (37 * 4)(a0) # sc_fpused = 1 6552708Sbostic cfc1 v0, $31 6652708Sbostic swc1 $f20, ((20 + 38) * 4)(a0) 6752708Sbostic swc1 $f21, ((21 + 38) * 4)(a0) 6852708Sbostic swc1 $f22, ((22 + 38) * 4)(a0) 6952708Sbostic swc1 $f23, ((23 + 38) * 4)(a0) 7052708Sbostic swc1 $f24, ((24 + 38) * 4)(a0) 7152708Sbostic swc1 $f25, ((25 + 38) * 4)(a0) 7252708Sbostic swc1 $f26, ((26 + 38) * 4)(a0) 7352708Sbostic swc1 $f27, ((27 + 38) * 4)(a0) 7452708Sbostic swc1 $f28, ((28 + 38) * 4)(a0) 7552708Sbostic swc1 $f29, ((29 + 38) * 4)(a0) 7652708Sbostic swc1 $f30, ((30 + 38) * 4)(a0) 7752708Sbostic swc1 $f31, ((31 + 38) * 4)(a0) 7852708Sbostic sw v0, ((32 + 38) * 4)(a0) 7952708Sbostic move v0, zero 8052708Sbostic j ra 8152708SbosticEND(setjmp) 8252708Sbostic 8352708SbosticLEAF(longjmp) 8452708Sbostic sw a1, ((V0 + 3) * 4)(a0) # save return value in sc_regs[V0] 8552708Sbostic li v0, SYS_sigreturn 8652708Sbostic syscall 8752708Sbosticbotch: 8852708Sbostic jal longjmperror 8952708Sbostic jal abort 9052708SbosticEND(longjmp) 91