1 1.22 uwe /* $NetBSD: setjmp.S,v 1.22 2025/05/08 00:28:31 uwe Exp $ */ 2 1.1 bjh21 3 1.1 bjh21 /* 4 1.1 bjh21 * Copyright (c) 1997 Mark Brinicombe 5 1.1 bjh21 * All rights reserved. 6 1.1 bjh21 * 7 1.1 bjh21 * Redistribution and use in source and binary forms, with or without 8 1.1 bjh21 * modification, are permitted provided that the following conditions 9 1.1 bjh21 * are met: 10 1.1 bjh21 * 1. Redistributions of source code must retain the above copyright 11 1.1 bjh21 * notice, this list of conditions and the following disclaimer. 12 1.1 bjh21 * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 bjh21 * notice, this list of conditions and the following disclaimer in the 14 1.1 bjh21 * documentation and/or other materials provided with the distribution. 15 1.1 bjh21 * 3. All advertising materials mentioning features or use of this software 16 1.1 bjh21 * must display the following acknowledgement: 17 1.1 bjh21 * This product includes software developed by Mark Brinicombe 18 1.1 bjh21 * 4. Neither the name of the University nor the names of its contributors 19 1.1 bjh21 * may be used to endorse or promote products derived from this software 20 1.1 bjh21 * without specific prior written permission. 21 1.1 bjh21 * 22 1.1 bjh21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 1.1 bjh21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 1.1 bjh21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 1.1 bjh21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 1.1 bjh21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 1.1 bjh21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 1.1 bjh21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 1.1 bjh21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 1.1 bjh21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 1.1 bjh21 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 1.1 bjh21 * SUCH DAMAGE. 33 1.1 bjh21 */ 34 1.1 bjh21 35 1.11 matt #if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS) 36 1.10 matt #error FPA is not supported anymore 37 1.10 matt #endif 38 1.10 matt 39 1.15 matt #if defined(__ARM_EABI__) && !defined(__ARM_PCS_VFP) 40 1.12 matt .fpu vfp 41 1.12 matt #endif 42 1.12 matt 43 1.1 bjh21 #include <machine/asm.h> 44 1.1 bjh21 #include <machine/setjmp.h> 45 1.1 bjh21 46 1.1 bjh21 /* 47 1.1 bjh21 * C library -- setjmp, longjmp 48 1.1 bjh21 * 49 1.1 bjh21 * longjmp(a,v) 50 1.1 bjh21 * will generate a "return(v)" from the last call to 51 1.1 bjh21 * setjmp(a) 52 1.1 bjh21 * by restoring registers from the stack. 53 1.1 bjh21 * The previous signal state is restored. 54 1.1 bjh21 */ 55 1.1 bjh21 56 1.8 christos ENTRY(__setjmp14) 57 1.8 christos /* Get the signal mask. */ 58 1.15 matt push {r0-r2, lr} 59 1.15 matt #if !defined(__thumb__) 60 1.15 matt adds r2, r0, #(_JB_SIGMASK * 4) 61 1.15 matt #else 62 1.22 uwe movs r2, r0 63 1.15 matt adds r2, r2, #(_JB_SIGMASK * 4) 64 1.15 matt #endif 65 1.15 matt movs r1, #0 66 1.15 matt movs r0, #0 67 1.17 joerg bl PLT_SYM(_C_LABEL(__sigprocmask14)) 68 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2) 69 1.15 matt pop {r0-r2, lr} 70 1.15 matt #else 71 1.15 matt pop {r0-r3} 72 1.15 matt mov lr, r3 73 1.15 matt #endif 74 1.1 bjh21 75 1.4 thorpej ldr r1, .Lsetjmp_magic 76 1.10 matt 77 1.15 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2)) 78 1.21 uwe ldr r2, .Lfpu_present 79 1.21 uwe #ifdef __PIC__ 80 1.21 uwe add r2, r2, pc /* pc = &.LPIC0 */ 81 1.21 uwe #endif 82 1.15 matt ldr r2, [r2] 83 1.21 uwe .LPIC0: 84 1.15 matt #if defined(__thumb__) && defined(_ARM_ARCH_T2) 85 1.15 matt cbz r2, 1f /* don't save if we don't have a FPU */ 86 1.12 matt #else 87 1.15 matt cmp r2, #0 /* do we have a FPU? */ 88 1.15 matt beq 1f /* no, don't save VFP registers */ 89 1.12 matt #endif 90 1.12 matt 91 1.15 matt orrs r1, r1, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP) 92 1.12 matt /* change magic to VFP magic */ 93 1.15 matt adds r2, r0, #(_JB_REG_D8 * 4) 94 1.12 matt vstmia r2, {d8-d15} 95 1.12 matt vmrs r2, fpscr 96 1.12 matt str r2, [r0, #(_JB_REG_FPSCR * 4)] 97 1.12 matt 1: 98 1.15 matt #endif /* __ARM_EABI__ && (!__thumb__ || _ARM_ARCH_T2) */ 99 1.12 matt 100 1.12 matt str r1, [r0] /* store magic */ 101 1.1 bjh21 102 1.1 bjh21 /* Store integer registers */ 103 1.15 matt adds r0, r0, #(_JB_REG_R4 * 4) 104 1.15 matt #if !defined(__thumb__) 105 1.15 matt stmia r0!, {r4-lr} 106 1.15 matt #else 107 1.15 matt stmia r0!, {r4-r7} 108 1.15 matt mov r2, r8 109 1.15 matt mov r3, r9 110 1.15 matt stmia r0!, {r2-r3} 111 1.15 matt mov r2, r10 112 1.15 matt mov r3, r11 113 1.15 matt stmia r0!, {r2-r3} 114 1.15 matt mov r2, sp 115 1.15 matt mov r3, lr 116 1.15 matt str r2, [r0, #4] 117 1.15 matt str r3, [r0, #8] 118 1.15 matt #endif 119 1.15 matt movs r0, #0 120 1.15 matt RET 121 1.1 bjh21 122 1.15 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2)) 123 1.15 matt .align 0 124 1.12 matt .Lfpu_present: 125 1.21 uwe .word REL_SYM(_libc_arm_fpu_present, .LPIC0) 126 1.15 matt #endif /* __ARM_EABI__ && (!__thumb__ || _ARM_ARCH_T2) */ 127 1.15 matt END(__setjmp14) 128 1.1 bjh21 129 1.8 christos ENTRY(__longjmp14) 130 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2) 131 1.12 matt ldr r2, [r0] 132 1.12 matt ldr ip, .Lsetjmp_magic 133 1.12 matt bic r3, r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP) 134 1.15 matt #else 135 1.15 matt ldr r3, .Lsetjmp_magic 136 1.15 matt mov ip, r3 137 1.15 matt ldr r3, [r0] 138 1.15 matt movs r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP) 139 1.18 skrll bics r3, r2 140 1.15 matt /* r2 is not the magic but we don't need it since we can't do VFP */ 141 1.15 matt #endif 142 1.15 matt cmp r3, ip 143 1.13 skrll bne .Lbotch 144 1.1 bjh21 145 1.19 skrll /* Validate sp and lr */ 146 1.19 skrll ldr r2, [r0, #(_JB_REG_R13 * 4)] 147 1.19 skrll #if defined(__thumb__) && defined(_ARM_ARCH_T2) 148 1.19 skrll cbz r2, .Lbotch 149 1.19 skrll #else 150 1.19 skrll cmp r2, #0 151 1.19 skrll beq .Lbotch 152 1.19 skrll #endif 153 1.19 skrll 154 1.19 skrll ldr r3, [r0, #(_JB_REG_R14 * 4)] 155 1.19 skrll #if defined(__thumb__) && defined(_ARM_ARCH_T2) 156 1.19 skrll cbz r3, .Lbotch 157 1.19 skrll #else 158 1.19 skrll cmp r3, #0 159 1.19 skrll beq .Lbotch 160 1.19 skrll #endif 161 1.19 skrll mov sp, r2 162 1.19 skrll mov lr, r3 163 1.19 skrll 164 1.8 christos /* Restore the signal mask. */ 165 1.15 matt push {r0-r2, lr} 166 1.15 matt movs r2, #0 167 1.15 matt #if !defined(__thumb__) 168 1.15 matt adds r1, r0, #(_JB_SIGMASK * 4) 169 1.15 matt #else 170 1.22 uwe movs r1, r0 171 1.15 matt adds r1, r1, #(_JB_SIGMASK * 4) 172 1.15 matt #endif 173 1.15 matt movs r0, #3 /* SIG_SETMASK */ 174 1.17 joerg bl PLT_SYM(_C_LABEL(__sigprocmask14)) 175 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2) 176 1.15 matt pop {r0-r2, lr} 177 1.15 matt #else 178 1.15 matt pop {r0-r3} 179 1.15 matt mov lr, r3 180 1.15 matt #endif 181 1.1 bjh21 182 1.15 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2)) 183 1.12 matt tst r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP) 184 1.12 matt /* is this a VFP magic? */ 185 1.12 matt beq 1f /* no, don't restore VFP */ 186 1.15 matt adds r2, r0, #(_JB_REG_D8 * 4) 187 1.15 matt vldmia r2, {d8-d15} 188 1.15 matt ldr r2, [r0, #(_JB_REG_FPSCR * 4)] 189 1.15 matt vmsr fpscr, r2 190 1.12 matt 1: 191 1.15 matt #endif /* __ARM_EABI__ && (!__thumb__ || _ARM_ARCH_T2) */ 192 1.10 matt 193 1.15 matt adds r0, r0, #(_JB_REG_R4 * 4) 194 1.1 bjh21 /* Restore integer registers */ 195 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2) 196 1.15 matt ldmia r0!, {r4-r12} 197 1.15 matt #else 198 1.15 matt ldmia r0!, {r4-r7} 199 1.15 matt ldmia r0!, {r2-r3} 200 1.15 matt mov r8, r2 201 1.15 matt mov r9, r3 202 1.15 matt ldmia r0!, {r2-r3} 203 1.15 matt mov r10, r2 204 1.15 matt mov r11, r3 205 1.15 matt adds r0, r0, #4 /* skip ip(r12) */ 206 1.15 matt #endif 207 1.15 matt 208 1.1 bjh21 /* Set return value */ 209 1.14 matt movs r0, r1 210 1.15 matt #if !defined(__thumb__) 211 1.15 matt moveq r0, #1 212 1.15 matt #else 213 1.15 matt bne 1f 214 1.15 matt movs r0, #1 215 1.15 matt 1: 216 1.15 matt #endif 217 1.6 rearnsha RET 218 1.1 bjh21 219 1.1 bjh21 /* validation failed, die die die. */ 220 1.8 christos .Lbotch: 221 1.17 joerg bl PLT_SYM(_C_LABEL(longjmperror)) 222 1.17 joerg bl PLT_SYM(_C_LABEL(abort)) 223 1.15 matt 1: b 1b /* Cannot get here */ 224 1.15 matt 225 1.15 matt .align 0 226 1.15 matt .Lsetjmp_magic: 227 1.15 matt .word _JB_MAGIC_SETJMP 228 1.15 matt END(__longjmp14) 229