1 1.20 uwe /* $NetBSD: _setjmp.S,v 1.20 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.9 matt #if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS) 36 1.8 matt #error FPA is not supported anymore 37 1.8 matt #endif 38 1.8 matt 39 1.13 matt #if defined(__ARM_EABI__) && !defined(__ARM_PCS_VFP) 40 1.10 matt .fpu vfp 41 1.10 matt #endif 42 1.10 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 NOT restored. 54 1.1 bjh21 * 55 1.1 bjh21 * Note: r0 is the return value 56 1.10 matt * r1-r3,ip are scratch registers in functions 57 1.1 bjh21 */ 58 1.1 bjh21 59 1.1 bjh21 ENTRY(_setjmp) 60 1.4 thorpej ldr r1, .L_setjmp_magic 61 1.10 matt 62 1.13 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2)) 63 1.19 uwe ldr r2, .Lfpu_present 64 1.19 uwe #ifdef __PIC__ 65 1.19 uwe add r2, r2, pc /* pc = &.LPIC0 */ 66 1.19 uwe #endif 67 1.13 matt ldr r2, [r2] 68 1.19 uwe .LPIC0: 69 1.13 matt #if defined(__thumb__) && defined(_ARM_ARCH_T2) 70 1.13 matt cbz r2, 1f 71 1.10 matt #else 72 1.13 matt cmp r2, #0 /* do we have a FPU? */ 73 1.13 matt beq 1f /* no, don't save VFP registers */ 74 1.10 matt #endif 75 1.10 matt 76 1.13 matt orrs r1, r1, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) 77 1.10 matt /* change magic to VFP magic */ 78 1.13 matt adds r2, r0, #(_JB_REG_D8 * 4) 79 1.10 matt vstmia r2, {d8-d15} 80 1.10 matt vmrs r2, fpscr 81 1.10 matt str r2, [r0, #(_JB_REG_FPSCR * 4)] 82 1.10 matt 1: 83 1.13 matt #endif /* __ARM_EABI__ && (_ARM_ARCH_T2 || !__thumb__) */ 84 1.10 matt 85 1.8 matt str r1, [r0] 86 1.8 matt 87 1.13 matt adds r0, r0, #(_JB_REG_R4 * 4) 88 1.1 bjh21 /* Store integer registers */ 89 1.13 matt #if !defined(__thumb__) || defined(_ARCH_ARCH_T2) 90 1.17 skrll stmia r0, {r4-r14} 91 1.13 matt #else 92 1.17 skrll stmia r0!, {r4-r7} 93 1.13 matt mov r1, r8 94 1.13 matt mov r2, r9 95 1.13 matt mov r3, r10 96 1.13 matt stmia r0!, {r1-r3} 97 1.13 matt mov r2, r11 98 1.13 matt mov r3, r12 99 1.13 matt stmia r0!, {r2-r3} 100 1.13 matt mov r2, sp 101 1.13 matt mov r3, lr 102 1.13 matt stmia r0!, {r2-r3} 103 1.13 matt #endif 104 1.1 bjh21 105 1.17 skrll movs r0, #0 106 1.17 skrll RET 107 1.1 bjh21 108 1.13 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2)) 109 1.13 matt .align 0 110 1.10 matt .Lfpu_present: 111 1.19 uwe .word REL_SYM(_libc_arm_fpu_present, .LPIC0) 112 1.13 matt #endif /* __ARM_EABI__ && (_ARM_ARCH_T2 || !__thumb__) */ 113 1.13 matt END(_setjmp) 114 1.1 bjh21 115 1.1 bjh21 ENTRY(_longjmp) 116 1.10 matt ldr r2, [r0] /* get magic from jmp_buf */ 117 1.13 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2) 118 1.13 matt bics r3, r2, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) 119 1.10 matt /* ignore VFP-ness of magic */ 120 1.10 matt ldr ip, .L_setjmp_magic /* load magic */ 121 1.13 matt #else 122 1.13 matt ldr r3, .L_setjmp_magic /* load magic */ 123 1.13 matt mov ip, r3 124 1.13 matt movs r3, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) 125 1.13 matt ands r3, r3, r2 126 1.13 matt eors r3, r3, r2 /* ignore VFP-ness of magic */ 127 1.13 matt #endif 128 1.13 matt cmp ip, r3 /* magic correct? */ 129 1.10 matt bne botch /* no, botch */ 130 1.10 matt 131 1.13 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2)) 132 1.13 matt cmp r3, r2 /* did magic change? */ 133 1.10 matt beq 1f /* no, don't restore VFP */ 134 1.13 matt adds r3, r0, #(_JB_REG_D8 * 4) 135 1.13 matt vldmia r3, {d8-d15} 136 1.13 matt ldr r3, [r0, #(_JB_REG_FPSCR * 4)] 137 1.13 matt vmsr fpscr, r3 138 1.15 skrll 1: 139 1.13 matt #endif /* __ARM_EABI__ && (_ARM_ARCH_T2 || !__thumb__) */ 140 1.8 matt 141 1.13 matt adds r0, r0, #(_JB_REG_R4 * 4) 142 1.17 skrll /* Restore integer registers */ 143 1.13 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2) 144 1.17 skrll ldmia r0!, {r4-r12} 145 1.13 matt #else 146 1.13 matt ldmia r0!, {r4-r7} 147 1.13 matt ldmia r0!, {r2-r3} 148 1.13 matt mov r8, r2 149 1.13 matt mov r9, r3 150 1.13 matt ldmia r0!, {r2-r3} 151 1.13 matt mov r10, r2 152 1.20 uwe movs r1, r3 153 1.13 matt adds r0, r0, #4 /* skip r12 */ 154 1.13 matt #endif 155 1.13 matt ldmia r0!, {r2-r3} /* r2 = sp, r3 = lr */ 156 1.1 bjh21 157 1.3 chris /* Validate sp and r14 */ 158 1.13 matt #if defined(__thumb__) && defined(_ARM_ARCH_T2) 159 1.13 matt cbz r2, botch 160 1.13 matt #else 161 1.13 matt cmp r2, #0 162 1.1 bjh21 beq botch 163 1.13 matt #endif 164 1.13 matt mov sp, r2 165 1.13 matt 166 1.13 matt #if defined(__thumb__) && defined(_ARM_ARCH_T2) 167 1.13 matt cbz r3, botch 168 1.13 matt #else 169 1.13 matt cmp r3, #0 170 1.13 matt beq botch 171 1.13 matt #endif 172 1.13 matt mov lr, r3 173 1.1 bjh21 174 1.1 bjh21 /* Set return value */ 175 1.12 matt movs r0, r1 176 1.13 matt #ifdef __thumb__ 177 1.13 matt bne 1f 178 1.13 matt movs r0, #1 179 1.13 matt 1: 180 1.13 matt #else 181 1.13 matt moveq r0, #1 182 1.13 matt #endif 183 1.6 rearnsha RET 184 1.1 bjh21 185 1.1 bjh21 /* validation failed, die die die. */ 186 1.1 bjh21 botch: 187 1.16 joerg bl PLT_SYM(_C_LABEL(longjmperror)) 188 1.16 joerg bl PLT_SYM(_C_LABEL(abort)) 189 1.13 matt 1: b 1b /* Cannot get here */ 190 1.13 matt 191 1.13 matt .align 0 192 1.13 matt .L_setjmp_magic: 193 1.13 matt .word _JB_MAGIC__SETJMP 194 1.13 matt END(_longjmp) 195