1*ef6a97f9Sguenther/* $OpenBSD: setjmp.S,v 1.8 2022/05/24 17:21:17 guenther Exp $ */ 2d987040fSdrahn/* $NetBSD: setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */ 3d987040fSdrahn 4d987040fSdrahn/* 5d987040fSdrahn * Copyright (c) 1997 Mark Brinicombe 6d987040fSdrahn * All rights reserved. 7d987040fSdrahn * 8d987040fSdrahn * Redistribution and use in source and binary forms, with or without 9d987040fSdrahn * modification, are permitted provided that the following conditions 10d987040fSdrahn * are met: 11d987040fSdrahn * 1. Redistributions of source code must retain the above copyright 12d987040fSdrahn * notice, this list of conditions and the following disclaimer. 13d987040fSdrahn * 2. Redistributions in binary form must reproduce the above copyright 14d987040fSdrahn * notice, this list of conditions and the following disclaimer in the 15d987040fSdrahn * documentation and/or other materials provided with the distribution. 16d987040fSdrahn * 3. All advertising materials mentioning features or use of this software 17d987040fSdrahn * must display the following acknowledgement: 18d987040fSdrahn * This product includes software developed by Mark Brinicombe 19d987040fSdrahn * 4. Neither the name of the University nor the names of its contributors 20d987040fSdrahn * may be used to endorse or promote products derived from this software 21d987040fSdrahn * without specific prior written permission. 22d987040fSdrahn * 23d987040fSdrahn * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 24d987040fSdrahn * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25d987040fSdrahn * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26d987040fSdrahn * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 27d987040fSdrahn * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28d987040fSdrahn * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29d987040fSdrahn * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30d987040fSdrahn * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31d987040fSdrahn * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32d987040fSdrahn * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33d987040fSdrahn * SUCH DAMAGE. 34d987040fSdrahn */ 35d987040fSdrahn 36b29bfccfSguenther#include "SYS.h" 37d987040fSdrahn#include <machine/setjmp.h> 38d987040fSdrahn 39b29bfccfSguenther .hidden __jmpxor 40b29bfccfSguenther 41d987040fSdrahn/* 42d987040fSdrahn * C library -- setjmp, longjmp 43d987040fSdrahn * 44d987040fSdrahn * longjmp(a,v) 45d987040fSdrahn * will generate a "return(v)" from the last call to 46d987040fSdrahn * setjmp(a) 47d987040fSdrahn * by restoring registers from the stack. 48d987040fSdrahn * The previous signal state is restored. 49d987040fSdrahn */ 50d987040fSdrahn 51d987040fSdrahnENTRY(setjmp) 52d987040fSdrahn /* Block all signals and retrieve the old signal mask */ 53b29bfccfSguenther mov r2, r0 54b29bfccfSguenther mov r1, #0x00000000 55b29bfccfSguenther mov r0, #0x00000001 /* SIG_BLOCK */ 56b29bfccfSguenther SYSTRAP(sigprocmask) 57d987040fSdrahn 58d987040fSdrahn /* Store signal mask */ 59552f7563Skettenis str r0, [r2, #(29 * 4)] 60d987040fSdrahn 61d987040fSdrahn ldr r1, .Lsetjmp_magic 62b29bfccfSguenther str r1, [r2], #4 63b29bfccfSguenther 64b29bfccfSguenther ldr r12, .L_jmpxor_setjmp 65b29bfccfSguenther1: add r12, pc, r12 /* r12 = &__jmpxor */ 66b29bfccfSguenther ldr r3, [r12], #4 /* r3 = __jmpxor[1] */ 67b29bfccfSguenther ldr r12, [r12] /* r12 = __jmpxor[0] */ 68b29bfccfSguenther eor r12, r13, r12 /* r12 = sp ^ __jmpxor[0] */ 69b29bfccfSguenther eor r3, lr, r3 /* r3 = lr ^ __jmpxor[1] */ 70d987040fSdrahn 71d987040fSdrahn#ifdef SOFTFLOAT 72552f7563Skettenis add r2, r2, #68 73d987040fSdrahn#else 74552f7563Skettenis /* Store fpcsr */ 75552f7563Skettenis vmrs r1, fpscr 76552f7563Skettenis str r1, [r2], #4 77d987040fSdrahn /* Store fp registers */ 78552f7563Skettenis vstmia r2!, {d8-d15} 79d987040fSdrahn#endif /* SOFTFLOAT */ 80d987040fSdrahn /* Store integer registers */ 81b29bfccfSguenther stmia r2, {r3-r12} 82b29bfccfSguenther 83d987040fSdrahn mov r0, #0x00000000 84b29bfccfSguenther mov r12, r0 /* overwrite __jmpxor copies */ 85b29bfccfSguenther mov r3, r0 86b29bfccfSguenther mov pc, lr 87d987040fSdrahn 88d987040fSdrahn.Lsetjmp_magic: 89d987040fSdrahn .word _JB_MAGIC_SETJMP 90b29bfccfSguenther.L_jmpxor_setjmp: 91b29bfccfSguenther .word __jmpxor - 1b 9238848718SguentherEND_STRONG(setjmp) 93d987040fSdrahn 94d987040fSdrahn 95d987040fSdrahnENTRY(longjmp) 96d987040fSdrahn ldr r2, .Lsetjmp_magic 97d987040fSdrahn ldr r3, [r0] 98d987040fSdrahn teq r2, r3 99*ef6a97f9Sguenther bne .Lbotch 100d987040fSdrahn 101b29bfccfSguenther /* Fetch signal mask and call sigprocmask */ 102b29bfccfSguenther mov r3, r0 /* r3 = jmpbuf */ 103b29bfccfSguenther mov r2, r1 /* r2 = retvalue */ 104552f7563Skettenis ldr r1, [r0, #(29 * 4)] 105b29bfccfSguenther mov r0, #0x00000003 /* SIG_SETMASK */ 106b29bfccfSguenther SYSTRAP(sigprocmask) 107d987040fSdrahn 108b29bfccfSguenther add r3, r3, #4 109d987040fSdrahn#ifdef SOFTFLOAT 110552f7563Skettenis add r3, r3, #68 111d987040fSdrahn#else 112552f7563Skettenis /* Restore fpcsr */ 113552f7563Skettenis ldr r4, [r3], #4 114552f7563Skettenis vmsr fpscr, r4 115d987040fSdrahn /* Restore fp registers */ 116552f7563Skettenis vldmia r3!, {d8-d15} 117d987040fSdrahn#endif /* SOFTFLOAT */ 118d987040fSdrahn /* Restore integer registers */ 119b29bfccfSguenther ldmia r3, {r3-r12} 120d987040fSdrahn 121b29bfccfSguenther ldr r0, .L_jmpxor_longjmp 122b29bfccfSguenther1: add r0, pc, r0 /* r0 = &__jmpxor */ 123b29bfccfSguenther ldr lr, [r0], #4 /* lr = __jmpxor[1] */ 124b29bfccfSguenther eor lr, r3, lr /* lr ^= jmpbuf[LR] */ 125b29bfccfSguenther ldr r0, [r0] /* r0 = __jmpxor[0] */ 126b29bfccfSguenther eor r13, r0, r12 /* sp = __jmpxor[0] ^ jmpbuf[SP] */ 127b29bfccfSguenther mov r12, r2 /* overwrite __jmpxor copies */ 128b29bfccfSguenther mov r3, r2 129b29bfccfSguenther 130b29bfccfSguenther /* Validate sp and lr */ 131d987040fSdrahn teq sp, #0 132b29bfccfSguenther teqne lr, #0 133*ef6a97f9Sguenther beq .Lbotch 134d987040fSdrahn 135d987040fSdrahn /* Set return value */ 136b29bfccfSguenther mov r0, r12 137d987040fSdrahn teq r0, #0x00000000 138d987040fSdrahn moveq r0, #0x00000001 139b29bfccfSguenther mov pc, lr 140b29bfccfSguenther 141b29bfccfSguenther.L_jmpxor_longjmp: 142b29bfccfSguenther .word __jmpxor - 1b 143d987040fSdrahn 144d987040fSdrahn /* validation failed, die die die. */ 145*ef6a97f9Sguenther.Lbotch: 14638848718Sguenther bl _HIDDEN(abort) 147d987040fSdrahn b . - 8 /* Cannot get here */ 14838848718SguentherEND_STRONG(longjmp) 149