]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / powerpc / powerpc64 / swapcontext.S
CommitLineData
609b4783 1/* Save current context and install the given one.
6d7e8eda 2 Copyright (C) 2002-2023 Free Software Foundation, Inc.
609b4783
UD
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
59ba27a6 16 License along with the GNU C Library; if not, see
5a82c748 17 <https://www.gnu.org/licenses/>. */
609b4783
UD
18
19#include <sysdep.h>
5ef6ae4b
UD
20#include <rtld-global-offsets.h>
21#include <shlib-compat.h>
609b4783
UD
22
23#define __ASSEMBLY__
24#include <asm/ptrace.h>
25#include "ucontext_i.h"
38e68573 26#include <asm/errno.h>
609b4783 27
edba7a54
UD
28 .section ".toc","aw"
29.LC__dl_hwcap:
30#ifdef SHARED
31 .tc _rtld_global_ro[TC],_rtld_global_ro
32#else
33 .tc _dl_hwcap[TC],_dl_hwcap
34#endif
35
5ef6ae4b 36#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
edba7a54 37 .section ".text"
5ef6ae4b 38ENTRY(__novec_swapcontext)
865d953f 39 CALL_MCOUNT 2
5ef6ae4b
UD
40 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
41 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
42 mflr r0
43 std r31,-8(1)
3e7e947f 44 cfi_offset(r31,-8)
5ef6ae4b
UD
45 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
46 std r0,FRAME_LR_SAVE(r1)
a7e91561 47 cfi_offset (lr, FRAME_LR_SAVE)
5ef6ae4b
UD
48 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
49 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
50 stdu r1,-128(r1)
a7e91561 51 cfi_adjust_cfa_offset (128)
5ef6ae4b
UD
52 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
53 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
54 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
55 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
56 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
57 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
58 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
59 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
60 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
61 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
62 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
63 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
64 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
65 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
66 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
67 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
68 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
69 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
70 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
71 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
72 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
73 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
74 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
75 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
76 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
77 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
78 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
79 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
80 mfctr r0
81 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
82 mfxer r0
83 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
84 mfcr r0
85 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
afdca0f2
UD
86
87 /* Set the return value of swapcontext to "success". R3 is the only
5ef6ae4b
UD
88 register whose value is not preserved in the saved context. */
89 li r0,0
90 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
afdca0f2 91
5ef6ae4b
UD
92 /* Zero fill fields that can't be set in user state or are unused. */
93 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
94 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
95 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
96 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
97 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
98 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
99 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
afdca0f2
UD
100
101 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
102 field. Struct pt_regs and elf_gregset_t are the same thing.
5ef6ae4b
UD
103 We kept the regs field for backwards compatibility with
104 libraries built before we extended sigcontext. */
105 addi r0,r3,SIGCONTEXT_GP_REGS
106 std r0,SIGCONTEXT_PT_REGS(r3)
afdca0f2 107
5ef6ae4b
UD
108 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
109 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
110 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
111 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
112 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
113 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
114 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
115 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
116 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
117 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
118 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
119 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
120 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
121 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
122 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
123 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
124 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
125 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
126 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
127 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
128 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
129 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
130 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
131 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
132 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
133 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
134 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
135 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
136 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
b86d92c0 137 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
5ef6ae4b
UD
138 mffs fp0
139 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
140 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
141 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
142
143 mr r31,r4
144 addi r5,r3,UCONTEXT_SIGMASK
145 addi r4,r4,UCONTEXT_SIGMASK
146 li r3,SIG_SETMASK
d980f41a 147 bl JUMPTARGET(__sigprocmask)
5ef6ae4b
UD
148 nop
149 cmpdi r3,0
150 bne L(nv_error_exit)
151
cbc06bc4 152 ld r8,.LC__dl_hwcap@toc(r2)
edba7a54
UD
153# ifdef SHARED
154/* Load _rtld-global._dl_hwcap. */
155 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
156# else
157 ld r8,0(r8) /* Load extern _dl_hwcap. */
158# endif
159
5ef6ae4b 160 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
afdca0f2 161 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
5ef6ae4b 162 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
db8fed87 163
edba7a54
UD
164# ifdef _ARCH_PWR6
165 /* Use the extended four-operand version of the mtfsf insn. */
bddec78c
UD
166 .machine push
167 .machine "power6"
db8fed87
MS
168
169 mtfsf 0xff,fp0,1,0
170
171 .machine pop
172# else
edba7a54
UD
173 /* Availability of DFP indicates a 64-bit FPSCR. */
174 andi. r6,r8,PPC_FEATURE_HAS_DFP
175 beq 5f
db8fed87
MS
176
177 .machine push
178 .machine "power6"
179
edba7a54 180 mtfsf 0xff,fp0,1,0
db8fed87
MS
181
182 .machine pop
183
edba7a54
UD
184 b 6f
185 /* Continue to operate on the FPSCR as if it were 32-bits. */
1865:
5ef6ae4b 187 mtfsf 0xff,fp0
edba7a54
UD
1886:
189#endif /* _ARCH_PWR6 */
db8fed87 190
afdca0f2 191 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
5ef6ae4b 192 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
afdca0f2 193 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
5ef6ae4b 194 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
afdca0f2 195 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
5ef6ae4b 196 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
afdca0f2 197 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
5ef6ae4b 198 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
afdca0f2 199 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
5ef6ae4b 200 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
afdca0f2 201 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
5ef6ae4b 202 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
afdca0f2 203 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
5ef6ae4b 204 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
afdca0f2 205 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
5ef6ae4b 206 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
afdca0f2 207 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
5ef6ae4b 208 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
afdca0f2 209 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
5ef6ae4b 210 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
afdca0f2 211 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
5ef6ae4b 212 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
afdca0f2 213 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
5ef6ae4b 214 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
afdca0f2 215 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
5ef6ae4b 216 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
afdca0f2 217 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
5ef6ae4b 218 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
afdca0f2 219 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
5ef6ae4b 220 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
afdca0f2
UD
221
222 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
5ef6ae4b
UD
223 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
224 mtlr r0
225 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
226 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
227 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
228 mtxer r0
229 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
230 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
231 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
16cc1800 232 mtcr r0
5ef6ae4b
UD
233 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
234 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
235 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
236 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
237 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
238 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
239 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
240 /* Don't reload the thread ID or TLS pointer (r13). */
241 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
242 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
243 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
244 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
245 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
246 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
247 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
248 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
249 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
250 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
251 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
252 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
253 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
254 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
255 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
256 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
257 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
afdca0f2 258
5ef6ae4b 259 /* Now we branch to the "Next Instruction Pointer" from the saved
afdca0f2 260 context. With the powerpc64 instruction set there is no good way to
5ef6ae4b 261 do this (from user state) without clobbering either the LR or CTR.
afdca0f2 262 The makecontext and swapcontext functions depend on the callers
5ef6ae4b
UD
263 LR being preserved so we use the CTR. */
264 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
265 mtctr r0
266 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
267 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
268 bctr
afdca0f2 269
5ef6ae4b 270L(nv_error_exit):
afdca0f2 271 ld r0,128+FRAME_LR_SAVE(r1)
5ef6ae4b
UD
272 addi r1,r1,128
273 mtlr r0
274 ld r31,-8(r1)
275 blr
276
5ef6ae4b
UD
277PSEUDO_END(__novec_swapcontext)
278
279compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
280
281#endif
282
5ef6ae4b 283 .section ".text"
f2bfeadf 284 .machine "altivec"
609b4783 285ENTRY(__swapcontext)
865d953f 286 CALL_MCOUNT 2
609b4783
UD
287 std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
288 std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
289 mflr r0
290 std r31,-8(1)
3e7e947f 291 cfi_offset(r31,-8)
609b4783
UD
292 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
293 std r0,FRAME_LR_SAVE(r1)
3e7e947f 294 cfi_offset (lr, FRAME_LR_SAVE)
609b4783
UD
295 std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
296 std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
297 stdu r1,-128(r1)
3e7e947f 298 cfi_adjust_cfa_offset(128)
609b4783
UD
299 std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
300 std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
301 std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
302 std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
303 std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
304 std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
305 std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
306 std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
307 std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
308 std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
309 std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
310 std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
311 std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
312 std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
313 std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
314 std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
315 std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
316 std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
317 std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
318 std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
319 std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
320 std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
321 std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
322 std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
323 std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
324 std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
325 std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
326 std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
327 mfctr r0
328 std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
329 mfxer r0
330 std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
331 mfcr r0
332 std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
afdca0f2
UD
333
334 /* Set the return value of swapcontext to "success". R3 is the only
609b4783
UD
335 register whose value is not preserved in the saved context. */
336 li r0,0
337 std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
afdca0f2 338
609b4783
UD
339 /* Zero fill fields that can't be set in user state or are unused. */
340 std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
341 std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
342 std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
343 std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
344 std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
345 std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
346 std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
afdca0f2
UD
347
348 /* Set the PT_REGS pointer to the address of sigcontext gp_regs
349 field. Struct pt_regs and elf_gregset_t are the same thing.
609b4783
UD
350 We kept the regs field for backwards compatibility with
351 libraries built before we extended sigcontext. */
352 addi r0,r3,SIGCONTEXT_GP_REGS
353 std r0,SIGCONTEXT_PT_REGS(r3)
afdca0f2 354
609b4783
UD
355 stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
356 stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
357 stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
358 stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
359 stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
360 stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
361 stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
362 stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
363 stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
364 stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
365 stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
366 stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
367 stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
368 stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
369 stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
370 stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
371 stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
372 stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
373 stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
374 stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
375 stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
376 stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
377 stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
378 stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
379 stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
380 stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
381 stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
382 stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
383 stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
b86d92c0 384 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
609b4783
UD
385 mffs fp0
386 stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
387 stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
388 stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
afdca0f2 389
5ef6ae4b 390 ld r8,.LC__dl_hwcap@toc(r2)
afdca0f2 391#ifdef SHARED
5ef6ae4b 392/* Load _rtld-global._dl_hwcap. */
ef690add 393 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
afdca0f2 394#else
5ef6ae4b
UD
395 ld r8,0(r8) /* Load extern _dl_hwcap. */
396#endif
5ef6ae4b
UD
397 la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
398 la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
fb9d5c73 399
edba7a54 400 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
e1ad4c53 401
5ef6ae4b 402 clrrdi r10,r10,4
e1ad4c53 403 beq L(has_no_vec)
fb9d5c73 404
5ef6ae4b 405 clrrdi r9,r9,4
e1ad4c53 406 mr r8,r10 /* Capture *v_regs value in r5. */
afdca0f2
UD
407
408 stvx v0,0,r10
5ef6ae4b
UD
409 stvx v1,0,r9
410 addi r10,r10,32
411 addi r9,r9,32
afdca0f2
UD
412
413 stvx v2,0,r10
5ef6ae4b
UD
414 stvx v3,0,r9
415 addi r10,r10,32
416 addi r9,r9,32
afdca0f2
UD
417
418 stvx v4,0,r10
5ef6ae4b
UD
419 stvx v5,0,r9
420 addi r10,r10,32
421 addi r9,r9,32
afdca0f2
UD
422
423 stvx v6,0,r10
5ef6ae4b
UD
424 stvx v7,0,r9
425 addi r10,r10,32
426 addi r9,r9,32
afdca0f2
UD
427
428 stvx v8,0,r10
5ef6ae4b
UD
429 stvx v9,0,r9
430 addi r10,r10,32
431 addi r9,r9,32
afdca0f2
UD
432
433 stvx v10,0,r10
5ef6ae4b
UD
434 stvx v11,0,r9
435 addi r10,r10,32
436 addi r9,r9,32
afdca0f2
UD
437
438 stvx v12,0,r10
5ef6ae4b
UD
439 stvx v13,0,r9
440 addi r10,r10,32
441 addi r9,r9,32
afdca0f2
UD
442
443 stvx v14,0,r10
5ef6ae4b
UD
444 stvx v15,0,r9
445 addi r10,r10,32
446 addi r9,r9,32
afdca0f2
UD
447
448 stvx v16,0,r10
5ef6ae4b
UD
449 stvx v17,0,r9
450 addi r10,r10,32
451 addi r9,r9,32
afdca0f2
UD
452
453 stvx v18,0,r10
e1ad4c53
RM
454 stvx v19,0,r9
455 addi r10,r10,32
5ef6ae4b 456 addi r9,r9,32
afdca0f2
UD
457
458 stvx v20,0,r10
5ef6ae4b
UD
459 stvx v21,0,r9
460 addi r10,r10,32
461 addi r9,r9,32
afdca0f2
UD
462
463 stvx v22,0,r10
5ef6ae4b
UD
464 stvx v23,0,r9
465 addi r10,r10,32
466 addi r9,r9,32
afdca0f2
UD
467
468 stvx v24,0,r10
5ef6ae4b
UD
469 stvx v25,0,r9
470 addi r10,r10,32
471 addi r9,r9,32
afdca0f2
UD
472
473 stvx v26,0,r10
5ef6ae4b
UD
474 stvx v27,0,r9
475 addi r10,r10,32
476 addi r9,r9,32
afdca0f2
UD
477
478 stvx v28,0,r10
5ef6ae4b
UD
479 stvx v29,0,r9
480 addi r10,r10,32
481 addi r9,r9,32
afdca0f2
UD
482
483 stvx v30,0,r10
5ef6ae4b
UD
484 stvx v31,0,r9
485 addi r10,r10,32
486 addi r9,r9,32
afdca0f2 487
5ef6ae4b
UD
488 mfvscr v0
489 mfspr r0,VRSAVE
490 stvx v0,0,r10
fb9d5c73 491 stw r0,0(r9)
afdca0f2 492
5ef6ae4b 493L(has_no_vec):
afdca0f2 494/*
5ef6ae4b
UD
495 Store either a NULL or a quadword aligned pointer to the Vector register
496 array into *v_regs.
497*/
e1ad4c53 498 std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
609b4783
UD
499
500 mr r31,r4
501 addi r5,r3,UCONTEXT_SIGMASK
502 addi r4,r4,UCONTEXT_SIGMASK
503 li r3,SIG_SETMASK
d980f41a 504 bl JUMPTARGET(__sigprocmask)
609b4783
UD
505 nop
506 cmpdi r3,0
507 bne L(error_exit)
508
5ef6ae4b
UD
509 ld r8,.LC__dl_hwcap@toc(r2)
510 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
ef690add 511# ifdef SHARED
5ef6ae4b 512/* Load _rtld-global._dl_hwcap. */
ef690add
UD
513 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
514# else
5ef6ae4b 515 ld r8,0(r8) /* Load extern _dl_hwcap. */
ef690add 516# endif
edba7a54 517 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
5ef6ae4b 518 beq L(has_no_vec2)
afdca0f2 519
5ef6ae4b
UD
520 cmpdi r10,0
521 beq L(has_no_vec2)
522 lwz r0,(33*16)(r10)
afdca0f2 523
5ef6ae4b
UD
524 li r9,(16*32)
525 mtspr VRSAVE,r0
526 cmpwi r0,0
afdca0f2
UD
527 beq L(has_no_vec2)
528
5ef6ae4b
UD
529 lvx v19,r9,r10
530 la r9,(16)(r10)
afdca0f2
UD
531
532 lvx v0,0,r10
5ef6ae4b
UD
533 lvx v1,0,r9
534 addi r10,r10,32
535 addi r9,r9,32
afdca0f2 536
5ef6ae4b 537 mtvscr v19
afdca0f2 538 lvx v2,0,r10
5ef6ae4b
UD
539 lvx v3,0,r9
540 addi r10,r10,32
541 addi r9,r9,32
afdca0f2
UD
542
543 lvx v4,0,r10
5ef6ae4b
UD
544 lvx v5,0,r9
545 addi r10,r10,32
546 addi r9,r9,32
afdca0f2
UD
547
548 lvx v6,0,r10
5ef6ae4b
UD
549 lvx v7,0,r9
550 addi r10,r10,32
551 addi r9,r9,32
afdca0f2
UD
552
553 lvx v8,0,r10
5ef6ae4b
UD
554 lvx v9,0,r9
555 addi r10,r10,32
556 addi r9,r9,32
afdca0f2
UD
557
558 lvx v10,0,r10
5ef6ae4b
UD
559 lvx v11,0,r9
560 addi r10,r10,32
561 addi r9,r9,32
afdca0f2
UD
562
563 lvx v12,0,r10
5ef6ae4b
UD
564 lvx v13,0,r9
565 addi r10,r10,32
566 addi r9,r9,32
afdca0f2
UD
567
568 lvx v14,0,r10
5ef6ae4b
UD
569 lvx v15,0,r9
570 addi r10,r10,32
571 addi r9,r9,32
afdca0f2
UD
572
573 lvx v16,0,r10
5ef6ae4b
UD
574 lvx v17,0,r9
575 addi r10,r10,32
576 addi r9,r9,32
afdca0f2
UD
577
578 lvx v18,0,r10
e1ad4c53
RM
579 lvx v19,0,r9
580 addi r10,r10,32
5ef6ae4b 581 addi r9,r9,32
afdca0f2
UD
582
583 lvx v20,0,r10
5ef6ae4b
UD
584 lvx v21,0,r9
585 addi r10,r10,32
586 addi r9,r9,32
afdca0f2
UD
587
588 lvx v22,0,r10
5ef6ae4b
UD
589 lvx v23,0,r9
590 addi r10,r10,32
591 addi r9,r9,32
afdca0f2
UD
592
593 lvx v24,0,r10
5ef6ae4b
UD
594 lvx v25,0,r9
595 addi r10,r10,32
596 addi r9,r9,32
afdca0f2
UD
597
598 lvx v26,0,r10
5ef6ae4b
UD
599 lvx v27,0,r9
600 addi r10,r10,32
601 addi r9,r9,32
afdca0f2
UD
602
603 lvx v28,0,r10
5ef6ae4b
UD
604 lvx v29,0,r9
605 addi r10,r10,32
606 addi r9,r9,32
afdca0f2
UD
607
608 lvx v30,0,r10
5ef6ae4b
UD
609 lvx v31,0,r9
610 addi r10,r10,32
611 addi r9,r9,32
afdca0f2
UD
612
613 lvx v10,0,r10
5ef6ae4b
UD
614 lvx v11,0,r9
615 addi r10,r10,32
616 addi r9,r9,32
afdca0f2 617
5ef6ae4b 618L(has_no_vec2):
609b4783
UD
619
620 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
afdca0f2 621 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
609b4783 622 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
db8fed87 623
edba7a54
UD
624# ifdef _ARCH_PWR6
625 /* Use the extended four-operand version of the mtfsf insn. */
bddec78c
UD
626 .machine push
627 .machine "power6"
db8fed87
MS
628
629 mtfsf 0xff,fp0,1,0
630
631 .machine pop
632# else
edba7a54
UD
633 /* Availability of DFP indicates a 64-bit FPSCR. */
634 andi. r6,r8,PPC_FEATURE_HAS_DFP
635 beq 7f
db8fed87
MS
636
637 .machine push
638 .machine "power6"
639
edba7a54 640 mtfsf 0xff,fp0,1,0
db8fed87
MS
641
642 .machine pop
643
edba7a54
UD
644 b 8f
645 /* Continue to operate on the FPSCR as if it were 32-bits. */
6467:
609b4783 647 mtfsf 0xff,fp0
edba7a54
UD
6488:
649#endif /* _ARCH_PWR6 */
db8fed87 650
afdca0f2 651 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
609b4783 652 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
afdca0f2 653 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
609b4783 654 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
afdca0f2 655 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
609b4783 656 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
afdca0f2 657 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
609b4783 658 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
afdca0f2 659 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
609b4783 660 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
afdca0f2 661 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
609b4783 662 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
afdca0f2 663 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
609b4783 664 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
afdca0f2 665 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
609b4783 666 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
afdca0f2 667 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
609b4783 668 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
afdca0f2 669 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
609b4783 670 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
afdca0f2 671 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
609b4783 672 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
afdca0f2 673 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
609b4783 674 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
afdca0f2 675 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
609b4783 676 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
afdca0f2 677 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
609b4783 678 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
afdca0f2 679 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
609b4783 680 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
afdca0f2
UD
681
682 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
609b4783
UD
683 ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
684 mtlr r0
685 ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
686 ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
687 ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
688 mtxer r0
689 ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
690 ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
691 ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
609b4783
UD
692 ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
693 ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
694 ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
695 ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
16cc1800 696 mtcr r0
609b4783
UD
697 ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
698 ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
699 ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
700 /* Don't reload the thread ID or TLS pointer (r13). */
701 ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
702 ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
703 ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
704 ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
705 ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
706 ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
707 ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
708 ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
709 ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
710 ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
711 ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
712 ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
713 ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
714 ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
715 ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
716 ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
717 ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
afdca0f2 718
609b4783 719 /* Now we branch to the "Next Instruction Pointer" from the saved
afdca0f2 720 context. With the powerpc64 instruction set there is no good way to
609b4783 721 do this (from user state) without clobbering either the LR or CTR.
afdca0f2 722 The makecontext and swapcontext functions depend on the callers
609b4783
UD
723 LR being preserved so we use the CTR. */
724 ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
725 mtctr r0
726 ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
727 ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
728 bctr
afdca0f2 729
609b4783 730L(error_exit):
afdca0f2 731 ld r0,128+FRAME_LR_SAVE(r1)
609b4783
UD
732 addi r1,r1,128
733 mtlr r0
734 ld r31,-8(r1)
735 blr
736
609b4783
UD
737PSEUDO_END(__swapcontext)
738
5ef6ae4b 739versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)