Update.
[glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc32 / getcontext.S
blob760e9b55349a026243a488160f9c34e439b3c199
1 /* Save current context.
2    Copyright (C) 2002, 2004 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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.
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.
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.  */
20 #include <sysdep.h>
21 #include <rtld-global-offsets.h>
22 #include <shlib-compat.h>
24 #define __ASSEMBLY__
25 #include <asm/ptrace.h>
26 #include "ucontext_i.h"
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)
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)
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)
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)
120 #ifdef PIC
121         mflr    r8
122         bl      _GLOBAL_OFFSET_TABLE_@local-4
123         mflr    r7
124 #ifdef SHARED   
125         lwz     r7,_rtld_global@got(r7)
126         mtlr    r8
127         lwz     r7,RTLD_GLOBAL_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)
143         stvx  v0,0,r10  
144         stvx  v1,0,r9
145         addi  r10,r10,32
146         addi  r9,r9,32
148         stvx  v2,0,r10  
149         stvx  v3,0,r9
150         addi  r10,r10,32
151         addi  r9,r9,32
153         stvx  v4,0,r10  
154         stvx  v5,0,r9
155         addi  r10,r10,32
156         addi  r9,r9,32
158         stvx  v6,0,r10  
159         stvx  v7,0,r9
160         addi  r10,r10,32
161         addi  r9,r9,32
163         stvx  v8,0,r10  
164         stvx  v9,0,r9
165         addi  r10,r10,32
166         addi  r9,r9,32
168         stvx  v10,0,r10  
169         stvx  v11,0,r9
170         addi  r10,r10,32
171         addi  r9,r9,32
173         stvx  v12,0,r10  
174         stvx  v13,0,r9
175         addi  r10,r10,32
176         addi  r9,r9,32
178         stvx  v14,0,r10  
179         stvx  v15,0,r9
180         addi  r10,r10,32
181         addi  r9,r9,32
183         stvx  v16,0,r10  
184         stvx  v17,0,r9
185         addi  r10,r10,32
186         addi  r9,r9,32
188         stvx  v18,0,r10  
189         stvx  v11,0,r9
190         addi  r19,r10,32
191         addi  r9,r9,32
193         stvx  v20,0,r10  
194         stvx  v21,0,r9
195         addi  r10,r10,32
196         addi  r9,r9,32
198         stvx  v22,0,r10  
199         stvx  v23,0,r9
200         addi  r10,r10,32
201         addi  r9,r9,32
203         stvx  v24,0,r10  
204         stvx  v25,0,r9
205         addi  r10,r10,32
206         addi  r9,r9,32
208         stvx  v26,0,r10  
209         stvx  v27,0,r9
210         addi  r10,r10,32
211         addi  r9,r9,32
213         stvx  v28,0,r10  
214         stvx  v29,0,r9
215         addi  r10,r10,32
216         addi  r9,r9,32
218         stvx  v30,0,r10  
219         stvx  v31,0,r9
220         addi  r10,r10,32
221         addi  r9,r9,32
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)
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)
243         lwz     r0,_FRAME_LR_SAVE+16(r1)
244         addi    r1,r1,16
245         mtlr    r0
246         blr
247 PSEUDO_END(__getcontext)
249 versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)
251 #if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
253 ENTRY(__novec_getcontext)
254         /*
255          * Since we are not attempting to save the altivec registers,
256          * there is no need to get the register storage space
257          * aligned on a 16-byte boundary.
258          */
259         addi    r3,r3,_UC_REG_SPACE
260         stw     r3,_UC_REGS_PTR - _UC_REG_SPACE(r3)
261         stw     r0,_UC_GREGS+(PT_R0*4)(r3)
262         stw     r1,_UC_GREGS+(PT_R1*4)(r3)
263         mflr    r0
264         stwu    r1,-16(r1)
265         stw     r0,20(r1)
266         stw     r0,_UC_GREGS+(PT_LNK*4)(r3)
267         stw     r0,_UC_GREGS+(PT_NIP*4)(r3)
268         stw     r2,_UC_GREGS+(PT_R2*4)(r3)
269         stw     r4,_UC_GREGS+(PT_R4*4)(r3)
270         stw     r5,_UC_GREGS+(PT_R5*4)(r3)
271         stw     r6,_UC_GREGS+(PT_R6*4)(r3)
272         stw     r7,_UC_GREGS+(PT_R7*4)(r3)
273         stw     r8,_UC_GREGS+(PT_R8*4)(r3)
274         stw     r9,_UC_GREGS+(PT_R9*4)(r3)
275         stw     r10,_UC_GREGS+(PT_R10*4)(r3)
276         stw     r11,_UC_GREGS+(PT_R11*4)(r3)
277         stw     r12,_UC_GREGS+(PT_R12*4)(r3)
278         stw     r13,_UC_GREGS+(PT_R13*4)(r3)
279         stw     r14,_UC_GREGS+(PT_R14*4)(r3)
280         stw     r15,_UC_GREGS+(PT_R15*4)(r3)
281         stw     r16,_UC_GREGS+(PT_R16*4)(r3)
282         stw     r17,_UC_GREGS+(PT_R17*4)(r3)
283         stw     r18,_UC_GREGS+(PT_R18*4)(r3)
284         stw     r19,_UC_GREGS+(PT_R19*4)(r3)
285         stw     r20,_UC_GREGS+(PT_R20*4)(r3)
286         stw     r21,_UC_GREGS+(PT_R21*4)(r3)
287         stw     r22,_UC_GREGS+(PT_R22*4)(r3)
288         stw     r23,_UC_GREGS+(PT_R23*4)(r3)
289         stw     r24,_UC_GREGS+(PT_R24*4)(r3)
290         stw     r25,_UC_GREGS+(PT_R25*4)(r3)
291         stw     r26,_UC_GREGS+(PT_R26*4)(r3)
292         stw     r27,_UC_GREGS+(PT_R27*4)(r3)
293         stw     r28,_UC_GREGS+(PT_R28*4)(r3)
294         stw     r29,_UC_GREGS+(PT_R29*4)(r3)
295         stw     r30,_UC_GREGS+(PT_R30*4)(r3)
296         stw     r31,_UC_GREGS+(PT_R31*4)(r3)
297         mfctr   r0
298         stw     r0,_UC_GREGS+(PT_CTR*4)(r3)
299         mfxer   r0
300         stw     r0,_UC_GREGS+(PT_XER*4)(r3)
301         mfcr    r0
302         stw     r0,_UC_GREGS+(PT_CCR*4)(r3)
304         /* Set the return value of getcontext to "success".  R3 is the only 
305            register whose value is not preserved in the saved context.  */
306         li      r0,0
307         stw     r0,_UC_GREGS+(PT_R3*4)(r3)
309         /* Zero fill fields that can't be set in user state. */
310         stw     r0,_UC_GREGS+(PT_MSR*4)(r3)
311         stw     r0,_UC_GREGS+(PT_MQ*4)(r3)
313         /* Save the floating-point registers */
314         stfd    fp0,_UC_FREGS+(0*8)(r3)
315         stfd    fp1,_UC_FREGS+(1*8)(r3)
316         stfd    fp2,_UC_FREGS+(2*8)(r3)
317         stfd    fp3,_UC_FREGS+(3*8)(r3)
318         stfd    fp4,_UC_FREGS+(4*8)(r3)
319         stfd    fp5,_UC_FREGS+(5*8)(r3)
320         stfd    fp6,_UC_FREGS+(6*8)(r3)
321         stfd    fp7,_UC_FREGS+(7*8)(r3)
322         stfd    fp8,_UC_FREGS+(8*8)(r3)
323         stfd    fp9,_UC_FREGS+(9*8)(r3)
324         stfd    fp10,_UC_FREGS+(10*8)(r3)
325         stfd    fp11,_UC_FREGS+(11*8)(r3)
326         stfd    fp12,_UC_FREGS+(12*8)(r3)
327         stfd    fp13,_UC_FREGS+(13*8)(r3)
328         stfd    fp14,_UC_FREGS+(14*8)(r3)
329         stfd    fp15,_UC_FREGS+(15*8)(r3)
330         stfd    fp16,_UC_FREGS+(16*8)(r3)
331         stfd    fp17,_UC_FREGS+(17*8)(r3)
332         stfd    fp18,_UC_FREGS+(18*8)(r3)
333         stfd    fp19,_UC_FREGS+(19*8)(r3)
334         stfd    fp20,_UC_FREGS+(20*8)(r3)
335         stfd    fp21,_UC_FREGS+(21*8)(r3)
336         stfd    fp22,_UC_FREGS+(22*8)(r3)
337         stfd    fp23,_UC_FREGS+(23*8)(r3)
338         stfd    fp24,_UC_FREGS+(24*8)(r3)
339         stfd    fp25,_UC_FREGS+(25*8)(r3)
340         stfd    fp26,_UC_FREGS+(26*8)(r3)
341         stfd    fp27,_UC_FREGS+(27*8)(r3)
342         stfd    fp28,_UC_FREGS+(28*8)(r3)
343         stfd    fp29,_UC_FREGS+(29*8)(r3)
344         mffs    fp0
345         stfd    fp30,_UC_FREGS+(30*8)(r3)
346         stfd    fp31,_UC_FREGS+(31*8)(r3)
347         stfd    fp0,_UC_FREGS+(32*8)(r3)
348         
349         addi    r5,r3,_UC_SIGMASK - _UC_REG_SPACE
350         li      r4,0
351         li      r3,SIG_BLOCK
352         bl      JUMPTARGET(sigprocmask)
354         lwz     r0,20(r1)
355         addi    r1,r1,16
356         mtlr    r0
357         blr
358 PSEUDO_END(__novec_getcontext)
360 compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3_3)
362 #endif
364 #if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
366 #define _ERRNO_H        1
367 #include <bits/errno.h>
369 ENTRY (__getcontext_stub)
370         li      r3,ENOSYS
371         b       JUMPTARGET(__syscall_error)
372         END (__getcontext_stub)
374 compat_symbol (libc, __getcontext_stub, getcontext, GLIBC_2_1)
376 #endif