1*52708Sbostic/*- 2*52708Sbostic * Copyright (c) 1991 The Regents of the University of California. 3*52708Sbostic * All rights reserved. 4*52708Sbostic * 5*52708Sbostic * This code is derived from software contributed to Berkeley by 6*52708Sbostic * Ralph Campbell. 7*52708Sbostic * 8*52708Sbostic * %sccs.include.redist.c% 9*52708Sbostic */ 10*52708Sbostic 11*52708Sbostic#if defined(LIBC_SCCS) && !defined(lint) 12*52708Sbostic ASMSTR("@(#)setjmp.s 5.1 (Berkeley) 02/29/92") 13*52708Sbostic#endif /* LIBC_SCCS and not lint */ 14*52708Sbostic 15*52708Sbostic#include <sys/syscall.h> 16*52708Sbostic#include "DEFS.h" 17*52708Sbostic 18*52708Sbostic/* 19*52708Sbostic * C library -- setjmp, longjmp 20*52708Sbostic * 21*52708Sbostic * longjmp(a,v) 22*52708Sbostic * will generate a "return(v)" from 23*52708Sbostic * the last call to 24*52708Sbostic * setjmp(a) 25*52708Sbostic * by restoring registers from the stack, 26*52708Sbostic * and a struct sigcontext, see <signal.h> 27*52708Sbostic */ 28*52708Sbostic 29*52708Sbostic#define SETJMP_FRAME_SIZE (STAND_FRAME_SIZE + 8) 30*52708Sbostic 31*52708SbosticNON_LEAF(setjmp, SETJMP_FRAME_SIZE, ra) 32*52708Sbostic subu sp, sp, SETJMP_FRAME_SIZE # allocate stack frame 33*52708Sbostic .mask 0x80000000, (STAND_RA_OFFSET - STAND_FRAME_SIZE) 34*52708Sbostic sw ra, STAND_RA_OFFSET(sp) # save state 35*52708Sbostic sw a0, SETJMP_FRAME_SIZE(sp) 36*52708Sbostic move a0, zero # get current signal mask 37*52708Sbostic jal sigblock 38*52708Sbostic lw v1, SETJMP_FRAME_SIZE(sp) # v1 = jmpbuf 39*52708Sbostic sw v0, (1 * 4)(v1) # save sc_mask = sigblock(0) 40*52708Sbostic move a0, zero 41*52708Sbostic addu a1, sp, STAND_FRAME_SIZE # pointer to struct sigstack 42*52708Sbostic jal sigstack 43*52708Sbostic lw a0, SETJMP_FRAME_SIZE(sp) # restore jmpbuf 44*52708Sbostic lw v1, STAND_FRAME_SIZE+4(sp) # get old ss_onstack 45*52708Sbostic sw v1, 0(a0) # save it in sc_onstack 46*52708Sbostic lw ra, STAND_RA_OFFSET(sp) 47*52708Sbostic addu sp, sp, SETJMP_FRAME_SIZE 48*52708Sbostic blt v0, zero, botch # check for sigstack() error 49*52708Sbostic sw ra, (2 * 4)(a0) # sc_pc = return address 50*52708Sbostic li v0, 0xACEDBADE # sigcontext magic number 51*52708Sbostic sw v0, ((ZERO + 3) * 4)(a0) # saved in sc_regs[0] 52*52708Sbostic sw s0, ((S0 + 3) * 4)(a0) 53*52708Sbostic sw s1, ((S1 + 3) * 4)(a0) 54*52708Sbostic sw s2, ((S2 + 3) * 4)(a0) 55*52708Sbostic sw s3, ((S3 + 3) * 4)(a0) 56*52708Sbostic sw s4, ((S4 + 3) * 4)(a0) 57*52708Sbostic sw s5, ((S5 + 3) * 4)(a0) 58*52708Sbostic sw s6, ((S6 + 3) * 4)(a0) 59*52708Sbostic sw s7, ((S7 + 3) * 4)(a0) 60*52708Sbostic sw gp, ((GP + 3) * 4)(a0) 61*52708Sbostic sw sp, ((SP + 3) * 4)(a0) 62*52708Sbostic sw s8, ((S8 + 3) * 4)(a0) 63*52708Sbostic li v0, 1 # be nice if we could tell 64*52708Sbostic sw v0, (37 * 4)(a0) # sc_fpused = 1 65*52708Sbostic cfc1 v0, $31 66*52708Sbostic swc1 $f20, ((20 + 38) * 4)(a0) 67*52708Sbostic swc1 $f21, ((21 + 38) * 4)(a0) 68*52708Sbostic swc1 $f22, ((22 + 38) * 4)(a0) 69*52708Sbostic swc1 $f23, ((23 + 38) * 4)(a0) 70*52708Sbostic swc1 $f24, ((24 + 38) * 4)(a0) 71*52708Sbostic swc1 $f25, ((25 + 38) * 4)(a0) 72*52708Sbostic swc1 $f26, ((26 + 38) * 4)(a0) 73*52708Sbostic swc1 $f27, ((27 + 38) * 4)(a0) 74*52708Sbostic swc1 $f28, ((28 + 38) * 4)(a0) 75*52708Sbostic swc1 $f29, ((29 + 38) * 4)(a0) 76*52708Sbostic swc1 $f30, ((30 + 38) * 4)(a0) 77*52708Sbostic swc1 $f31, ((31 + 38) * 4)(a0) 78*52708Sbostic sw v0, ((32 + 38) * 4)(a0) 79*52708Sbostic move v0, zero 80*52708Sbostic j ra 81*52708SbosticEND(setjmp) 82*52708Sbostic 83*52708SbosticLEAF(longjmp) 84*52708Sbostic sw a1, ((V0 + 3) * 4)(a0) # save return value in sc_regs[V0] 85*52708Sbostic li v0, SYS_sigreturn 86*52708Sbostic syscall 87*52708Sbosticbotch: 88*52708Sbostic jal longjmperror 89*52708Sbostic jal abort 90*52708SbosticEND(longjmp) 91