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