diff options
Diffstat (limited to 'lib/libc/arch/m88k/gen/sigsetjmp.S')
-rw-r--r-- | lib/libc/arch/m88k/gen/sigsetjmp.S | 144 |
1 files changed, 123 insertions, 21 deletions
diff --git a/lib/libc/arch/m88k/gen/sigsetjmp.S b/lib/libc/arch/m88k/gen/sigsetjmp.S index 44637c0c25a..f3c8b1161fd 100644 --- a/lib/libc/arch/m88k/gen/sigsetjmp.S +++ b/lib/libc/arch/m88k/gen/sigsetjmp.S @@ -1,11 +1,69 @@ +/*- + * Copyright (c) 2002 Steve Murphree, Jr. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Steve Murphree, Jr. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) + .text + .string "$OpenBSD: sigsetjmp.S,v 1.2 2002/09/18 05:03:54 smurph Exp $\0" +#endif /* LIBC_SCCS */ + #include "SYS.h" /* - * Need to write sigsetjmp version. But for now, - * I am copying setjmp XXX nivas + * C library -- sigsetjmp, siglongjmp + * + * siglongjmp(a,v) + * will generate a "return(v)" from + * the last call to + * sigsetjmp(a,m) + * by restoring registers from the stack, + * The previous signal state is restored if 'm' was non-zero. + * + * For m88k, we define our jmp_buf length + * to be the size of 22 longs. <machine/setjmp.h> + * The buffer's usage is as follows: + * + * jmp_buf[0] return address + * jmp_buf[1] signal set (if used) + * jmp_buf[2 to 19] r14 to r31 + * jmp_buf[20] 'used' flag + * jmp_buf[21] setjmp type + * + */ + +#include <machine/setjmp.h> + +/* +int sigsetjmp(jmp_buf env, int savemask); */ ENTRY(sigsetjmp) - st r1, r2,0 + st r1, r2,0 /* save registers to the environment buffer */ st r14,r2,8 st r15,r2,12 st r16,r2,16 @@ -24,17 +82,41 @@ ENTRY(sigsetjmp) st r29,r2,68 st r30,r2,72 st r31,r2,76 - or r15,r1,0 /* can use r15 */ - or r14,r2,0 /* can use r14 as it is already saved */ - bsr.n _sigblock - or r2,r0,0 - st r2,r14,4 - jmp.n r15 + st r0,r2,80 /* mark environment as NOT returned (0x0) */ + or r4,r0,0 /* clear r4 */ + or r4,r0,SETJMP_TYPE3 /* r4 now contains setjmp type */ + st r4,r2,84 /* setjmp type to _setjmp */ + + or r15,r1,0 /* store return address in r15 */ + or r14,r2,0 /* store address of env in r14 */ + or r13,r3,0 /* store savemask in r13 */ + + cmp r11,r13,0x0 /* see if sigmask == 0 */ + bb1.n eq,r1,1f /* skip sig stuff */ + st r0,r14,4 /* but save 0 set in offset 4 of env first */ + + bsr.n _C_LABEL(sigblock) /* r2 = sigblock(savemask) */ + or r2,r0,r13 + st r2,r14,4 /* save signal set in offset 4 of env */ +1: + jmp.n r15 /* return 0 */ or r2,r0,0 +/* +void siglongjmp(sigjmp_buf env, int val); + */ ENTRY(siglongjmp) - subu r31,r31,32 /* get some temporary stack */ - ld r14,r2,8 + cpm r4,r2,0x0 /* check for bad envnvironment buffer address. */ + bb1 eq,r4,3f /* if == 0, abort. */ + ld r4,r2,80 /* check if environment buffer has */ + cpm r4,r4,0x0 /* already returned. */ + bb1 ne,r4,3f /* if != 0, abort. */ + ld r4,r2,84 /* check setjmp type. */ + cpm r4,r4,SETJMP_TYPE3 /* should be SETJMP_TYPE3 */ + bb1 ne,r4,3f /* if != SETJMP_TYPE3, abort. */ + + subu r31,r31,32 /* get a temporary stack */ + ld r14,r2,8 /* restore registers from the environment buffer */ ld r15,r2,12 ld r16,r2,16 ld r17,r2,20 @@ -50,15 +132,35 @@ ENTRY(siglongjmp) ld r27,r2,60 ld r28,r2,64 ld r29,r2,68 + + ld r4,r2,4 /* get the sinal set from env */ + cpm r4,r4,0x0 /* if r2 == 0 then skip signal stuff */ + bb1 eq,r4,1f - st r2,r31,24 /* save r2 on stack */ - st r3,r31,28 /* save r3 on stack */ - bsr.n _sigsetmask + st r2,r31,24 /* save r2 on stack (environment) */ + st r3,r31,28 /* save r3 on stack (return val) */ + bsr.n _C_LABEL(sigsetmask) /* restore the signal set */ ld r2,r2,4 - ld r2,r31,24 /* restore r2 from stack */ - ld r3,r31,28 /* restore r3 from stack */ - ld r30,r2,72 /* restore r30 */ - ld r31,r2,76 /* restore r31 */ - ld r1,r2,0 /* restore r1 */ - jmp.n r1 /* and jump to it */ - or r2,r0,r3 /* but first return r3 value */ + ld r2,r31,24 /* restore r2 from stack */ + ld r3,r31,28 /* restore r3 from stack */ +1: + ld r30,r2,72 /* restore r30 */ + ld r31,r2,76 /* restore r31 (sp)*/ + or r4,r0,1 + st r4,r2,80 /* mark environment buffer as returned */ + ld r1,r2,0 /* restore r1 */ + cmp r2,r3,0 /* test retval for 0 */ + bb0 eq,r2,2f /* if != 0, it's ok. */ + jmp.n r1 /* and jump to it */ + or r2,r0,r3 /* but first return r3 value */ +2: jmp.n r1 + or r2,r0,1 /* return non-zero value. */ +3: + subu r31,r31,32 /* get a temporary stack */ + st r1,r31,20 /* save r1 on stack (return address) */ + bsr _C_LABEL(longjmperror) + bsr _C_LABEL(abort) /* NO RETURN */ + ld r1,r31,20 /* restore r1 from stack */ + addu r31,r31,32 /* restore the stack */ + jmp r1 /* this should not happen but we are prepared */ + |