(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc32 / setcontext.S
blob2d4fa9910e0a7dec32c1a605792c1d37d789cab4
1 /* Jump to a new 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         .machine        "altivec"
29 ENTRY(__setcontext)
30         mflr    r0
31         stwu    r1,-16(r1)
32         stw     r0,20(r1)
33         stw     r31,12(r1)
34         lwz     r31,_UC_REGS_PTR(r3)
36         /*
37          * If this ucontext refers to the point where we were interrupted
38          * by a signal, we have to use the rt_sigreturn system call to
39          * return to the context so we get both LR and CTR restored.
40          *
41          * Otherwise, the context we are restoring is either just after
42          * a procedure call (getcontext/swapcontext) or at the beginning
43          * of a procedure call (makecontext), so we don't need to restore
44          * r0, xer, ctr.  We don't restore r2 since it will be used as
45          * the TLS pointer.
46          */
47         lwz     r0,_UC_GREGS+(PT_MSR*4)(r31)
48         cmpwi   r0,0
49         bne     L(do_sigret)
51         /* Restore the signal mask */
52         li      r5,0
53         addi    r4,r3,_UC_SIGMASK
54         li      r3,SIG_SETMASK
55         bl      JUMPTARGET(__sigprocmask)
56         cmpwi   r3,0
57         bne     L(error_exit)
59 #ifdef PIC
60         mflr    r8
61         bl      _GLOBAL_OFFSET_TABLE_@local-4
62         mflr    r7
63 # ifdef SHARED
64         lwz     r7,_rtld_global_ro@got(r7)
65         mtlr    r8
66         lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r7)
67 # else
68         lwz     r7,_dl_hwcap@got(r7)
69         mtlr    r8
70         lwz     r7,0(r7)
71 # endif
72 #else
73         lis     r7,_dl_hwcap@ha
74         lwz     r7,_dl_hwcap@l(r7)
75 #endif
76         andis.  r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
77         la      r10,(_UC_VREGS)(r31)
78         beq     L(has_no_vec)
80         lwz   r0,(32*16)(r10)
81         li    r9,(32*16)
82         cmpwi r0,0
83         mtspr VRSAVE,r0
84         beq   L(has_no_vec)
86         lvx   v19,r9,r10
87         la    r9,(16)(r10)
89         lvx   v0,0,r10
90         lvx   v1,0,r9
91         addi  r10,r10,32
92         addi  r9,r9,32
94         mtvscr  v19
95         lvx   v2,0,r10
96         lvx   v3,0,r9
97         addi  r10,r10,32
98         addi  r9,r9,32
100         lvx   v4,0,r10
101         lvx   v5,0,r9
102         addi  r10,r10,32
103         addi  r9,r9,32
105         lvx   v6,0,r10
106         lvx   v7,0,r9
107         addi  r10,r10,32
108         addi  r9,r9,32
110         lvx   v8,0,r10
111         lvx   v9,0,r9
112         addi  r10,r10,32
113         addi  r9,r9,32
115         lvx   v10,0,r10
116         lvx   v11,0,r9
117         addi  r10,r10,32
118         addi  r9,r9,32
120         lvx   v12,0,r10
121         lvx   v13,0,r9
122         addi  r10,r10,32
123         addi  r9,r9,32
125         lvx   v14,0,r10
126         lvx   v15,0,r9
127         addi  r10,r10,32
128         addi  r9,r9,32
130         lvx   v16,0,r10
131         lvx   v17,0,r9
132         addi  r10,r10,32
133         addi  r9,r9,32
135         lvx   v18,0,r10
136         lvx   v19,0,r9
137         addi  r10,r10,32
138         addi  r9,r9,32
140         lvx   v20,0,r10
141         lvx   v21,0,r9
142         addi  r10,r10,32
143         addi  r9,r9,32
145         lvx   v22,0,r10
146         lvx   v23,0,r9
147         addi  r10,r10,32
148         addi  r9,r9,32
150         lvx   v24,0,r10
151         lvx   v25,0,r9
152         addi  r10,r10,32
153         addi  r9,r9,32
155         lvx   v26,0,r10
156         lvx   v27,0,r9
157         addi  r10,r10,32
158         addi  r9,r9,32
160         lvx   v28,0,r10
161         lvx   v29,0,r9
162         addi  r10,r10,32
163         addi  r9,r9,32
165         lvx   v30,0,r10
166         lvx   v31,0,r9
167         addi  r10,r10,32
168         addi  r9,r9,32
170         lvx   v10,0,r10
171         lvx   v11,0,r9
173 L(has_no_vec):
174         /* Restore the floating-point registers */
175         lfd     fp31,_UC_FREGS+(32*8)(r31)
176         lfd     fp0,_UC_FREGS+(0*8)(r31)
177         mtfsf   0xff,fp31
178         lfd     fp1,_UC_FREGS+(1*8)(r31)
179         lfd     fp2,_UC_FREGS+(2*8)(r31)
180         lfd     fp3,_UC_FREGS+(3*8)(r31)
181         lfd     fp4,_UC_FREGS+(4*8)(r31)
182         lfd     fp5,_UC_FREGS+(5*8)(r31)
183         lfd     fp6,_UC_FREGS+(6*8)(r31)
184         lfd     fp7,_UC_FREGS+(7*8)(r31)
185         lfd     fp8,_UC_FREGS+(8*8)(r31)
186         lfd     fp9,_UC_FREGS+(9*8)(r31)
187         lfd     fp10,_UC_FREGS+(10*8)(r31)
188         lfd     fp11,_UC_FREGS+(11*8)(r31)
189         lfd     fp12,_UC_FREGS+(12*8)(r31)
190         lfd     fp13,_UC_FREGS+(13*8)(r31)
191         lfd     fp14,_UC_FREGS+(14*8)(r31)
192         lfd     fp15,_UC_FREGS+(15*8)(r31)
193         lfd     fp16,_UC_FREGS+(16*8)(r31)
194         lfd     fp17,_UC_FREGS+(17*8)(r31)
195         lfd     fp18,_UC_FREGS+(18*8)(r31)
196         lfd     fp19,_UC_FREGS+(19*8)(r31)
197         lfd     fp20,_UC_FREGS+(20*8)(r31)
198         lfd     fp21,_UC_FREGS+(21*8)(r31)
199         lfd     fp22,_UC_FREGS+(22*8)(r31)
200         lfd     fp23,_UC_FREGS+(23*8)(r31)
201         lfd     fp24,_UC_FREGS+(24*8)(r31)
202         lfd     fp25,_UC_FREGS+(25*8)(r31)
203         lfd     fp26,_UC_FREGS+(26*8)(r31)
204         lfd     fp27,_UC_FREGS+(27*8)(r31)
205         lfd     fp28,_UC_FREGS+(28*8)(r31)
206         lfd     fp29,_UC_FREGS+(29*8)(r31)
207         lfd     fp30,_UC_FREGS+(30*8)(r31)
208         lfd     fp31,_UC_FREGS+(31*8)(r31)
210         /* Restore LR and CCR, and set CTR to the NIP value */
211         lwz     r3,_UC_GREGS+(PT_LNK*4)(r31)
212         lwz     r4,_UC_GREGS+(PT_NIP*4)(r31)
213         lwz     r5,_UC_GREGS+(PT_CCR*4)(r31)
214         mtlr    r3
215         mtctr   r4
216         mtcr    r5
218         /* Restore the general registers */
219         lwz     r1,_UC_GREGS+(PT_R1*4)(r31)
220         lwz     r3,_UC_GREGS+(PT_R3*4)(r31)
221         lwz     r4,_UC_GREGS+(PT_R4*4)(r31)
222         lwz     r5,_UC_GREGS+(PT_R5*4)(r31)
223         lwz     r6,_UC_GREGS+(PT_R6*4)(r31)
224         lwz     r7,_UC_GREGS+(PT_R7*4)(r31)
225         lwz     r8,_UC_GREGS+(PT_R8*4)(r31)
226         lwz     r9,_UC_GREGS+(PT_R9*4)(r31)
227         lwz     r10,_UC_GREGS+(PT_R10*4)(r31)
228         lwz     r11,_UC_GREGS+(PT_R11*4)(r31)
229         lwz     r12,_UC_GREGS+(PT_R12*4)(r31)
230         lwz     r13,_UC_GREGS+(PT_R13*4)(r31)
231         lwz     r14,_UC_GREGS+(PT_R14*4)(r31)
232         lwz     r15,_UC_GREGS+(PT_R15*4)(r31)
233         lwz     r16,_UC_GREGS+(PT_R16*4)(r31)
234         lwz     r17,_UC_GREGS+(PT_R17*4)(r31)
235         lwz     r18,_UC_GREGS+(PT_R18*4)(r31)
236         lwz     r19,_UC_GREGS+(PT_R19*4)(r31)
237         lwz     r20,_UC_GREGS+(PT_R20*4)(r31)
238         lwz     r21,_UC_GREGS+(PT_R21*4)(r31)
239         lwz     r22,_UC_GREGS+(PT_R22*4)(r31)
240         lwz     r23,_UC_GREGS+(PT_R23*4)(r31)
241         lwz     r24,_UC_GREGS+(PT_R24*4)(r31)
242         lwz     r25,_UC_GREGS+(PT_R25*4)(r31)
243         lwz     r26,_UC_GREGS+(PT_R26*4)(r31)
244         lwz     r27,_UC_GREGS+(PT_R27*4)(r31)
245         lwz     r28,_UC_GREGS+(PT_R28*4)(r31)
246         lwz     r29,_UC_GREGS+(PT_R29*4)(r31)
247         lwz     r30,_UC_GREGS+(PT_R30*4)(r31)
248         lwz     r31,_UC_GREGS+(PT_R31*4)(r31)
250         bctr
252 L(error_exit):
253         lwz     r31,12(r1)
254         lwz     r0,20(r1)
255         addi    r1,r1,16
256         mtlr    r0
257         blr
259 L(do_sigret):
260         addi    r1,r3,-0xd0
261         li      r0,SYS_ify(rt_sigreturn)
262         sc
263         /* NOTREACHED */
265 END (__setcontext)
267 versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)
269 #if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
271         compat_text_section
272 ENTRY(__novec_setcontext)
273         mflr    r0
274         stwu    r1,-16(r1)
275         stw     r0,20(r1)
276         stw     r31,12(r1)
277         lwz     r31,_UC_REGS_PTR(r3)
279         /*
280          * If this ucontext refers to the point where we were interrupted
281          * by a signal, we have to use the rt_sigreturn system call to
282          * return to the context so we get both LR and CTR restored.
283          *
284          * Otherwise, the context we are restoring is either just after
285          * a procedure call (getcontext/swapcontext) or at the beginning
286          * of a procedure call (makecontext), so we don't need to restore
287          * r0, xer, ctr.  We don't restore r2 since it will be used as
288          * the TLS pointer.
289          */
290         lwz     r0,_UC_GREGS+(PT_MSR*4)(r31)
291         cmpwi   r0,0
292         bne     L(novec_do_sigret)
294         /* Restore the signal mask */
295         li      r5,0
296         addi    r4,r3,_UC_SIGMASK
297         li      r3,SIG_SETMASK
298         bl      JUMPTARGET(__sigprocmask)
299         cmpwi   r3,0
300         bne     L(novec_error_exit)
302         /* Restore the floating-point registers */
303         lfd     fp31,_UC_FREGS+(32*8)(r31)
304         lfd     fp0,_UC_FREGS+(0*8)(r31)
305         mtfsf   0xff,fp31
306         lfd     fp1,_UC_FREGS+(1*8)(r31)
307         lfd     fp2,_UC_FREGS+(2*8)(r31)
308         lfd     fp3,_UC_FREGS+(3*8)(r31)
309         lfd     fp4,_UC_FREGS+(4*8)(r31)
310         lfd     fp5,_UC_FREGS+(5*8)(r31)
311         lfd     fp6,_UC_FREGS+(6*8)(r31)
312         lfd     fp7,_UC_FREGS+(7*8)(r31)
313         lfd     fp8,_UC_FREGS+(8*8)(r31)
314         lfd     fp9,_UC_FREGS+(9*8)(r31)
315         lfd     fp10,_UC_FREGS+(10*8)(r31)
316         lfd     fp11,_UC_FREGS+(11*8)(r31)
317         lfd     fp12,_UC_FREGS+(12*8)(r31)
318         lfd     fp13,_UC_FREGS+(13*8)(r31)
319         lfd     fp14,_UC_FREGS+(14*8)(r31)
320         lfd     fp15,_UC_FREGS+(15*8)(r31)
321         lfd     fp16,_UC_FREGS+(16*8)(r31)
322         lfd     fp17,_UC_FREGS+(17*8)(r31)
323         lfd     fp18,_UC_FREGS+(18*8)(r31)
324         lfd     fp19,_UC_FREGS+(19*8)(r31)
325         lfd     fp20,_UC_FREGS+(20*8)(r31)
326         lfd     fp21,_UC_FREGS+(21*8)(r31)
327         lfd     fp22,_UC_FREGS+(22*8)(r31)
328         lfd     fp23,_UC_FREGS+(23*8)(r31)
329         lfd     fp24,_UC_FREGS+(24*8)(r31)
330         lfd     fp25,_UC_FREGS+(25*8)(r31)
331         lfd     fp26,_UC_FREGS+(26*8)(r31)
332         lfd     fp27,_UC_FREGS+(27*8)(r31)
333         lfd     fp28,_UC_FREGS+(28*8)(r31)
334         lfd     fp29,_UC_FREGS+(29*8)(r31)
335         lfd     fp30,_UC_FREGS+(30*8)(r31)
336         lfd     fp31,_UC_FREGS+(31*8)(r31)
338         /* Restore LR and CCR, and set CTR to the NIP value */
339         lwz     r3,_UC_GREGS+(PT_LNK*4)(r31)
340         lwz     r4,_UC_GREGS+(PT_NIP*4)(r31)
341         lwz     r5,_UC_GREGS+(PT_CCR*4)(r31)
342         mtlr    r3
343         mtctr   r4
344         mtcr    r5
346         /* Restore the general registers */
347         lwz     r1,_UC_GREGS+(PT_R1*4)(r31)
348         lwz     r3,_UC_GREGS+(PT_R3*4)(r31)
349         lwz     r4,_UC_GREGS+(PT_R4*4)(r31)
350         lwz     r5,_UC_GREGS+(PT_R5*4)(r31)
351         lwz     r6,_UC_GREGS+(PT_R6*4)(r31)
352         lwz     r7,_UC_GREGS+(PT_R7*4)(r31)
353         lwz     r8,_UC_GREGS+(PT_R8*4)(r31)
354         lwz     r9,_UC_GREGS+(PT_R9*4)(r31)
355         lwz     r10,_UC_GREGS+(PT_R10*4)(r31)
356         lwz     r11,_UC_GREGS+(PT_R11*4)(r31)
357         lwz     r12,_UC_GREGS+(PT_R12*4)(r31)
358         lwz     r13,_UC_GREGS+(PT_R13*4)(r31)
359         lwz     r14,_UC_GREGS+(PT_R14*4)(r31)
360         lwz     r15,_UC_GREGS+(PT_R15*4)(r31)
361         lwz     r16,_UC_GREGS+(PT_R16*4)(r31)
362         lwz     r17,_UC_GREGS+(PT_R17*4)(r31)
363         lwz     r18,_UC_GREGS+(PT_R18*4)(r31)
364         lwz     r19,_UC_GREGS+(PT_R19*4)(r31)
365         lwz     r20,_UC_GREGS+(PT_R20*4)(r31)
366         lwz     r21,_UC_GREGS+(PT_R21*4)(r31)
367         lwz     r22,_UC_GREGS+(PT_R22*4)(r31)
368         lwz     r23,_UC_GREGS+(PT_R23*4)(r31)
369         lwz     r24,_UC_GREGS+(PT_R24*4)(r31)
370         lwz     r25,_UC_GREGS+(PT_R25*4)(r31)
371         lwz     r26,_UC_GREGS+(PT_R26*4)(r31)
372         lwz     r27,_UC_GREGS+(PT_R27*4)(r31)
373         lwz     r28,_UC_GREGS+(PT_R28*4)(r31)
374         lwz     r29,_UC_GREGS+(PT_R29*4)(r31)
375         lwz     r30,_UC_GREGS+(PT_R30*4)(r31)
376         lwz     r31,_UC_GREGS+(PT_R31*4)(r31)
378         bctr
380 L(novec_error_exit):
381         lwz     r31,12(r1)
382         lwz     r0,20(r1)
383         addi    r1,r1,16
384         mtlr    r0
385         blr
387 L(novec_do_sigret):
388         addi    r1,r3,-0xd0
389         li      r0,SYS_ify(rt_sigreturn)
390         sc
391         /* NOTREACHED */
393 END (__novec_setcontext)
394         .previous
396 compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3_3)
398 #endif
400 #if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_3)
402 #define _ERRNO_H        1
403 #include <bits/errno.h>
405         compat_text_section
406 ENTRY (__setcontext_stub)
407         li      r3,ENOSYS
408         b       JUMPTARGET(__syscall_error)
409 END (__setcontext_stub)
410         .previous
412 compat_symbol (libc, __setcontext_stub, setcontext, GLIBC_2_0)
414 #endif