1*55510a1dSmckusick/*- 2*55510a1dSmckusick * Copyright (c) 1990, 1993 3*55510a1dSmckusick * The Regents of the University of California. All rights reserved. 4*55510a1dSmckusick * 5*55510a1dSmckusick * This code is derived from software contributed to Berkeley by 6*55510a1dSmckusick * the Systems Programming Group of the University of Utah Computer 7*55510a1dSmckusick * Science Department. 8*55510a1dSmckusick * 9*55510a1dSmckusick * %sccs.include.redist.c% 10*55510a1dSmckusick */ 11*55510a1dSmckusick 12*55510a1dSmckusick#if defined(LIBC_SCCS) && !defined(lint) 13*55510a1dSmckusick .asciz "@(#)sigsetjmp.s 8.1 (Berkeley) 05/03/95" 14*55510a1dSmckusick#endif /* LIBC_SCCS and not lint */ 15*55510a1dSmckusick 16*55510a1dSmckusick/* 17*55510a1dSmckusick * C library -- sigsetjmp, siglongjmp 18*55510a1dSmckusick * 19*55510a1dSmckusick * siglongjmp(a,v) 20*55510a1dSmckusick * will generate a "return(v)" from 21*55510a1dSmckusick * the last call to 22*55510a1dSmckusick * sigsetjmp(a, savesig) 23*55510a1dSmckusick * by restoring registers from the stack, 24*55510a1dSmckusick * and a struct sigcontext, see <signal.h> 25*55510a1dSmckusick */ 26*55510a1dSmckusick 27*55510a1dSmckusick#define _JBLEN 17 /* XXX from <setjmp.h> */ 28*55510a1dSmckusick 29*55510a1dSmckusick#include "DEFS.h" 30*55510a1dSmckusick 31*55510a1dSmckusickENTRY(sigsetjmp) 32*55510a1dSmckusick tstl sp@(8) /* save signal mask? */ 33*55510a1dSmckusick beq _setjmp /* do _setjmp */ 34*55510a1dSmckusick movl #_JBLEN,d0 /* last entry in jmpbuf */ 35*55510a1dSmckusick asll #2,d0 /* scale to long ptr */ 36*55510a1dSmckusick movl sp@(4),a0 /* save area pointer */ 37*55510a1dSmckusick addl d0,a0 /* &jmpbuf[_JBLEN] */ 38*55510a1dSmckusick movl sp@(8),a0@ /* jmpbuf[_JBLEN] = savemask */ 39*55510a1dSmckusick bra setjmp /* do setjmp */ 40*55510a1dSmckusick 41*55510a1dSmckusick_setjmp: 42*55510a1dSmckusick movl sp@(4),a0 /* save area pointer */ 43*55510a1dSmckusick clrl a0@+ /* no old onstack */ 44*55510a1dSmckusick clrl a0@+ /* no old sigmask */ 45*55510a1dSmckusick movl sp,a0@+ /* save old SP */ 46*55510a1dSmckusick movl a6,a0@+ /* save old FP */ 47*55510a1dSmckusick clrl a0@+ /* no old AP */ 48*55510a1dSmckusick movl sp@,a0@+ /* save old PC */ 49*55510a1dSmckusick clrl a0@+ /* clear PS */ 50*55510a1dSmckusick moveml #0x3CFC,a0@ /* save other non-scratch regs */ 51*55510a1dSmckusick clrl d0 /* return zero */ 52*55510a1dSmckusick rts 53*55510a1dSmckusick 54*55510a1dSmckusicksetjmp: 55*55510a1dSmckusick subl #12,sp /* space for sigaltstack args/rvals */ 56*55510a1dSmckusick clrl sp@ /* don't change it... */ 57*55510a1dSmckusick movl sp,sp@(4) /* ...but return the current val */ 58*55510a1dSmckusick jsr _sigaltstack /* note: onstack returned in sp@(8) */ 59*55510a1dSmckusick clrl sp@ /* don't change mask, just return */ 60*55510a1dSmckusick jsr _sigblock /* old value */ 61*55510a1dSmckusick movl sp@(8),d1 /* old onstack value */ 62*55510a1dSmckusick andl #1,d1 /* extract onstack flag */ 63*55510a1dSmckusick addl #12,sp 64*55510a1dSmckusick movl sp@(4),a0 /* save area pointer */ 65*55510a1dSmckusick movl d1,a0@+ /* save old onstack value */ 66*55510a1dSmckusick movl d0,a0@+ /* save old signal mask */ 67*55510a1dSmckusick lea sp@(4),a1 /* adjust saved SP since we won't rts */ 68*55510a1dSmckusick movl a1,a0@+ /* save old SP */ 69*55510a1dSmckusick movl a6,a0@+ /* save old FP */ 70*55510a1dSmckusick clrl a0@+ /* no AP */ 71*55510a1dSmckusick movl sp@,a0@+ /* save old PC */ 72*55510a1dSmckusick clrl a0@+ /* clean PS */ 73*55510a1dSmckusick moveml #0x3CFC,a0@ /* save remaining non-scratch regs */ 74*55510a1dSmckusick clrl d0 /* return 0 */ 75*55510a1dSmckusick rts 76*55510a1dSmckusick 77*55510a1dSmckusickENTRY(siglongjmp) 78*55510a1dSmckusick movl #_JBLEN,d0 /* last entry in jmpbuf */ 79*55510a1dSmckusick asll #2,d0 /* scale to long ptr */ 80*55510a1dSmckusick movl sp@(4),a0 /* save area pointer */ 81*55510a1dSmckusick addl d0,a0 /* &jmpbuf[_JBLEN] */ 82*55510a1dSmckusick tstl a0@ /* if jmpbuf[_JBLEN] */ 83*55510a1dSmckusick bne longjmp /* do longjmp */ 84*55510a1dSmckusick 85*55510a1dSmckusick_longjmp: 86*55510a1dSmckusick movl sp@(4),a0 /* save area pointer */ 87*55510a1dSmckusick addql #8,a0 /* skip onstack/sigmask */ 88*55510a1dSmckusick tstl a0@ /* ensure non-zero SP */ 89*55510a1dSmckusick jeq botch /* oops! */ 90*55510a1dSmckusick movl sp@(8),d0 /* grab return value */ 91*55510a1dSmckusick jne ok /* non-zero ok */ 92*55510a1dSmckusick moveq #1,d0 /* else make non-zero */ 93*55510a1dSmckusickok: 94*55510a1dSmckusick movl a0@+,sp /* restore SP */ 95*55510a1dSmckusick movl a0@+,a6 /* restore FP */ 96*55510a1dSmckusick addql #4,a0 /* skip AP */ 97*55510a1dSmckusick movl a0@+,sp@ /* restore PC */ 98*55510a1dSmckusick moveml a0@(4),#0x3CFC /* restore non-scratch regs */ 99*55510a1dSmckusick rts 100*55510a1dSmckusick 101*55510a1dSmckusicklongjmp: 102*55510a1dSmckusick movl sp@(4),a0 /* save area pointer */ 103*55510a1dSmckusick tstl a0@(8) /* ensure non-zero SP */ 104*55510a1dSmckusick jeq botch /* oops! */ 105*55510a1dSmckusick movl sp@(8),d0 /* grab return value */ 106*55510a1dSmckusick jne good /* non-zero good */ 107*55510a1dSmckusick moveq #1,d0 /* else make non-zero */ 108*55510a1dSmckusickgood: 109*55510a1dSmckusick moveml a0@(28),#0x3CFC /* restore non-scratch regs */ 110*55510a1dSmckusick movl a0,sp@- /* let sigreturn */ 111*55510a1dSmckusick jsr _sigreturn /* finish for us */ 112*55510a1dSmckusick 113*55510a1dSmckusickbotch: 114*55510a1dSmckusick jsr _longjmperror 115*55510a1dSmckusick stop #0 116