]>
Commit | Line | Data |
---|---|---|
c50ce9a4 | 1 | /* Jump to a new context powerpc32 common. |
568035b7 | 2 | Copyright (C) 2005-2013 Free Software Foundation, Inc. |
c50ce9a4 UD |
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 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
c50ce9a4 UD |
18 | |
19 | /* This is the common implementation of setcontext for powerpc32. | |
b7219e53 | 20 | It not complete in itself should be included in to a framework that |
c50ce9a4 UD |
21 | defines: |
22 | __CONTEXT_FUNC_NAME | |
23 | and if appropriate: | |
24 | __CONTEXT_ENABLE_FPRS | |
25 | __CONTEXT_ENABLE_VRS | |
6f65e668 | 26 | Any architecture that implements the Vector unit is assumed to also |
c50ce9a4 UD |
27 | implement the floating unit. */ |
28 | ||
29 | /* Stack frame offsets. */ | |
30 | #define _FRAME_BACKCHAIN 0 | |
31 | #define _FRAME_LR_SAVE 4 | |
32 | #define _FRAME_PARM_SAVE1 8 | |
33 | #define _FRAME_PARM_SAVE2 12 | |
34 | #define _FRAME_PARM_SAVE3 16 | |
35 | #define _FRAME_PARM_SAVE4 20 | |
36 | ||
37 | #ifdef __CONTEXT_ENABLE_VRS | |
38 | .machine "altivec" | |
39 | #endif | |
40 | ENTRY(__CONTEXT_FUNC_NAME) | |
41 | mflr r0 | |
42 | stwu r1,-16(r1) | |
a7e91561 | 43 | cfi_adjust_cfa_offset (16) |
c50ce9a4 | 44 | stw r0,20(r1) |
a7e91561 | 45 | cfi_offset (lr, _FRAME_LR_SAVE) |
c50ce9a4 | 46 | stw r31,12(r1) |
3e7e947f | 47 | cfi_offset(r31,-4) |
c50ce9a4 UD |
48 | lwz r31,_UC_REGS_PTR(r3) |
49 | ||
50 | /* | |
51 | * If this ucontext refers to the point where we were interrupted | |
52 | * by a signal, we have to use the rt_sigreturn system call to | |
53 | * return to the context so we get both LR and CTR restored. | |
54 | * | |
55 | * Otherwise, the context we are restoring is either just after | |
56 | * a procedure call (getcontext/swapcontext) or at the beginning | |
57 | * of a procedure call (makecontext), so we don't need to restore | |
58 | * r0, xer, ctr. We don't restore r2 since it will be used as | |
59 | * the TLS pointer. | |
60 | */ | |
61 | lwz r0,_UC_GREGS+(PT_MSR*4)(r31) | |
62 | cmpwi r0,0 | |
63 | bne 4f /* L(do_sigret) */ | |
64 | ||
65 | /* Restore the signal mask */ | |
66 | li r5,0 | |
67 | addi r4,r3,_UC_SIGMASK | |
68 | li r3,SIG_SETMASK | |
69 | bl __sigprocmask@local | |
70 | cmpwi r3,0 | |
71 | bne 3f /* L(error_exit) */ | |
72 | ||
edba7a54 | 73 | #ifdef PIC |
c50ce9a4 | 74 | mflr r8 |
929d11c7 | 75 | # define got_label GENERATE_GOT_LABEL (__CONTEXT_FUNC_NAME) |
91d2a845 WS |
76 | SETUP_GOT_ACCESS(r7,got_label) |
77 | addis r7,r7,_GLOBAL_OFFSET_TABLE_-got_label@ha | |
78 | addi r7,r7,_GLOBAL_OFFSET_TABLE_-got_label@l | |
edba7a54 | 79 | # ifdef SHARED |
c50ce9a4 UD |
80 | lwz r7,_rtld_global_ro@got(r7) |
81 | mtlr r8 | |
edba7a54 UD |
82 | lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7) |
83 | # else | |
c50ce9a4 UD |
84 | lwz r7,_dl_hwcap@got(r7) |
85 | mtlr r8 | |
edba7a54 UD |
86 | lwz r7,4(r7) |
87 | # endif | |
88 | #else | |
89 | lis r7,(_dl_hwcap+4)@ha | |
90 | lwz r7,(_dl_hwcap+4)@l(r7) | |
91 | #endif | |
92 | ||
93 | #ifdef __CONTEXT_ENABLE_FPRS | |
94 | # ifdef __CONTEXT_ENABLE_VRS | |
95 | andis. r6,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) | |
c50ce9a4 UD |
96 | la r10,(_UC_VREGS)(r31) |
97 | beq 2f /* L(has_no_vec) */ | |
98 | ||
99 | lwz r0,(32*16)(r10) | |
100 | li r9,(32*16) | |
101 | cmpwi r0,0 | |
102 | mtspr VRSAVE,r0 | |
103 | beq 2f /* L(has_no_vec) */ | |
104 | ||
105 | lvx v19,r9,r10 | |
106 | la r9,(16)(r10) | |
107 | ||
108 | lvx v0,0,r10 | |
109 | lvx v1,0,r9 | |
110 | addi r10,r10,32 | |
111 | addi r9,r9,32 | |
112 | ||
113 | mtvscr v19 | |
114 | lvx v2,0,r10 | |
115 | lvx v3,0,r9 | |
116 | addi r10,r10,32 | |
117 | addi r9,r9,32 | |
118 | ||
119 | lvx v4,0,r10 | |
120 | lvx v5,0,r9 | |
121 | addi r10,r10,32 | |
122 | addi r9,r9,32 | |
123 | ||
124 | lvx v6,0,r10 | |
125 | lvx v7,0,r9 | |
126 | addi r10,r10,32 | |
127 | addi r9,r9,32 | |
128 | ||
129 | lvx v8,0,r10 | |
130 | lvx v9,0,r9 | |
131 | addi r10,r10,32 | |
132 | addi r9,r9,32 | |
133 | ||
134 | lvx v10,0,r10 | |
135 | lvx v11,0,r9 | |
136 | addi r10,r10,32 | |
137 | addi r9,r9,32 | |
138 | ||
139 | lvx v12,0,r10 | |
140 | lvx v13,0,r9 | |
141 | addi r10,r10,32 | |
142 | addi r9,r9,32 | |
143 | ||
144 | lvx v14,0,r10 | |
145 | lvx v15,0,r9 | |
146 | addi r10,r10,32 | |
147 | addi r9,r9,32 | |
148 | ||
149 | lvx v16,0,r10 | |
150 | lvx v17,0,r9 | |
151 | addi r10,r10,32 | |
152 | addi r9,r9,32 | |
153 | ||
154 | lvx v18,0,r10 | |
155 | lvx v19,0,r9 | |
156 | addi r10,r10,32 | |
157 | addi r9,r9,32 | |
158 | ||
159 | lvx v20,0,r10 | |
160 | lvx v21,0,r9 | |
161 | addi r10,r10,32 | |
162 | addi r9,r9,32 | |
163 | ||
164 | lvx v22,0,r10 | |
165 | lvx v23,0,r9 | |
166 | addi r10,r10,32 | |
167 | addi r9,r9,32 | |
168 | ||
169 | lvx v24,0,r10 | |
170 | lvx v25,0,r9 | |
171 | addi r10,r10,32 | |
172 | addi r9,r9,32 | |
173 | ||
174 | lvx v26,0,r10 | |
175 | lvx v27,0,r9 | |
176 | addi r10,r10,32 | |
177 | addi r9,r9,32 | |
178 | ||
179 | lvx v28,0,r10 | |
180 | lvx v29,0,r9 | |
181 | addi r10,r10,32 | |
182 | addi r9,r9,32 | |
183 | ||
184 | lvx v30,0,r10 | |
185 | lvx v31,0,r9 | |
186 | addi r10,r10,32 | |
187 | addi r9,r9,32 | |
188 | ||
189 | lvx v10,0,r10 | |
190 | lvx v11,0,r9 | |
191 | ||
192 | 2: /* L(has_no_vec): */ | |
193 | # endif /* __CONTEXT_ENABLE_VRS */ | |
194 | /* Restore the floating-point registers */ | |
195 | lfd fp31,_UC_FREGS+(32*8)(r31) | |
196 | lfd fp0,_UC_FREGS+(0*8)(r31) | |
edba7a54 UD |
197 | # ifdef _ARCH_PWR6 |
198 | /* Use the extended four-operand version of the mtfsf insn. */ | |
b7219e53 | 199 | mtfsf 0xff,fp31,1,0 |
edba7a54 | 200 | # else |
bddec78c UD |
201 | .machine push |
202 | .machine "power6" | |
edba7a54 UD |
203 | /* Availability of DFP indicates a 64-bit FPSCR. */ |
204 | andi. r6,r7,PPC_FEATURE_HAS_DFP | |
205 | beq 7f | |
206 | /* Use the extended four-operand version of the mtfsf insn. */ | |
207 | mtfsf 0xff,fp31,1,0 | |
208 | b 8f | |
209 | /* Continue to operate on the FPSCR as if it were 32-bits. */ | |
210 | 7: mtfsf 0xff,fp31 | |
bddec78c | 211 | 8: .machine pop |
edba7a54 | 212 | # endif /* _ARCH_PWR6 */ |
c50ce9a4 UD |
213 | lfd fp1,_UC_FREGS+(1*8)(r31) |
214 | lfd fp2,_UC_FREGS+(2*8)(r31) | |
215 | lfd fp3,_UC_FREGS+(3*8)(r31) | |
216 | lfd fp4,_UC_FREGS+(4*8)(r31) | |
217 | lfd fp5,_UC_FREGS+(5*8)(r31) | |
218 | lfd fp6,_UC_FREGS+(6*8)(r31) | |
219 | lfd fp7,_UC_FREGS+(7*8)(r31) | |
220 | lfd fp8,_UC_FREGS+(8*8)(r31) | |
221 | lfd fp9,_UC_FREGS+(9*8)(r31) | |
222 | lfd fp10,_UC_FREGS+(10*8)(r31) | |
223 | lfd fp11,_UC_FREGS+(11*8)(r31) | |
224 | lfd fp12,_UC_FREGS+(12*8)(r31) | |
225 | lfd fp13,_UC_FREGS+(13*8)(r31) | |
226 | lfd fp14,_UC_FREGS+(14*8)(r31) | |
227 | lfd fp15,_UC_FREGS+(15*8)(r31) | |
228 | lfd fp16,_UC_FREGS+(16*8)(r31) | |
229 | lfd fp17,_UC_FREGS+(17*8)(r31) | |
230 | lfd fp18,_UC_FREGS+(18*8)(r31) | |
231 | lfd fp19,_UC_FREGS+(19*8)(r31) | |
232 | lfd fp20,_UC_FREGS+(20*8)(r31) | |
233 | lfd fp21,_UC_FREGS+(21*8)(r31) | |
234 | lfd fp22,_UC_FREGS+(22*8)(r31) | |
235 | lfd fp23,_UC_FREGS+(23*8)(r31) | |
236 | lfd fp24,_UC_FREGS+(24*8)(r31) | |
237 | lfd fp25,_UC_FREGS+(25*8)(r31) | |
238 | lfd fp26,_UC_FREGS+(26*8)(r31) | |
239 | lfd fp27,_UC_FREGS+(27*8)(r31) | |
240 | lfd fp28,_UC_FREGS+(28*8)(r31) | |
241 | lfd fp29,_UC_FREGS+(29*8)(r31) | |
242 | lfd fp30,_UC_FREGS+(30*8)(r31) | |
243 | lfd fp31,_UC_FREGS+(31*8)(r31) | |
244 | #endif /* __CONTEXT_ENABLE_FPRS */ | |
245 | ||
246 | /* Restore LR and CCR, and set CTR to the NIP value */ | |
247 | lwz r3,_UC_GREGS+(PT_LNK*4)(r31) | |
248 | lwz r4,_UC_GREGS+(PT_NIP*4)(r31) | |
249 | lwz r5,_UC_GREGS+(PT_CCR*4)(r31) | |
250 | mtlr r3 | |
251 | mtctr r4 | |
252 | mtcr r5 | |
253 | ||
254 | /* Restore the general registers */ | |
255 | lwz r1,_UC_GREGS+(PT_R1*4)(r31) | |
256 | lwz r3,_UC_GREGS+(PT_R3*4)(r31) | |
257 | lwz r4,_UC_GREGS+(PT_R4*4)(r31) | |
258 | lwz r5,_UC_GREGS+(PT_R5*4)(r31) | |
259 | lwz r6,_UC_GREGS+(PT_R6*4)(r31) | |
260 | lwz r7,_UC_GREGS+(PT_R7*4)(r31) | |
261 | lwz r8,_UC_GREGS+(PT_R8*4)(r31) | |
262 | lwz r9,_UC_GREGS+(PT_R9*4)(r31) | |
263 | lwz r10,_UC_GREGS+(PT_R10*4)(r31) | |
264 | lwz r11,_UC_GREGS+(PT_R11*4)(r31) | |
265 | lwz r12,_UC_GREGS+(PT_R12*4)(r31) | |
266 | lwz r13,_UC_GREGS+(PT_R13*4)(r31) | |
267 | lwz r14,_UC_GREGS+(PT_R14*4)(r31) | |
268 | lwz r15,_UC_GREGS+(PT_R15*4)(r31) | |
269 | lwz r16,_UC_GREGS+(PT_R16*4)(r31) | |
270 | lwz r17,_UC_GREGS+(PT_R17*4)(r31) | |
271 | lwz r18,_UC_GREGS+(PT_R18*4)(r31) | |
272 | lwz r19,_UC_GREGS+(PT_R19*4)(r31) | |
273 | lwz r20,_UC_GREGS+(PT_R20*4)(r31) | |
274 | lwz r21,_UC_GREGS+(PT_R21*4)(r31) | |
275 | lwz r22,_UC_GREGS+(PT_R22*4)(r31) | |
276 | lwz r23,_UC_GREGS+(PT_R23*4)(r31) | |
277 | lwz r24,_UC_GREGS+(PT_R24*4)(r31) | |
278 | lwz r25,_UC_GREGS+(PT_R25*4)(r31) | |
279 | lwz r26,_UC_GREGS+(PT_R26*4)(r31) | |
280 | lwz r27,_UC_GREGS+(PT_R27*4)(r31) | |
281 | lwz r28,_UC_GREGS+(PT_R28*4)(r31) | |
282 | lwz r29,_UC_GREGS+(PT_R29*4)(r31) | |
283 | lwz r30,_UC_GREGS+(PT_R30*4)(r31) | |
284 | lwz r31,_UC_GREGS+(PT_R31*4)(r31) | |
285 | ||
286 | bctr | |
287 | ||
288 | 3: /* L(error_exit): */ | |
289 | lwz r31,12(r1) | |
290 | lwz r0,20(r1) | |
291 | addi r1,r1,16 | |
292 | mtlr r0 | |
293 | blr | |
294 | ||
295 | ||
296 | 4: /* L(do_sigret): */ | |
297 | addi r1,r3,-0xd0 | |
298 | li r0,SYS_ify(rt_sigreturn) | |
299 | sc | |
300 | /* NOTREACHED */ | |
301 | ||
302 | END (__CONTEXT_FUNC_NAME) |