summaryrefslogtreecommitdiff
path: root/lib/libc/arch/m88k/gen/sigsetjmp.S
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/arch/m88k/gen/sigsetjmp.S')
-rw-r--r--lib/libc/arch/m88k/gen/sigsetjmp.S144
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 */
+