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