]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
Update.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc32 / getcontext.S
1 /* Save current context.
2 Copyright (C) 2002, 2004 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20 #include <sysdep.h>
21 #include <rtld-global-offsets.h>
22 #include <shlib-compat.h>
23
24 #define __ASSEMBLY__
25 #include <asm/ptrace.h>
26 #include "ucontext_i.h"
27
28 ENTRY(__getcontext)
29 stw r3,_FRAME_PARM_SAVE1(r1)
30 addi r3,r3,_UC_REG_SPACE+12
31 clrrwi r3,r3,4
32 stw r0,_UC_GREGS+(PT_R0*4)(r3)
33 mflr r0
34 stw r1,_UC_GREGS+(PT_R1*4)(r3)
35 stwu r1,-16(r1)
36 stw r0,_UC_GREGS+(PT_LNK*4)(r3)
37 stw r0,_UC_GREGS+(PT_NIP*4)(r3)
38 stw r0,_FRAME_LR_SAVE+16(r1)
39 stw r2,_UC_GREGS+(PT_R2*4)(r3)
40 stw r4,_UC_GREGS+(PT_R4*4)(r3)
41 stw r5,_UC_GREGS+(PT_R5*4)(r3)
42 stw r6,_UC_GREGS+(PT_R6*4)(r3)
43 stw r7,_UC_GREGS+(PT_R7*4)(r3)
44 stw r8,_UC_GREGS+(PT_R8*4)(r3)
45 stw r9,_UC_GREGS+(PT_R9*4)(r3)
46 stw r10,_UC_GREGS+(PT_R10*4)(r3)
47 stw r11,_UC_GREGS+(PT_R11*4)(r3)
48 stw r12,_UC_GREGS+(PT_R12*4)(r3)
49 stw r13,_UC_GREGS+(PT_R13*4)(r3)
50 stw r14,_UC_GREGS+(PT_R14*4)(r3)
51 stw r15,_UC_GREGS+(PT_R15*4)(r3)
52 stw r16,_UC_GREGS+(PT_R16*4)(r3)
53 stw r17,_UC_GREGS+(PT_R17*4)(r3)
54 stw r18,_UC_GREGS+(PT_R18*4)(r3)
55 stw r19,_UC_GREGS+(PT_R19*4)(r3)
56 stw r20,_UC_GREGS+(PT_R20*4)(r3)
57 stw r21,_UC_GREGS+(PT_R21*4)(r3)
58 stw r22,_UC_GREGS+(PT_R22*4)(r3)
59 stw r23,_UC_GREGS+(PT_R23*4)(r3)
60 stw r24,_UC_GREGS+(PT_R24*4)(r3)
61 stw r25,_UC_GREGS+(PT_R25*4)(r3)
62 stw r26,_UC_GREGS+(PT_R26*4)(r3)
63 stw r27,_UC_GREGS+(PT_R27*4)(r3)
64 stw r28,_UC_GREGS+(PT_R28*4)(r3)
65 stw r29,_UC_GREGS+(PT_R29*4)(r3)
66 stw r30,_UC_GREGS+(PT_R30*4)(r3)
67 stw r31,_UC_GREGS+(PT_R31*4)(r3)
68 mfctr r0
69 stw r0,_UC_GREGS+(PT_CTR*4)(r3)
70 mfxer r0
71 stw r0,_UC_GREGS+(PT_XER*4)(r3)
72 mfcr r0
73 stw r0,_UC_GREGS+(PT_CCR*4)(r3)
74
75 /* Set the return value of getcontext to "success". R3 is the only
76 register whose value is not preserved in the saved context. */
77 li r0,0
78 stw r0,_UC_GREGS+(PT_R3*4)(r3)
79
80 /* Zero fill fields that can't be set in user state. */
81 stw r0,_UC_GREGS+(PT_MSR*4)(r3)
82 stw r0,_UC_GREGS+(PT_MQ*4)(r3)
83
84 /* Save the floating-point registers */
85 stfd fp0,_UC_FREGS+(0*8)(r3)
86 stfd fp1,_UC_FREGS+(1*8)(r3)
87 stfd fp2,_UC_FREGS+(2*8)(r3)
88 stfd fp3,_UC_FREGS+(3*8)(r3)
89 stfd fp4,_UC_FREGS+(4*8)(r3)
90 stfd fp5,_UC_FREGS+(5*8)(r3)
91 stfd fp6,_UC_FREGS+(6*8)(r3)
92 stfd fp7,_UC_FREGS+(7*8)(r3)
93 stfd fp8,_UC_FREGS+(8*8)(r3)
94 stfd fp9,_UC_FREGS+(9*8)(r3)
95 stfd fp10,_UC_FREGS+(10*8)(r3)
96 stfd fp11,_UC_FREGS+(11*8)(r3)
97 stfd fp12,_UC_FREGS+(12*8)(r3)
98 stfd fp13,_UC_FREGS+(13*8)(r3)
99 stfd fp14,_UC_FREGS+(14*8)(r3)
100 stfd fp15,_UC_FREGS+(15*8)(r3)
101 stfd fp16,_UC_FREGS+(16*8)(r3)
102 stfd fp17,_UC_FREGS+(17*8)(r3)
103 stfd fp18,_UC_FREGS+(18*8)(r3)
104 stfd fp19,_UC_FREGS+(19*8)(r3)
105 stfd fp20,_UC_FREGS+(20*8)(r3)
106 stfd fp21,_UC_FREGS+(21*8)(r3)
107 stfd fp22,_UC_FREGS+(22*8)(r3)
108 stfd fp23,_UC_FREGS+(23*8)(r3)
109 stfd fp24,_UC_FREGS+(24*8)(r3)
110 stfd fp25,_UC_FREGS+(25*8)(r3)
111 stfd fp26,_UC_FREGS+(26*8)(r3)
112 stfd fp27,_UC_FREGS+(27*8)(r3)
113 stfd fp28,_UC_FREGS+(28*8)(r3)
114 stfd fp29,_UC_FREGS+(29*8)(r3)
115 mffs fp0
116 stfd fp30,_UC_FREGS+(30*8)(r3)
117 stfd fp31,_UC_FREGS+(31*8)(r3)
118 stfd fp0,_UC_FREGS+(32*8)(r3)
119
120 #ifdef PIC
121 mflr r8
122 bl _GLOBAL_OFFSET_TABLE_@local-4
123 mflr r7
124 # ifdef SHARED
125 lwz r7,_rtld_global_ro@got(r7)
126 mtlr r8
127 lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7)
128 # else
129 lwz r7,_dl_hwcap@got(r7)
130 mtlr r8
131 lwz r7,0(r7)
132 # endif
133 #else
134 lis r7,_dl_hwcap@ha
135 lwz r7,_dl_hwcap@l(r7)
136 #endif
137 andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
138 beq L(no_vec)
139
140 la r10,(_UC_VREGS)(r3)
141 la r9,(_UC_VREGS+16)(r3)
142
143 stvx v0,0,r10
144 stvx v1,0,r9
145 addi r10,r10,32
146 addi r9,r9,32
147
148 stvx v2,0,r10
149 stvx v3,0,r9
150 addi r10,r10,32
151 addi r9,r9,32
152
153 stvx v4,0,r10
154 stvx v5,0,r9
155 addi r10,r10,32
156 addi r9,r9,32
157
158 stvx v6,0,r10
159 stvx v7,0,r9
160 addi r10,r10,32
161 addi r9,r9,32
162
163 stvx v8,0,r10
164 stvx v9,0,r9
165 addi r10,r10,32
166 addi r9,r9,32
167
168 stvx v10,0,r10
169 stvx v11,0,r9
170 addi r10,r10,32
171 addi r9,r9,32
172
173 stvx v12,0,r10
174 stvx v13,0,r9
175 addi r10,r10,32
176 addi r9,r9,32
177
178 stvx v14,0,r10
179 stvx v15,0,r9
180 addi r10,r10,32
181 addi r9,r9,32
182
183 stvx v16,0,r10
184 stvx v17,0,r9
185 addi r10,r10,32
186 addi r9,r9,32
187
188 stvx v18,0,r10
189 stvx v11,0,r9
190 addi r19,r10,32
191 addi r9,r9,32
192
193 stvx v20,0,r10
194 stvx v21,0,r9
195 addi r10,r10,32
196 addi r9,r9,32
197
198 stvx v22,0,r10
199 stvx v23,0,r9
200 addi r10,r10,32
201 addi r9,r9,32
202
203 stvx v24,0,r10
204 stvx v25,0,r9
205 addi r10,r10,32
206 addi r9,r9,32
207
208 stvx v26,0,r10
209 stvx v27,0,r9
210 addi r10,r10,32
211 addi r9,r9,32
212
213 stvx v28,0,r10
214 stvx v29,0,r9
215 addi r10,r10,32
216 addi r9,r9,32
217
218 stvx v30,0,r10
219 stvx v31,0,r9
220 addi r10,r10,32
221 addi r9,r9,32
222
223 stvx v10,0,r10
224 stvx v11,0,r9
225 addi r10,r10,32
226 addi r9,r9,32
227
228 mfvscr v0
229 mfspr r0,VRSAVE
230 stvx v0,0,r10
231 sync
232 stw r0,0(r10)
233
234 L(no_vec):
235 /* Restore ucontext (parm1) from stack. */
236 lwz r12,_FRAME_PARM_SAVE1+16(r1)
237 li r4,0
238 stw r3,_UC_REGS_PTR(r12)
239 addi r5,r12,_UC_SIGMASK
240 li r3,SIG_BLOCK
241 bl JUMPTARGET(__sigprocmask)
242
243 lwz r0,_FRAME_LR_SAVE+16(r1)
244 addi r1,r1,16
245 mtlr r0
246 blr
247 END(__getcontext)
248
249 versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)
250
251 #if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
252
253 compat_text_section
254 ENTRY(__novec_getcontext)
255 /*
256 * Since we are not attempting to save the altivec registers,
257 * there is no need to get the register storage space
258 * aligned on a 16-byte boundary.
259 */
260 addi r3,r3,_UC_REG_SPACE
261 stw r3,_UC_REGS_PTR - _UC_REG_SPACE(r3)
262 stw r0,_UC_GREGS+(PT_R0*4)(r3)
263 stw r1,_UC_GREGS+(PT_R1*4)(r3)
264 mflr r0
265 stwu r1,-16(r1)
266 stw r0,20(r1)
267 stw r0,_UC_GREGS+(PT_LNK*4)(r3)
268 stw r0,_UC_GREGS+(PT_NIP*4)(r3)
269 stw r2,_UC_GREGS+(PT_R2*4)(r3)
270 stw r4,_UC_GREGS+(PT_R4*4)(r3)
271 stw r5,_UC_GREGS+(PT_R5*4)(r3)
272 stw r6,_UC_GREGS+(PT_R6*4)(r3)
273 stw r7,_UC_GREGS+(PT_R7*4)(r3)
274 stw r8,_UC_GREGS+(PT_R8*4)(r3)
275 stw r9,_UC_GREGS+(PT_R9*4)(r3)
276 stw r10,_UC_GREGS+(PT_R10*4)(r3)
277 stw r11,_UC_GREGS+(PT_R11*4)(r3)
278 stw r12,_UC_GREGS+(PT_R12*4)(r3)
279 stw r13,_UC_GREGS+(PT_R13*4)(r3)
280 stw r14,_UC_GREGS+(PT_R14*4)(r3)
281 stw r15,_UC_GREGS+(PT_R15*4)(r3)
282 stw r16,_UC_GREGS+(PT_R16*4)(r3)
283 stw r17,_UC_GREGS+(PT_R17*4)(r3)
284 stw r18,_UC_GREGS+(PT_R18*4)(r3)
285 stw r19,_UC_GREGS+(PT_R19*4)(r3)
286 stw r20,_UC_GREGS+(PT_R20*4)(r3)
287 stw r21,_UC_GREGS+(PT_R21*4)(r3)
288 stw r22,_UC_GREGS+(PT_R22*4)(r3)
289 stw r23,_UC_GREGS+(PT_R23*4)(r3)
290 stw r24,_UC_GREGS+(PT_R24*4)(r3)
291 stw r25,_UC_GREGS+(PT_R25*4)(r3)
292 stw r26,_UC_GREGS+(PT_R26*4)(r3)
293 stw r27,_UC_GREGS+(PT_R27*4)(r3)
294 stw r28,_UC_GREGS+(PT_R28*4)(r3)
295 stw r29,_UC_GREGS+(PT_R29*4)(r3)
296 stw r30,_UC_GREGS+(PT_R30*4)(r3)
297 stw r31,_UC_GREGS+(PT_R31*4)(r3)
298 mfctr r0
299 stw r0,_UC_GREGS+(PT_CTR*4)(r3)
300 mfxer r0
301 stw r0,_UC_GREGS+(PT_XER*4)(r3)
302 mfcr r0
303 stw r0,_UC_GREGS+(PT_CCR*4)(r3)
304
305 /* Set the return value of getcontext to "success". R3 is the only
306 register whose value is not preserved in the saved context. */
307 li r0,0
308 stw r0,_UC_GREGS+(PT_R3*4)(r3)
309
310 /* Zero fill fields that can't be set in user state. */
311 stw r0,_UC_GREGS+(PT_MSR*4)(r3)
312 stw r0,_UC_GREGS+(PT_MQ*4)(r3)
313
314 /* Save the floating-point registers */
315 stfd fp0,_UC_FREGS+(0*8)(r3)
316 stfd fp1,_UC_FREGS+(1*8)(r3)
317 stfd fp2,_UC_FREGS+(2*8)(r3)
318 stfd fp3,_UC_FREGS+(3*8)(r3)
319 stfd fp4,_UC_FREGS+(4*8)(r3)
320 stfd fp5,_UC_FREGS+(5*8)(r3)
321 stfd fp6,_UC_FREGS+(6*8)(r3)
322 stfd fp7,_UC_FREGS+(7*8)(r3)
323 stfd fp8,_UC_FREGS+(8*8)(r3)
324 stfd fp9,_UC_FREGS+(9*8)(r3)
325 stfd fp10,_UC_FREGS+(10*8)(r3)
326 stfd fp11,_UC_FREGS+(11*8)(r3)
327 stfd fp12,_UC_FREGS+(12*8)(r3)
328 stfd fp13,_UC_FREGS+(13*8)(r3)
329 stfd fp14,_UC_FREGS+(14*8)(r3)
330 stfd fp15,_UC_FREGS+(15*8)(r3)
331 stfd fp16,_UC_FREGS+(16*8)(r3)
332 stfd fp17,_UC_FREGS+(17*8)(r3)
333 stfd fp18,_UC_FREGS+(18*8)(r3)
334 stfd fp19,_UC_FREGS+(19*8)(r3)
335 stfd fp20,_UC_FREGS+(20*8)(r3)
336 stfd fp21,_UC_FREGS+(21*8)(r3)
337 stfd fp22,_UC_FREGS+(22*8)(r3)
338 stfd fp23,_UC_FREGS+(23*8)(r3)
339 stfd fp24,_UC_FREGS+(24*8)(r3)
340 stfd fp25,_UC_FREGS+(25*8)(r3)
341 stfd fp26,_UC_FREGS+(26*8)(r3)
342 stfd fp27,_UC_FREGS+(27*8)(r3)
343 stfd fp28,_UC_FREGS+(28*8)(r3)
344 stfd fp29,_UC_FREGS+(29*8)(r3)
345 mffs fp0
346 stfd fp30,_UC_FREGS+(30*8)(r3)
347 stfd fp31,_UC_FREGS+(31*8)(r3)
348 stfd fp0,_UC_FREGS+(32*8)(r3)
349
350 addi r5,r3,_UC_SIGMASK - _UC_REG_SPACE
351 li r4,0
352 li r3,SIG_BLOCK
353 bl JUMPTARGET(__sigprocmask)
354
355 lwz r0,20(r1)
356 addi r1,r1,16
357 mtlr r0
358 blr
359 END(__novec_getcontext)
360 .previous
361
362 compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3_3)
363
364 #endif
365
366 #if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
367
368 #define _ERRNO_H 1
369 #include <bits/errno.h>
370
371 compat_text_section
372 ENTRY (__getcontext_stub)
373 li r3,ENOSYS
374 b JUMPTARGET(__syscall_error)
375 END (__getcontext_stub)
376 .previous
377
378 compat_symbol (libc, __getcontext_stub, getcontext, GLIBC_2_1)
379
380 #endif