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