setjmp.S revision 1.22 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