setjmp.S revision 1.16 1 1.16 joerg /* $NetBSD: setjmp.S,v 1.16 2013/09/12 15:36:15 joerg 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.8 christos bl PIC_SYM(_C_LABEL(__sigprocmask14), PLT)
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.12 matt ldr r2, .Lfpu_present
79 1.16 joerg #ifdef __PIC__
80 1.15 matt add r2, r2, pc /* pc = &.LPIC0 */
81 1.15 matt #endif
82 1.15 matt ldr r2, [r2]
83 1.15 matt .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.15 matt .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.15 matt 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.8 christos /* Restore the signal mask. */
146 1.15 matt push {r0-r2, lr}
147 1.15 matt movs r2, #0
148 1.15 matt #if !defined(__thumb__)
149 1.15 matt adds r1, r0, #(_JB_SIGMASK * 4)
150 1.15 matt #else
151 1.15 matt mov r1, r0
152 1.15 matt adds r1, r1, #(_JB_SIGMASK * 4)
153 1.15 matt #endif
154 1.15 matt movs r0, #3 /* SIG_SETMASK */
155 1.8 christos bl PIC_SYM(_C_LABEL(__sigprocmask14), PLT)
156 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
157 1.15 matt pop {r0-r2, lr}
158 1.15 matt #else
159 1.15 matt pop {r0-r3}
160 1.15 matt mov lr, r3
161 1.15 matt #endif
162 1.1 bjh21
163 1.15 matt #if defined(__ARM_EABI__) && (!defined(__thumb__) || defined(_ARM_ARCH_T2))
164 1.12 matt tst r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
165 1.12 matt /* is this a VFP magic? */
166 1.12 matt beq 1f /* no, don't restore VFP */
167 1.15 matt adds r2, r0, #(_JB_REG_D8 * 4)
168 1.15 matt vldmia r2, {d8-d15}
169 1.15 matt ldr r2, [r0, #(_JB_REG_FPSCR * 4)]
170 1.15 matt vmsr fpscr, r2
171 1.12 matt 1:
172 1.15 matt #endif /* __ARM_EABI__ && (!__thumb__ || _ARM_ARCH_T2) */
173 1.10 matt
174 1.15 matt adds r0, r0, #(_JB_REG_R4 * 4)
175 1.1 bjh21 /* Restore integer registers */
176 1.15 matt #if !defined(__thumb__) || defined(_ARM_ARCH_T2)
177 1.15 matt ldmia r0!, {r4-r12}
178 1.15 matt #else
179 1.15 matt ldmia r0!, {r4-r7}
180 1.15 matt ldmia r0!, {r2-r3}
181 1.15 matt mov r8, r2
182 1.15 matt mov r9, r3
183 1.15 matt ldmia r0!, {r2-r3}
184 1.15 matt mov r10, r2
185 1.15 matt mov r11, r3
186 1.15 matt adds r0, r0, #4 /* skip ip(r12) */
187 1.15 matt #endif
188 1.15 matt
189 1.15 matt ldmia r0!, {r2-r3}
190 1.1 bjh21
191 1.15 matt /* Validate sp and lr */
192 1.15 matt #if defined(__thumb__) && defined(_ARM_ARCH_T2)
193 1.15 matt cbz r2, .Lbotch
194 1.15 matt #else
195 1.15 matt cmp r2, #0
196 1.8 christos beq .Lbotch
197 1.15 matt #endif
198 1.15 matt mov sp, r2
199 1.15 matt
200 1.15 matt #if defined(__thumb__) && defined(_ARM_ARCH_T2)
201 1.15 matt cbz r3, .Lbotch
202 1.15 matt #else
203 1.15 matt cmp r3, #0
204 1.15 matt beq .Lbotch
205 1.15 matt #endif
206 1.15 matt mov lr, r3
207 1.1 bjh21
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.2 matt bl PIC_SYM(_C_LABEL(longjmperror), PLT)
222 1.2 matt bl PIC_SYM(_C_LABEL(abort), PLT)
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