setjmp.S revision 1.20 1 1.20 riastrad /* $NetBSD: setjmp.S,v 1.20 2025/05/03 19:57:13 riastradh 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.15 matt mov 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.20 riastrad PCREL_GET(r2, .Lfpu_present, .LPIC0)
79 1.15 matt ldr r2, [r2]
80 1.15 matt #if defined(__thumb__) && defined(_ARM_ARCH_T2)
81 1.15 matt cbz r2, 1f /* don't save if we don't have a FPU */
82 1.12 matt #else
83 1.15 matt cmp r2, #0 /* do we have a FPU? */
84 1.15 matt beq 1f /* no, don't save VFP registers */
85 1.12 matt #endif
86 1.12 matt
87 1.15 matt orrs r1, r1, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
88 1.12 matt /* change magic to VFP magic */
89 1.15 matt adds r2, r0, #(_JB_REG_D8 * 4)
90 1.12 matt vstmia r2, {d8-d15}
91 1.12 matt vmrs r2, fpscr
92 1.12 matt str r2, [r0, #(_JB_REG_FPSCR * 4)]
93 1.12 matt 1:
94 1.15 matt #endif /* __ARM_EABI__ && (!__thumb__ || _ARM_ARCH_T2) */
95 1.12 matt
96 1.12 matt str r1, [r0] /* store magic */
97 1.1 bjh21
98 1.1 bjh21 /* Store integer registers */
99 1.15 matt adds r0, r0, #(_JB_REG_R4 * 4)
100 1.15 matt #if !defined(__thumb__)
101 1.15 matt stmia r0!, {r4-lr}
102 1.15 matt #else
103 1.15 matt stmia r0!, {r4-r7}
104 1.15 matt mov r2, r8
105 1.15 matt mov r3, r9
106 1.15 matt stmia r0!, {r2-r3}
107 1.15 matt mov r2, r10
108 1.15 matt mov r3, r11
109 1.15 matt stmia r0!, {r2-r3}
110 1.15 matt mov r2, sp
111 1.15 matt mov r3, lr
112 1.15 matt str r2, [r0, #4]
113 1.15 matt str r3, [r0, #8]
114 1.15 matt #endif
115 1.15 matt movs r0, #0
116 1.15 matt RET
117 1.1 bjh21
118 1.15 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2))
119 1.15 matt .align 0
120 1.12 matt .Lfpu_present:
121 1.20 riastrad .word PCREL_SYM(_libc_arm_fpu_present, .LPIC0)
122 1.15 matt #endif /* __ARM_EABI__ && (!__thumb__ || _ARM_ARCH_T2) */
123 1.15 matt END(__setjmp14)
124 1.1 bjh21
125 1.8 christos ENTRY(__longjmp14)
126 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
127 1.12 matt ldr r2, [r0]
128 1.12 matt ldr ip, .Lsetjmp_magic
129 1.12 matt bic r3, r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
130 1.15 matt #else
131 1.15 matt ldr r3, .Lsetjmp_magic
132 1.15 matt mov ip, r3
133 1.15 matt ldr r3, [r0]
134 1.15 matt movs r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
135 1.18 skrll bics r3, r2
136 1.15 matt /* r2 is not the magic but we don't need it since we can't do VFP */
137 1.15 matt #endif
138 1.15 matt cmp r3, ip
139 1.13 skrll bne .Lbotch
140 1.1 bjh21
141 1.19 skrll /* Validate sp and lr */
142 1.19 skrll ldr r2, [r0, #(_JB_REG_R13 * 4)]
143 1.19 skrll #if defined(__thumb__) && defined(_ARM_ARCH_T2)
144 1.19 skrll cbz r2, .Lbotch
145 1.19 skrll #else
146 1.19 skrll cmp r2, #0
147 1.19 skrll beq .Lbotch
148 1.19 skrll #endif
149 1.19 skrll
150 1.19 skrll ldr r3, [r0, #(_JB_REG_R14 * 4)]
151 1.19 skrll #if defined(__thumb__) && defined(_ARM_ARCH_T2)
152 1.19 skrll cbz r3, .Lbotch
153 1.19 skrll #else
154 1.19 skrll cmp r3, #0
155 1.19 skrll beq .Lbotch
156 1.19 skrll #endif
157 1.19 skrll mov sp, r2
158 1.19 skrll mov lr, r3
159 1.19 skrll
160 1.8 christos /* Restore the signal mask. */
161 1.15 matt push {r0-r2, lr}
162 1.15 matt movs r2, #0
163 1.15 matt #if !defined(__thumb__)
164 1.15 matt adds r1, r0, #(_JB_SIGMASK * 4)
165 1.15 matt #else
166 1.15 matt mov r1, r0
167 1.15 matt adds r1, r1, #(_JB_SIGMASK * 4)
168 1.15 matt #endif
169 1.15 matt movs r0, #3 /* SIG_SETMASK */
170 1.17 joerg bl PLT_SYM(_C_LABEL(__sigprocmask14))
171 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
172 1.15 matt pop {r0-r2, lr}
173 1.15 matt #else
174 1.15 matt pop {r0-r3}
175 1.15 matt mov lr, r3
176 1.15 matt #endif
177 1.1 bjh21
178 1.15 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2))
179 1.12 matt tst r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
180 1.12 matt /* is this a VFP magic? */
181 1.12 matt beq 1f /* no, don't restore VFP */
182 1.15 matt adds r2, r0, #(_JB_REG_D8 * 4)
183 1.15 matt vldmia r2, {d8-d15}
184 1.15 matt ldr r2, [r0, #(_JB_REG_FPSCR * 4)]
185 1.15 matt vmsr fpscr, r2
186 1.12 matt 1:
187 1.15 matt #endif /* __ARM_EABI__ && (!__thumb__ || _ARM_ARCH_T2) */
188 1.10 matt
189 1.15 matt adds r0, r0, #(_JB_REG_R4 * 4)
190 1.1 bjh21 /* Restore integer registers */
191 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
192 1.15 matt ldmia r0!, {r4-r12}
193 1.15 matt #else
194 1.15 matt ldmia r0!, {r4-r7}
195 1.15 matt ldmia r0!, {r2-r3}
196 1.15 matt mov r8, r2
197 1.15 matt mov r9, r3
198 1.15 matt ldmia r0!, {r2-r3}
199 1.15 matt mov r10, r2
200 1.15 matt mov r11, r3
201 1.15 matt adds r0, r0, #4 /* skip ip(r12) */
202 1.15 matt #endif
203 1.15 matt
204 1.1 bjh21 /* Set return value */
205 1.14 matt movs r0, r1
206 1.15 matt #if !defined(__thumb__)
207 1.15 matt moveq r0, #1
208 1.15 matt #else
209 1.15 matt bne 1f
210 1.15 matt movs r0, #1
211 1.15 matt 1:
212 1.15 matt #endif
213 1.6 rearnsha RET
214 1.1 bjh21
215 1.1 bjh21 /* validation failed, die die die. */
216 1.8 christos .Lbotch:
217 1.17 joerg bl PLT_SYM(_C_LABEL(longjmperror))
218 1.17 joerg bl PLT_SYM(_C_LABEL(abort))
219 1.15 matt 1: b 1b /* Cannot get here */
220 1.15 matt
221 1.15 matt .align 0
222 1.15 matt .Lsetjmp_magic:
223 1.15 matt .word _JB_MAGIC_SETJMP
224 1.15 matt END(__longjmp14)
225