Add missing export of fallocate64 on 32-bit platforms.
[glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc32 / getcontext-common.S
blob63e1773e22cf13d829af1a37d2bb8bde8da7aa7a
1 /* Save current context, powerpc32 common.
2    Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston MA
18    02110-1301 USA.  */
20 /* This is the common implementation of getcontext for powerpc32.
21    It not complete in itself should be included in to a framework that 
22    defines:
23      __CONTEXT_FUNC_NAME
24    and if appropriate:
25      __CONTEXT_ENABLE_FPRS
26      __CONTEXT_ENABLE_VRS
27    Any archecture that implements the Vector unit is assumed to also 
28    implement the floating unit.  */
30 /* Stack frame offsets.  */
31 #define _FRAME_BACKCHAIN        0
32 #define _FRAME_LR_SAVE          4
33 #define _FRAME_PARM_SAVE1       8
34 #define _FRAME_PARM_SAVE2       12
35 #define _FRAME_PARM_SAVE3       16
36 #define _FRAME_PARM_SAVE4       20
38 #ifdef __CONTEXT_ENABLE_VRS
39         .machine        "altivec"
40 #endif
41 ENTRY(__CONTEXT_FUNC_NAME)
42         stwu    r1,-16(r1)
43         cfi_adjust_cfa_offset (16)
44 /* Insure that the _UC_REGS start on a quadword boundary.  */
45         stw     r3,_FRAME_PARM_SAVE1(r1)
46         addi    r3,r3,_UC_REG_SPACE+12
47         clrrwi  r3,r3,4
49 /* Save the general purpose registers */
50         stw     r0,_UC_GREGS+(PT_R0*4)(r3)
51         mflr    r0
52         stw     r2,_UC_GREGS+(PT_R2*4)(r3)
53         stw     r4,_UC_GREGS+(PT_R4*4)(r3)
54 /* Set the callers LR_SAVE, and the ucontext LR and NIP to the callers
55    return address.  */
56         stw     r0,_UC_GREGS+(PT_LNK*4)(r3)
57         stw     r0,_UC_GREGS+(PT_NIP*4)(r3)
58         stw     r0,_FRAME_LR_SAVE+16(r1)
59         cfi_offset (lr, _FRAME_LR_SAVE)
60         stw     r5,_UC_GREGS+(PT_R5*4)(r3)
61         stw     r6,_UC_GREGS+(PT_R6*4)(r3)
62         stw     r7,_UC_GREGS+(PT_R7*4)(r3)
63         stw     r8,_UC_GREGS+(PT_R8*4)(r3)
64         stw     r9,_UC_GREGS+(PT_R9*4)(r3)
65         stw     r10,_UC_GREGS+(PT_R10*4)(r3)
66         stw     r11,_UC_GREGS+(PT_R11*4)(r3)
67         stw     r12,_UC_GREGS+(PT_R12*4)(r3)
68         stw     r13,_UC_GREGS+(PT_R13*4)(r3)
69         stw     r14,_UC_GREGS+(PT_R14*4)(r3)
70         stw     r15,_UC_GREGS+(PT_R15*4)(r3)
71         stw     r16,_UC_GREGS+(PT_R16*4)(r3)
72         stw     r17,_UC_GREGS+(PT_R17*4)(r3)
73         stw     r18,_UC_GREGS+(PT_R18*4)(r3)
74         stw     r19,_UC_GREGS+(PT_R19*4)(r3)
75         stw     r20,_UC_GREGS+(PT_R20*4)(r3)
76         stw     r21,_UC_GREGS+(PT_R21*4)(r3)
77         stw     r22,_UC_GREGS+(PT_R22*4)(r3)
78         stw     r23,_UC_GREGS+(PT_R23*4)(r3)
79         stw     r24,_UC_GREGS+(PT_R24*4)(r3)
80         stw     r25,_UC_GREGS+(PT_R25*4)(r3)
81         stw     r26,_UC_GREGS+(PT_R26*4)(r3)
82         stw     r27,_UC_GREGS+(PT_R27*4)(r3)
83         stw     r28,_UC_GREGS+(PT_R28*4)(r3)
84         stw     r29,_UC_GREGS+(PT_R29*4)(r3)
85         stw     r30,_UC_GREGS+(PT_R30*4)(r3)
86         stw     r31,_UC_GREGS+(PT_R31*4)(r3)
87 /* Save the value of R1.  We had to push the stack before we
88    had the address of uc_reg_space.  So compute the address of
89    the callers stack pointer and save it as R1.  */
90         addi    r8,r1,16
91         li      r0,0
92 /* Save the count, exception and condition registers.  */
93         mfctr   r11
94         mfxer   r10
95         mfcr    r9
96         stw     r8,_UC_GREGS+(PT_R1*4)(r3)
97         stw     r11,_UC_GREGS+(PT_CTR*4)(r3)
98         stw     r10,_UC_GREGS+(PT_XER*4)(r3)
99         stw     r9,_UC_GREGS+(PT_CCR*4)(r3)
100 /* Set the return value of getcontext to "success".  R3 is the only
101    register whose value is not preserved in the saved context.  */
102         stw     r0,_UC_GREGS+(PT_R3*4)(r3)
104 /* Zero fill fields that can't be set in user state. */
105         stw     r0,_UC_GREGS+(PT_MSR*4)(r3)
106         stw     r0,_UC_GREGS+(PT_MQ*4)(r3)
108 #ifdef __CONTEXT_ENABLE_FPRS
109 /* Save the floating-point registers */
110         stfd    fp0,_UC_FREGS+(0*8)(r3)
111         stfd    fp1,_UC_FREGS+(1*8)(r3)
112         stfd    fp2,_UC_FREGS+(2*8)(r3)
113         stfd    fp3,_UC_FREGS+(3*8)(r3)
114         stfd    fp4,_UC_FREGS+(4*8)(r3)
115         stfd    fp5,_UC_FREGS+(5*8)(r3)
116         stfd    fp6,_UC_FREGS+(6*8)(r3)
117         stfd    fp7,_UC_FREGS+(7*8)(r3)
118         stfd    fp8,_UC_FREGS+(8*8)(r3)
119         stfd    fp9,_UC_FREGS+(9*8)(r3)
120         stfd    fp10,_UC_FREGS+(10*8)(r3)
121         stfd    fp11,_UC_FREGS+(11*8)(r3)
122         stfd    fp12,_UC_FREGS+(12*8)(r3)
123         stfd    fp13,_UC_FREGS+(13*8)(r3)
124         stfd    fp14,_UC_FREGS+(14*8)(r3)
125         stfd    fp15,_UC_FREGS+(15*8)(r3)
126         stfd    fp16,_UC_FREGS+(16*8)(r3)
127         stfd    fp17,_UC_FREGS+(17*8)(r3)
128         stfd    fp18,_UC_FREGS+(18*8)(r3)
129         stfd    fp19,_UC_FREGS+(19*8)(r3)
130         stfd    fp20,_UC_FREGS+(20*8)(r3)
131         stfd    fp21,_UC_FREGS+(21*8)(r3)
132         stfd    fp22,_UC_FREGS+(22*8)(r3)
133         stfd    fp23,_UC_FREGS+(23*8)(r3)
134         stfd    fp24,_UC_FREGS+(24*8)(r3)
135         stfd    fp25,_UC_FREGS+(25*8)(r3)
136         stfd    fp26,_UC_FREGS+(26*8)(r3)
137         stfd    fp27,_UC_FREGS+(27*8)(r3)
138         stfd    fp28,_UC_FREGS+(28*8)(r3)
139         stfd    fp29,_UC_FREGS+(29*8)(r3)
140         mffs    fp0
141         stfd    fp30,_UC_FREGS+(30*8)(r3)
142         stfd    fp31,_UC_FREGS+(31*8)(r3)
143         stfd    fp0,_UC_FREGS+(32*8)(r3)
145 # ifdef __CONTEXT_ENABLE_VRS
146 #  ifdef PIC
147         mflr    r8
148 #   ifdef HAVE_ASM_PPC_REL16
149         bcl     20,31,1f
150 1:      mflr    r7
151         addis   r7,r7,_GLOBAL_OFFSET_TABLE_-1b@ha
152         addi    r7,r7,_GLOBAL_OFFSET_TABLE_-1b@l
153 #   else
154         bl      _GLOBAL_OFFSET_TABLE_@local-4
155         mflr    r7
156 #   endif
157 #   ifdef SHARED
158         lwz     r7,_rtld_global_ro@got(r7)
159         mtlr    r8
160         lwz     r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r7)
161 #   else
162         lwz     r7,_dl_hwcap@got(r7)
163         mtlr    r8
164         lwz     r7,4(r7)
165 #   endif
166 #  else
167         lis     r7,(_dl_hwcap+4)@ha
168         lwz     r7,(_dl_hwcap+4)@l(r7)
169 #  endif
170         andis.  r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
172         la      r10,(_UC_VREGS)(r3)
173         la      r9,(_UC_VREGS+16)(r3)
174         
175         beq     2f      /* L(no_vec) */
176 /* address of the combined VSCR/VSAVE quadword.  */     
177         la      r8,(_UC_VREGS+512)(r3)
179 /* Save the vector registers */
180         stvx  v0,0,r10
181         stvx  v1,0,r9
182         addi  r10,r10,32
183         addi  r9,r9,32
184 /* We need to get the Vector Status and Control Register early to avoid
185    store order problems later with the VSAVE register that shares the
186    same quadword.  */
187         mfvscr  v0
189         stvx  v2,0,r10
190         stvx  v3,0,r9
191         addi  r10,r10,32
192         addi  r9,r9,32
194         stvx    v0,0,r8
195         
196         stvx  v4,0,r10
197         stvx  v5,0,r9
198         addi  r10,r10,32
199         addi  r9,r9,32
201         stvx  v6,0,r10
202         stvx  v7,0,r9
203         addi  r10,r10,32
204         addi  r9,r9,32
206         stvx  v8,0,r10
207         stvx  v9,0,r9
208         addi  r10,r10,32
209         addi  r9,r9,32
211         stvx  v10,0,r10
212         stvx  v11,0,r9
213         addi  r10,r10,32
214         addi  r9,r9,32
216         stvx  v12,0,r10
217         stvx  v13,0,r9
218         addi  r10,r10,32
219         addi  r9,r9,32
221         stvx  v14,0,r10
222         stvx  v15,0,r9
223         addi  r10,r10,32
224         addi  r9,r9,32
226         stvx  v16,0,r10
227         stvx  v17,0,r9
228         addi  r10,r10,32
229         addi  r9,r9,32
231         stvx  v18,0,r10
232         stvx  v19,0,r9
233         addi  r10,r10,32
234         addi  r9,r9,32
236         stvx  v20,0,r10
237         stvx  v21,0,r9
238         addi  r10,r10,32
239         addi  r9,r9,32
241         stvx  v22,0,r10
242         stvx  v23,0,r9
243         addi  r10,r10,32
244         addi  r9,r9,32
246         stvx  v24,0,r10
247         stvx  v25,0,r9
248         addi  r10,r10,32
249         addi  r9,r9,32
251         stvx  v26,0,r10
252         stvx  v27,0,r9
253         addi  r10,r10,32
254         addi  r9,r9,32
256         stvx  v28,0,r10
257         stvx  v29,0,r9
258         addi  r10,r10,32
259         addi  r9,r9,32
261         mfspr   r0,VRSAVE
262         stvx  v30,0,r10
263         stvx  v31,0,r9
265         stw     r0,0(r8)
267 2: /* L(no_vec): */
268 # endif
269 #endif
270 /* We need to set up parms and call sigprocmask which will clobber
271    volatile registers. So before the call we need to retrieve the
272    original ucontext ptr (parm1) from stack and store the UC_REGS_PTR
273    (current R3).  */
274         lwz     r12,_FRAME_PARM_SAVE1(r1)
275         li      r4,0
276         stw     r3,_UC_REGS_PTR(r12)
277         addi    r5,r12,_UC_SIGMASK
278         li      r3,SIG_BLOCK
279         bl      __sigprocmask@local
281         lwz     r0,_FRAME_LR_SAVE+16(r1)
282         addi    r1,r1,16
283         mtlr    r0
284         blr
285 END(__CONTEXT_FUNC_NAME)