]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext-common.S
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc32 / setcontext-common.S
1 /* Jump to a new context powerpc32 common.
2 Copyright (C) 2005-2014 Free Software Foundation, Inc.
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
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
18
19 /* This is the common implementation of setcontext for powerpc32.
20 It not complete in itself should be included in to a framework that
21 defines:
22 __CONTEXT_FUNC_NAME
23 and if appropriate:
24 __CONTEXT_ENABLE_FPRS
25 __CONTEXT_ENABLE_VRS
26 Any architecture that implements the Vector unit is assumed to also
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)
43 cfi_adjust_cfa_offset (16)
44 stw r0,20(r1)
45 cfi_offset (lr, _FRAME_LR_SAVE)
46 stw r31,12(r1)
47 cfi_offset(r31,-4)
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
73 #ifdef PIC
74 mflr r8
75 # define got_label GENERATE_GOT_LABEL (__CONTEXT_FUNC_NAME)
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
79 # ifdef SHARED
80 lwz r7,_rtld_global_ro@got(r7)
81 mtlr r8
82 lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7)
83 # else
84 lwz r7,_dl_hwcap@got(r7)
85 mtlr r8
86 lwz r7,LOWORD(r7)
87 # endif
88 #else
89 lis r7,(_dl_hwcap+LOWORD)@ha
90 lwz r7,(_dl_hwcap+LOWORD)@l(r7)
91 #endif
92
93 #ifdef __CONTEXT_ENABLE_FPRS
94 # ifdef __CONTEXT_ENABLE_VRS
95 andis. r6,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
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)
197 # ifdef _ARCH_PWR6
198 /* Use the extended four-operand version of the mtfsf insn. */
199 mtfsf 0xff,fp31,1,0
200 # else
201 .machine push
202 .machine "power6"
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
211 8: .machine pop
212 # endif /* _ARCH_PWR6 */
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 #ifdef __CONTEXT_ENABLE_E500
247 setcontext_e500
248 #endif
249
250 /* Restore LR and CCR, and set CTR to the NIP value */
251 lwz r3,_UC_GREGS+(PT_LNK*4)(r31)
252 lwz r4,_UC_GREGS+(PT_NIP*4)(r31)
253 lwz r5,_UC_GREGS+(PT_CCR*4)(r31)
254 mtlr r3
255 mtctr r4
256 mtcr r5
257
258 /* Restore the general registers */
259 lwz r1,_UC_GREGS+(PT_R1*4)(r31)
260 lwz r3,_UC_GREGS+(PT_R3*4)(r31)
261 lwz r4,_UC_GREGS+(PT_R4*4)(r31)
262 lwz r5,_UC_GREGS+(PT_R5*4)(r31)
263 lwz r6,_UC_GREGS+(PT_R6*4)(r31)
264 lwz r7,_UC_GREGS+(PT_R7*4)(r31)
265 lwz r8,_UC_GREGS+(PT_R8*4)(r31)
266 lwz r9,_UC_GREGS+(PT_R9*4)(r31)
267 lwz r10,_UC_GREGS+(PT_R10*4)(r31)
268 lwz r11,_UC_GREGS+(PT_R11*4)(r31)
269 lwz r12,_UC_GREGS+(PT_R12*4)(r31)
270 lwz r13,_UC_GREGS+(PT_R13*4)(r31)
271 lwz r14,_UC_GREGS+(PT_R14*4)(r31)
272 lwz r15,_UC_GREGS+(PT_R15*4)(r31)
273 lwz r16,_UC_GREGS+(PT_R16*4)(r31)
274 lwz r17,_UC_GREGS+(PT_R17*4)(r31)
275 lwz r18,_UC_GREGS+(PT_R18*4)(r31)
276 lwz r19,_UC_GREGS+(PT_R19*4)(r31)
277 lwz r20,_UC_GREGS+(PT_R20*4)(r31)
278 lwz r21,_UC_GREGS+(PT_R21*4)(r31)
279 lwz r22,_UC_GREGS+(PT_R22*4)(r31)
280 lwz r23,_UC_GREGS+(PT_R23*4)(r31)
281 lwz r24,_UC_GREGS+(PT_R24*4)(r31)
282 lwz r25,_UC_GREGS+(PT_R25*4)(r31)
283 lwz r26,_UC_GREGS+(PT_R26*4)(r31)
284 lwz r27,_UC_GREGS+(PT_R27*4)(r31)
285 lwz r28,_UC_GREGS+(PT_R28*4)(r31)
286 lwz r29,_UC_GREGS+(PT_R29*4)(r31)
287 lwz r30,_UC_GREGS+(PT_R30*4)(r31)
288 lwz r31,_UC_GREGS+(PT_R31*4)(r31)
289
290 bctr
291
292 3: /* L(error_exit): */
293 lwz r31,12(r1)
294 lwz r0,20(r1)
295 addi r1,r1,16
296 mtlr r0
297 blr
298
299
300 4: /* L(do_sigret): */
301 addi r1,r3,-0xd0
302 li r0,SYS_ify(rt_sigreturn)
303 sc
304 /* NOTREACHED */
305
306 END (__CONTEXT_FUNC_NAME)