diff options
author | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-02-06 18:50:27 +0000 |
---|---|---|
committer | Michael Shalayeff <mickey@cvs.openbsd.org> | 2002-02-06 18:50:27 +0000 |
commit | 6e2126d25c4e9b87c284f3ac3e5f68e6c71eeaf0 (patch) | |
tree | 2b0f6702bc3088f86860520e40adb9e1db040785 /lib/libc/arch/hppa | |
parent | 9f59a28f734b90ce467c2c68d567f5261449fc09 (diff) |
implement the setjmp/longjmp family, based on fredette@'s work
Diffstat (limited to 'lib/libc/arch/hppa')
-rw-r--r-- | lib/libc/arch/hppa/gen/Makefile.inc | 4 | ||||
-rw-r--r-- | lib/libc/arch/hppa/gen/setjmp.S | 202 | ||||
-rw-r--r-- | lib/libc/arch/hppa/gen/sigsetjmp.S | 21 |
3 files changed, 204 insertions, 23 deletions
diff --git a/lib/libc/arch/hppa/gen/Makefile.inc b/lib/libc/arch/hppa/gen/Makefile.inc index d483ab0495f..3ec21a4ee72 100644 --- a/lib/libc/arch/hppa/gen/Makefile.inc +++ b/lib/libc/arch/hppa/gen/Makefile.inc @@ -1,3 +1,3 @@ -# $OpenBSD: Makefile.inc,v 1.2 1999/09/14 00:21:15 mickey Exp $ +# $OpenBSD: Makefile.inc,v 1.3 2002/02/06 18:50:26 mickey Exp $ -SRCS+= isnan.c isinf.c infinity.c sigsetjmp.S +SRCS+= isnan.c isinf.c infinity.c setjmp.S diff --git a/lib/libc/arch/hppa/gen/setjmp.S b/lib/libc/arch/hppa/gen/setjmp.S new file mode 100644 index 00000000000..39b4358fa36 --- /dev/null +++ b/lib/libc/arch/hppa/gen/setjmp.S @@ -0,0 +1,202 @@ +/* $OpenBSD: setjmp.S,v 1.1 2002/02/06 18:50:26 mickey Exp $ */ + +/*- + * Copyright (c) 1990 The Regents of the University of California. + * All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * the Systems Programming Group of the University of Utah Computer + * Science Department. + * + * 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 the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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. + */ + +#include <machine/asm.h> +#define _LOCORE +#include <machine/frame.h> +#undef _LOCORE + +#if defined(LIBC_SCCS) && !defined(lint) + .text + .asciz "$OpenBSD: setjmp.S,v 1.1 2002/02/06 18:50:26 mickey Exp $" + .align 4 +#endif /* LIBC_SCCS and not lint */ + +/* + * C library -- setjmp, longjmp + * + * longjmp(a,v) + * will generate a "return(v)" from + * the last call to + * setjmp(a) + * by restoring registers from the stack, + * and a struct sigcontext, see <signal.h> + */ + +ENTRY(sigsetjmp, 64) + sub,= %r0, %arg1, %r0 + b _setjmp + + stw %arg1, 44(%arg0) ; last of reserved words + +ALTENTRY(setjmp) + stw %rp, HPPA_FRAME_CRP(%sp) + stw %arg0, HPPA_FRAME_ARG(0)(%sp) + + copy %r3, %r1 + copy %sp, %r3 + stwm %r1, HPPA_FRAME_SIZE(%sp) + + bl sigblock, %rp + copy %r0, %arg0 + + ldo HPPA_FRAME_SIZE(%r3),%sp + ldwm -HPPA_FRAME_SIZE(%sp),%r3 + ldw HPPA_FRAME_CRP(%sp), %rp + ldw HPPA_FRAME_ARG(0)(%sp), %arg0 + + stw %r0, 0(%arg0) ; no onstack + b _setjmp$dosaves + stw %ret0, 4(%arg0) ; mask + +ALTENTRY(_setjmp) + /* A sigcontext is at the beginning of our jmp_buf. */ + stw %r0, 0(%arg0) ; no onstack + stw %r0, 4(%arg0) ; mask +_setjmp$dosaves + stw %sp, 8(%arg0) ; sc.sc_sp = %sp + stw %r0, 12(%arg0) ; set sc.sc_ps + stw %r0, 16(%arg0) ; sc.sc_fp + ldo 4(%rp), %r1 + stw %rp, 20(%arg0) ; sc.sc_pcoqh = %rp + stw %r1, 24(%arg0) ; sc.sc_pcoqt = %rp + 4 + + /* We store all callee-saved registers after the sigcontext. */ + ldo 48(%arg0), %r1 ; offset to after sc + stwm %r3, 4(%r1) + stwm %r4, 4(%r1) + stwm %r5, 4(%r1) + stwm %r6, 4(%r1) + stwm %r7, 4(%r1) + stwm %r8, 4(%r1) + stwm %r9, 4(%r1) + stwm %r10, 4(%r1) + stwm %r11, 4(%r1) + stwm %r12, 4(%r1) + stwm %r13, 4(%r1) + stwm %r14, 4(%r1) + stwm %r15, 4(%r1) + stwm %r16, 4(%r1) + stwm %r17, 4(%r1) + stwm %r18, 4(%r1) + + /* Return 0. */ + bv %r0(%rp) + copy %r0, %ret0 +EXIT(_setjmp) + +ENTRY(siglongjmp,64) + /* XXX have to dup this from below */ + sub,<<= %sp, %arg0, %r0 /* botch if jbuf was on stack */ + bl,n longjmperror, %rp + nop + ldw 16(%arg0), %r1 /* botch if it's a real signal frame */ + add,= %r0, %r1, %r0 + bl,n longjmperror, %rp + nop + + ldw 44(%arg0), %arg2 + sub,= %r0, %arg2, %r0 + b _setjmp + +ALTENTRY(longjmp) + /* XXX have to dup this from below */ + sub,<<= %sp, %arg0, %r0 /* botch if jbuf was on stack */ + bl,n longjmperror, %rp + nop + ldw 16(%arg0), %r1 /* botch if it's a real signal frame */ + add,= %r0, %r1, %r0 + bl,n longjmperror, %rp + nop + + stw %rp, HPPA_FRAME_CRP(%sp) + stw %arg0, HPPA_FRAME_ARG(0)(%sp) + stw %arg1, HPPA_FRAME_ARG(1)(%sp) + + copy %r3, %r1 + copy %sp, %r3 + stwm %r1, HPPA_FRAME_SIZE(%sp) + + bl sigsetmask, %rp + ldw 4(%arg0), %arg0 + + ldo HPPA_FRAME_SIZE(%r3),%sp + ldwm -HPPA_FRAME_SIZE(%sp),%r3 + ldw HPPA_FRAME_CRP(%sp), %rp + ldw HPPA_FRAME_ARG(0)(%sp), %arg0 + b _longjmp$restores + ldw HPPA_FRAME_ARG(1)(%sp), %arg1 + +ALTENTRY(_longjmp) + sub,<<= %sp, %arg0, %r0 /* botch if jbuf was on stack */ + bl,n longjmperror, %rp + nop + ldw 16(%arg0), %r1 /* botch if it's a real signal frame */ + add,= %r0, %r1, %r0 + bl,n longjmperror, %rp + nop + +_longjmp$restores + /* restore callee-saved registers */ + ldo 48(%arg0), %r1 + ldwm 4(%r1), %r3 + ldwm 4(%r1), %r4 + ldwm 4(%r1), %r5 + ldwm 4(%r1), %r6 + ldwm 4(%r1), %r7 + ldwm 4(%r1), %r8 + ldwm 4(%r1), %r9 + ldwm 4(%r1), %r10 + ldwm 4(%r1), %r11 + ldwm 4(%r1), %r12 + ldwm 4(%r1), %r13 + ldwm 4(%r1), %r14 + ldwm 4(%r1), %r15 + ldwm 4(%r1), %r16 + ldwm 4(%r1), %r17 + ldwm 4(%r1), %r18 + + /* restore the rest */ + ldw 8(%arg0), %sp + ldw 20(%arg0), %rp /* check the priv level */ + bv %r0(%rp) + copy %arg1, %ret0 +EXIT(_longjmp) + + .end diff --git a/lib/libc/arch/hppa/gen/sigsetjmp.S b/lib/libc/arch/hppa/gen/sigsetjmp.S deleted file mode 100644 index 9a32480d449..00000000000 --- a/lib/libc/arch/hppa/gen/sigsetjmp.S +++ /dev/null @@ -1,21 +0,0 @@ -/* $OpenBSD: sigsetjmp.S,v 1.3 2001/06/04 23:14:01 mickey Exp $ */ - -#include "SYS.h" - -#ifdef SYSLIBC_SCCS - .text - .asciz "$OpenBSD: sigsetjmp.S,v 1.3 2001/06/04 23:14:01 mickey Exp $" - .align 4 -#endif - -ENTRY(sigsetjmp,0) - bv r0(rp) - nop -EXIT(sigsetjmp) - -ENTRY(siglongjmp,0) - bv r0(rp) - nop -EXIT(siglongjmp) - - .end |