Updated to fedora-glibc-20041217T0906
[glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc64 / getcontext.S
blob61e0f8ed11dbce5780ba008d1cab957302612871
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>
23 #include "kernel-features.h"
25 #define __ASSEMBLY__
26 #include <asm/ptrace.h>
27 #include <asm/errno.h>
28 #include "ucontext_i.h"
31 #if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
32 ENTRY(__novec_getcontext)
33         CALL_MCOUNT 1
34 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
35   std  r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
36   std  r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
37   mflr  r0
38   std  r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
39   std  r0,FRAME_LR_SAVE(r1)
40   std  r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
41   std  r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
42   stdu  r1,-128(r1)
43   std  r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
44   std  r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
45   std  r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
46   std  r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
47   std  r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
48   std  r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
49   std  r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
50   std  r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
51   std  r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
52   std  r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
53   std  r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
54   std  r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
55   std  r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
56   std  r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
57   std  r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
58   std  r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
59   std  r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
60   std  r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
61   std  r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
62   std  r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
63   std  r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
64   std  r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
65   std  r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
66   std  r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
67   std  r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
68   std  r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
69   std  r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
70   std  r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
71   mfctr  r0
72   std  r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
73   mfxer  r0
74   std  r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
75   mfcr  r0
76   std  r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
78   /* Set the return value of swapcontext to "success".  R3 is the only
79      register whose value is not preserved in the saved context.  */
80   li   r0,0
81   std  r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
83   /* Zero fill fields that can't be set in user state or are unused.  */
84   std  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
85   std  r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
86   std  r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
87   std  r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
88   std  r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
89   std  r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
90   std  r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
92   /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
93      field.  Struct pt_regs and elf_gregset_t are the same thing.
94      We kept the regs field for backwards compatibility with
95      libraries built before we extended sigcontext.  */
96   addi r0,r3,SIGCONTEXT_GP_REGS
97   std  r0,SIGCONTEXT_PT_REGS(r3)
99   stfd  fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
100   stfd  fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
101   stfd  fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
102   stfd  fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
103   stfd  fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
104   stfd  fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
105   stfd  fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
106   stfd  fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
107   stfd  fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
108   stfd  fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
109   stfd  fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
110   stfd  fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
111   stfd  fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
112   stfd  fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
113   stfd  fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
114   stfd  fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
115   stfd  fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
116   stfd  fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
117   stfd  fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
118   stfd  fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
119   stfd  fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
120   stfd  fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
121   stfd  fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
122   stfd  fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
123   stfd  fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
124   stfd  fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
125   stfd  fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
126   stfd  fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
127   stfd  fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
128   stfd  fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
129   mffs  fp0
130   stfd  fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
131   stfd  fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
132   stfd  fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
134   addi  r5,r3,UCONTEXT_SIGMASK
135   li  r4,0
136   li  r3,SIG_BLOCK
137   bl  JUMPTARGET(__sigprocmask)
138   nop
139 #else
140   /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub.  */
141   mflr r0
142   std  r0,FRAME_LR_SAVE(r1)
143   stdu r1,-128(r1)
144   li   r3,ENOSYS
145   bl   JUMPTARGET(__syscall_error)
146   nop
147   li   r3,-1
148 #endif
150   ld    r0,128+FRAME_LR_SAVE(r1)
151   addi  r1,r1,128
152   mtlr  r0
153   blr
154 PSEUDO_END(__novec_getcontext)
156 compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3)
158 #endif
160         .section        ".toc","aw"
161 .LC__dl_hwcap:
162 #ifdef SHARED
163         .tc _rtld_global_ro[TC],_rtld_global_ro
164 #else
165         .tc _dl_hwcap[TC],_dl_hwcap
166 #endif
167         .section ".text"
169         .machine        "altivec"
170 ENTRY(__getcontext)
171         CALL_MCOUNT 1
172 #ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
173   std  r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
174   std  r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
175   mflr  r0
176   std  r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
177   std  r0,FRAME_LR_SAVE(r1)
178   std  r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
179   std  r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
180   stdu  r1,-128(r1)
181   std  r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
182   std  r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
183   std  r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
184   std  r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
185   std  r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
186   std  r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
187   std  r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
188   std  r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
189   std  r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
190   std  r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
191   std  r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
192   std  r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
193   std  r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
194   std  r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
195   std  r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
196   std  r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
197   std  r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
198   std  r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
199   std  r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
200   std  r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
201   std  r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
202   std  r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
203   std  r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
204   std  r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
205   std  r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
206   std  r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
207   std  r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
208   std  r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
209   mfctr  r0
210   std  r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
211   mfxer  r0
212   std  r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
213   mfcr  r0
214   std  r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
216   /* Set the return value of swapcontext to "success".  R3 is the only
217      register whose value is not preserved in the saved context.  */
218   li   r0,0
219   std  r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
221   /* Zero fill fields that can't be set in user state or are unused.  */
222   std  r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
223   std  r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
224   std  r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
225   std  r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
226   std  r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
227   std  r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
228   std  r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
230   /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
231      field.  Struct pt_regs and elf_gregset_t are the same thing.
232      We kept the regs field for backwards compatibility with
233      libraries built before we extended sigcontext.  */
234   addi r0,r3,SIGCONTEXT_GP_REGS
235   std  r0,SIGCONTEXT_PT_REGS(r3)
237   stfd  fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
238   stfd  fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
239   stfd  fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
240   stfd  fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
241   stfd  fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
242   stfd  fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
243   stfd  fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
244   stfd  fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
245   stfd  fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
246   stfd  fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
247   stfd  fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
248   stfd  fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
249   stfd  fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
250   stfd  fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
251   stfd  fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
252   stfd  fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
253   stfd  fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
254   stfd  fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
255   stfd  fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
256   stfd  fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
257   stfd  fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
258   stfd  fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
259   stfd  fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
260   stfd  fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
261   stfd  fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
262   stfd  fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
263   stfd  fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
264   stfd  fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
265   stfd  fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
266   stfd  fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
267   mffs  fp0
268   stfd  fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
269   stfd  fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
270   stfd  fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
272   ld    r5,.LC__dl_hwcap@toc(r2)
273 # ifdef SHARED
274 /* Load _rtld-global._dl_hwcap.  */
275   ld    r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
276 # else
277   ld    r5,0(r5) /* Load extern _dl_hwcap.  */
278 # endif
279   la    r10,(SIGCONTEXT_V_RESERVE+8)(r3)
280   la    r9,(SIGCONTEXT_V_RESERVE+24)(r3)
282   andis.  r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
284   clrrdi  r10,r10,4
285   beq   L(has_no_vec)
286   clrrdi  r9,r9,4
287   mr    r5,r10  /* Capture *v_regs value in r5.  */
289   stvx  v0,0,r10
290   stvx  v1,0,r9
291   addi  r10,r10,32
292   addi  r9,r9,32
294   stvx  v2,0,r10
295   stvx  v3,0,r9
296   addi  r10,r10,32
297   addi  r9,r9,32
299   stvx  v4,0,r10
300   stvx  v5,0,r9
301   addi  r10,r10,32
302   addi  r9,r9,32
304   stvx  v6,0,r10
305   stvx  v7,0,r9
306   addi  r10,r10,32
307   addi  r9,r9,32
309   stvx  v8,0,r10
310   stvx  v9,0,r9
311   addi  r10,r10,32
312   addi  r9,r9,32
314   stvx  v10,0,r10
315   stvx  v11,0,r9
316   addi  r10,r10,32
317   addi  r9,r9,32
319   stvx  v12,0,r10
320   stvx  v13,0,r9
321   addi  r10,r10,32
322   addi  r9,r9,32
324   stvx  v14,0,r10
325   stvx  v15,0,r9
326   addi  r10,r10,32
327   addi  r9,r9,32
329   stvx  v16,0,r10
330   stvx  v17,0,r9
331   addi  r10,r10,32
332   addi  r9,r9,32
334   stvx  v18,0,r10
335   stvx  v19,0,r9
336   addi  r10,r10,32
337   addi  r9,r9,32
339   stvx  v20,0,r10
340   stvx  v21,0,r9
341   addi  r10,r10,32
342   addi  r9,r9,32
344   stvx  v22,0,r10
345   stvx  v23,0,r9
346   addi  r10,r10,32
347   addi  r9,r9,32
349   stvx  v24,0,r10
350   stvx  v25,0,r9
351   addi  r10,r10,32
352   addi  r9,r9,32
354   stvx  v26,0,r10
355   stvx  v27,0,r9
356   addi  r10,r10,32
357   addi  r9,r9,32
359   stvx  v28,0,r10
360   stvx  v29,0,r9
361   addi  r10,r10,32
362   addi  r9,r9,32
364   stvx  v30,0,r10
365   stvx  v31,0,r9
366   addi  r10,r10,32
367   addi  r9,r9,32
369   mfvscr  v0
370   mfspr r0,VRSAVE
371   stvx  v0,0,r10
372   stw   r0,0(9)
374 L(has_no_vec):
376    Store either a NULL or a quadword aligned pointer to the Vector register
377    array into *v_regs.
379   std   r5,(SIGCONTEXT_V_REGS_PTR)(r3)
381   addi  r5,r3,UCONTEXT_SIGMASK
382   li  r4,0
383   li  r3,SIG_BLOCK
384   bl  JUMPTARGET(__sigprocmask)
385   nop
386 #else
387   /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub.  */
388   mflr r0
389   std  r0,FRAME_LR_SAVE(r1)
390   stdu r1,-128(r1)
391   li   r3,ENOSYS
392   bl   JUMPTARGET(__syscall_error)
393   nop
394   li   r3,-1
395 #endif
397   ld    r0,128+FRAME_LR_SAVE(r1)
398   addi  r1,r1,128
399   mtlr  r0
400   blr
401 PSEUDO_END(__getcontext)
403 versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)