152708Sbostic/*- 2*61143Sbostic * Copyright (c) 1991, 1993 3*61143Sbostic * The Regents of the University of California. 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> 1252857Sralph#include <machine/reg.h> 1355705Sralph#include <machine/machAsmDefs.h> 1452739Sbostic 1552708Sbostic#if defined(LIBC_SCCS) && !defined(lint) 16*61143Sbostic ASMSTR("@(#)setjmp.s 8.1 (Berkeley) 06/04/93") 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 3053729Smckusick#define SETJMP_FRAME_SIZE (STAND_FRAME_SIZE + 12) 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 4253726Smckusick addu a1, sp, STAND_FRAME_SIZE # pointer to struct sigaltstack 4353726Smckusick jal sigaltstack 4452708Sbostic lw a0, SETJMP_FRAME_SIZE(sp) # restore jmpbuf 4553726Smckusick lw v1, STAND_FRAME_SIZE+8(sp) # get old ss_onstack 4653726Smckusick and v1, v1, 1 # extract onstack flag 4752708Sbostic sw v1, 0(a0) # save it in sc_onstack 4852708Sbostic lw ra, STAND_RA_OFFSET(sp) 4952708Sbostic addu sp, sp, SETJMP_FRAME_SIZE 5052708Sbostic blt v0, zero, botch # check for sigstack() error 5152708Sbostic sw ra, (2 * 4)(a0) # sc_pc = return address 5252708Sbostic li v0, 0xACEDBADE # sigcontext magic number 5352708Sbostic sw v0, ((ZERO + 3) * 4)(a0) # saved in sc_regs[0] 5452708Sbostic sw s0, ((S0 + 3) * 4)(a0) 5552708Sbostic sw s1, ((S1 + 3) * 4)(a0) 5652708Sbostic sw s2, ((S2 + 3) * 4)(a0) 5752708Sbostic sw s3, ((S3 + 3) * 4)(a0) 5852708Sbostic sw s4, ((S4 + 3) * 4)(a0) 5952708Sbostic sw s5, ((S5 + 3) * 4)(a0) 6052708Sbostic sw s6, ((S6 + 3) * 4)(a0) 6152708Sbostic sw s7, ((S7 + 3) * 4)(a0) 6252708Sbostic sw gp, ((GP + 3) * 4)(a0) 6352708Sbostic sw sp, ((SP + 3) * 4)(a0) 6452708Sbostic sw s8, ((S8 + 3) * 4)(a0) 6552708Sbostic li v0, 1 # be nice if we could tell 6652708Sbostic sw v0, (37 * 4)(a0) # sc_fpused = 1 6752708Sbostic cfc1 v0, $31 6852708Sbostic swc1 $f20, ((20 + 38) * 4)(a0) 6952708Sbostic swc1 $f21, ((21 + 38) * 4)(a0) 7052708Sbostic swc1 $f22, ((22 + 38) * 4)(a0) 7152708Sbostic swc1 $f23, ((23 + 38) * 4)(a0) 7252708Sbostic swc1 $f24, ((24 + 38) * 4)(a0) 7352708Sbostic swc1 $f25, ((25 + 38) * 4)(a0) 7452708Sbostic swc1 $f26, ((26 + 38) * 4)(a0) 7552708Sbostic swc1 $f27, ((27 + 38) * 4)(a0) 7652708Sbostic swc1 $f28, ((28 + 38) * 4)(a0) 7752708Sbostic swc1 $f29, ((29 + 38) * 4)(a0) 7852708Sbostic swc1 $f30, ((30 + 38) * 4)(a0) 7952708Sbostic swc1 $f31, ((31 + 38) * 4)(a0) 8052708Sbostic sw v0, ((32 + 38) * 4)(a0) 8152708Sbostic move v0, zero 8252708Sbostic j ra 8352708SbosticEND(setjmp) 8452708Sbostic 8552708SbosticLEAF(longjmp) 8652708Sbostic sw a1, ((V0 + 3) * 4)(a0) # save return value in sc_regs[V0] 8752708Sbostic li v0, SYS_sigreturn 8852708Sbostic syscall 8952708Sbosticbotch: 9052708Sbostic jal longjmperror 9152708Sbostic jal abort 9252708SbosticEND(longjmp) 93