]>
Commit | Line | Data |
---|---|---|
f10eff58 | 1 | /* longjmp for ARM. |
d4697bc9 | 2 | Copyright (C) 1997-2014 Free Software Foundation, Inc. |
f10eff58 DJ |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
22423683 | 15 | You should have received a copy of the GNU Lesser General Public |
ab84e3ff PE |
16 | License along with the GNU C Library. If not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
f10eff58 DJ |
18 | |
19 | #include <sysdep.h> | |
f10eff58 | 20 | #include <bits/setjmp.h> |
f10eff58 | 21 | #include <rtld-global-offsets.h> |
2aa5b9c1 | 22 | #include <arm-features.h> |
f10eff58 DJ |
23 | |
24 | /* __longjmp(jmpbuf, val) */ | |
25 | ||
26 | ENTRY (__longjmp) | |
27 | mov ip, r0 | |
28 | movs r0, r1 /* get the return value in place */ | |
6d9b9a67 | 29 | it eq |
f10eff58 DJ |
30 | moveq r0, #1 /* can't let setjmp() return zero! */ |
31 | ||
ef889ffe | 32 | #ifdef CHECK_SP |
a7ac7522 RM |
33 | sfi_breg ip, \ |
34 | ldr r4, [\B, #32] /* jmpbuf's sp */ | |
01b32e73 | 35 | cfi_undefined (r4) |
b7f2d27d WN |
36 | #ifdef PTR_DEMANGLE |
37 | PTR_DEMANGLE (r4, r4, a3, a4) | |
38 | #endif | |
53df8bce | 39 | CHECK_SP (r4) |
ef889ffe | 40 | #endif |
1362a2aa | 41 | sfi_sp sfi_breg ip, \ |
a7ac7522 | 42 | ldmia \B!, JMP_BUF_REGLIST |
b7f2d27d | 43 | #ifdef PTR_DEMANGLE |
b7f2d27d | 44 | ldr a4, [ip], #4 |
2f10c4d6 | 45 | PTR_DEMANGLE (a4, a4, a3, a2) |
6d9b9a67 | 46 | mov sp, a4 |
b7f2d27d WN |
47 | ldr a4, [ip], #4 |
48 | PTR_DEMANGLE2 (lr, a4, a3) | |
49 | #else | |
b7f2d27d WN |
50 | ldr sp, [ip], #4 |
51 | ldr lr, [ip], #4 | |
52 | #endif | |
01b32e73 TS |
53 | cfi_restore (v1) |
54 | cfi_restore (v2) | |
55 | cfi_restore (v3) | |
56 | cfi_restore (v4) | |
57 | cfi_restore (v5) | |
58 | cfi_restore (v6) | |
59 | cfi_restore (sl) | |
60 | cfi_restore (fp) | |
61 | cfi_restore (sp) | |
62 | cfi_restore (lr) | |
f10eff58 | 63 | |
2aa5b9c1 RM |
64 | #if !defined ARM_ASSUME_NO_IWMMXT || defined __SOFTFP__ |
65 | # define NEED_HWCAP 1 | |
66 | #endif | |
67 | ||
68 | #ifdef NEED_HWCAP | |
69 | # ifdef IS_IN_rtld | |
6dcf80c7 RM |
70 | ldr a2, 1f |
71 | ldr a3, .Lrtld_local_ro | |
f10eff58 DJ |
72 | 0: add a2, pc, a2 |
73 | add a2, a2, a3 | |
74 | ldr a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] | |
2aa5b9c1 RM |
75 | # else |
76 | # ifdef PIC | |
6dcf80c7 RM |
77 | ldr a2, 1f |
78 | ldr a3, .Lrtld_global_ro | |
f10eff58 DJ |
79 | 0: add a2, pc, a2 |
80 | ldr a2, [a2, a3] | |
81 | ldr a2, [a2, #RTLD_GLOBAL_RO_DL_HWCAP_OFFSET] | |
2aa5b9c1 | 82 | # else |
6dcf80c7 | 83 | ldr a2, .Lhwcap |
f10eff58 | 84 | ldr a2, [a2, #0] |
2aa5b9c1 RM |
85 | # endif |
86 | # endif | |
f10eff58 DJ |
87 | #endif |
88 | ||
6dcf80c7 | 89 | #ifdef __SOFTFP__ |
4b860fb9 | 90 | tst a2, #HWCAP_ARM_VFP |
6dcf80c7 RM |
91 | beq .Lno_vfp |
92 | #endif | |
f10eff58 DJ |
93 | |
94 | /* Restore the VFP registers. */ | |
fbc4c20a | 95 | /* Following instruction is vldmia ip!, {d8-d15}. */ |
a7ac7522 RM |
96 | sfi_breg r12, \ |
97 | ldc p11, cr8, [\B], #64 | |
6dcf80c7 | 98 | .Lno_vfp: |
f10eff58 | 99 | |
2aa5b9c1 | 100 | #ifndef ARM_ASSUME_NO_IWMMXT |
4b860fb9 | 101 | tst a2, #HWCAP_ARM_IWMMXT |
6dcf80c7 | 102 | beq .Lno_iwmmxt |
4b860fb9 DJ |
103 | |
104 | /* Restore the call-preserved iWMMXt registers. */ | |
105 | /* Following instructions are wldrd wr10, [ip], #8 (etc.) */ | |
a7ac7522 RM |
106 | sfi_breg r12, \ |
107 | ldcl p1, cr10, [\B], #8 | |
108 | sfi_breg r12, \ | |
109 | ldcl p1, cr11, [\B], #8 | |
110 | sfi_breg r12, \ | |
111 | ldcl p1, cr12, [\B], #8 | |
112 | sfi_breg r12, \ | |
113 | ldcl p1, cr13, [\B], #8 | |
114 | sfi_breg r12, \ | |
115 | ldcl p1, cr14, [\B], #8 | |
116 | sfi_breg r12, \ | |
117 | ldcl p1, cr15, [\B], #8 | |
6dcf80c7 | 118 | .Lno_iwmmxt: |
2aa5b9c1 | 119 | #endif |
4b860fb9 | 120 | |
f10eff58 DJ |
121 | DO_RET(lr) |
122 | ||
2aa5b9c1 RM |
123 | #ifdef NEED_HWCAP |
124 | # ifdef IS_IN_rtld | |
783a65c2 | 125 | 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS |
6dcf80c7 | 126 | .Lrtld_local_ro: |
f10eff58 | 127 | .long C_SYMBOL_NAME(_rtld_local_ro)(GOTOFF) |
2aa5b9c1 RM |
128 | # else |
129 | # ifdef PIC | |
783a65c2 | 130 | 1: .long _GLOBAL_OFFSET_TABLE_ - 0b - PC_OFS |
6dcf80c7 | 131 | .Lrtld_global_ro: |
f10eff58 | 132 | .long C_SYMBOL_NAME(_rtld_global_ro)(GOT) |
2aa5b9c1 | 133 | # else |
6dcf80c7 | 134 | .Lhwcap: |
f10eff58 | 135 | .long C_SYMBOL_NAME(_dl_hwcap) |
2aa5b9c1 RM |
136 | # endif |
137 | # endif | |
f10eff58 DJ |
138 | #endif |
139 | ||
140 | END (__longjmp) |