1/* Save current context and install the given one. 2 Copyright (C) 2002-2021 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 <https://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 "ucontext_i.h" 26#include <asm/errno.h> 27 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 36#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4) 37 .section ".text" 38ENTRY(__novec_swapcontext) 39 CALL_MCOUNT 2 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) 44 cfi_offset(r31,-8) 45 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) 46 std r0,FRAME_LR_SAVE(r1) 47 cfi_offset (lr, FRAME_LR_SAVE) 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) 51 cfi_adjust_cfa_offset (128) 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) 86 87 /* Set the return value of swapcontext to "success". R3 is the only 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) 91 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) 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. 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) 107 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) 137 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3) 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 147 bl JUMPTARGET(__sigprocmask) 148 nop 149 cmpdi r3,0 150 bne L(nv_error_exit) 151 152 ld r8,.LC__dl_hwcap@toc(r2) 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 160 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31) 161 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31) 162 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31) 163 164# ifdef _ARCH_PWR6 165 /* Use the extended four-operand version of the mtfsf insn. */ 166 .machine push 167 .machine "power6" 168 169 mtfsf 0xff,fp0,1,0 170 171 .machine pop 172# else 173 /* Availability of DFP indicates a 64-bit FPSCR. */ 174 andi. r6,r8,PPC_FEATURE_HAS_DFP 175 beq 5f 176 177 .machine push 178 .machine "power6" 179 180 mtfsf 0xff,fp0,1,0 181 182 .machine pop 183 184 b 6f 185 /* Continue to operate on the FPSCR as if it were 32-bits. */ 1865: 187 mtfsf 0xff,fp0 1886: 189#endif /* _ARCH_PWR6 */ 190 191 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31) 192 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31) 193 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31) 194 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31) 195 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31) 196 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31) 197 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31) 198 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31) 199 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31) 200 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31) 201 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31) 202 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31) 203 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31) 204 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31) 205 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31) 206 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31) 207 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31) 208 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31) 209 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31) 210 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31) 211 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31) 212 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31) 213 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31) 214 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31) 215 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31) 216 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31) 217 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31) 218 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31) 219 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31) 220 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31) 221 222 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31) 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) 232 mtcr r0 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) 258 259 /* Now we branch to the "Next Instruction Pointer" from the saved 260 context. With the powerpc64 instruction set there is no good way to 261 do this (from user state) without clobbering either the LR or CTR. 262 The makecontext and swapcontext functions depend on the callers 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 269 270L(nv_error_exit): 271 ld r0,128+FRAME_LR_SAVE(r1) 272 addi r1,r1,128 273 mtlr r0 274 ld r31,-8(r1) 275 blr 276 277PSEUDO_END(__novec_swapcontext) 278 279compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3) 280 281#endif 282 283 .section ".text" 284 .machine "altivec" 285ENTRY(__swapcontext) 286 CALL_MCOUNT 2 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) 291 cfi_offset(r31,-8) 292 std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3) 293 std r0,FRAME_LR_SAVE(r1) 294 cfi_offset (lr, FRAME_LR_SAVE) 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) 298 cfi_adjust_cfa_offset(128) 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) 333 334 /* Set the return value of swapcontext to "success". R3 is the only 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) 338 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) 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. 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) 354 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) 384 stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3) 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) 389 390 ld r8,.LC__dl_hwcap@toc(r2) 391#ifdef SHARED 392/* Load _rtld-global._dl_hwcap. */ 393 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8) 394#else 395 ld r8,0(r8) /* Load extern _dl_hwcap. */ 396#endif 397 la r10,(SIGCONTEXT_V_RESERVE+8)(r3) 398 la r9,(SIGCONTEXT_V_RESERVE+24)(r3) 399 400 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16) 401 402 clrrdi r10,r10,4 403 beq L(has_no_vec) 404 405 clrrdi r9,r9,4 406 mr r8,r10 /* Capture *v_regs value in r5. */ 407 408 stvx v0,0,r10 409 stvx v1,0,r9 410 addi r10,r10,32 411 addi r9,r9,32 412 413 stvx v2,0,r10 414 stvx v3,0,r9 415 addi r10,r10,32 416 addi r9,r9,32 417 418 stvx v4,0,r10 419 stvx v5,0,r9 420 addi r10,r10,32 421 addi r9,r9,32 422 423 stvx v6,0,r10 424 stvx v7,0,r9 425 addi r10,r10,32 426 addi r9,r9,32 427 428 stvx v8,0,r10 429 stvx v9,0,r9 430 addi r10,r10,32 431 addi r9,r9,32 432 433 stvx v10,0,r10 434 stvx v11,0,r9 435 addi r10,r10,32 436 addi r9,r9,32 437 438 stvx v12,0,r10 439 stvx v13,0,r9 440 addi r10,r10,32 441 addi r9,r9,32 442 443 stvx v14,0,r10 444 stvx v15,0,r9 445 addi r10,r10,32 446 addi r9,r9,32 447 448 stvx v16,0,r10 449 stvx v17,0,r9 450 addi r10,r10,32 451 addi r9,r9,32 452 453 stvx v18,0,r10 454 stvx v19,0,r9 455 addi r10,r10,32 456 addi r9,r9,32 457 458 stvx v20,0,r10 459 stvx v21,0,r9 460 addi r10,r10,32 461 addi r9,r9,32 462 463 stvx v22,0,r10 464 stvx v23,0,r9 465 addi r10,r10,32 466 addi r9,r9,32 467 468 stvx v24,0,r10 469 stvx v25,0,r9 470 addi r10,r10,32 471 addi r9,r9,32 472 473 stvx v26,0,r10 474 stvx v27,0,r9 475 addi r10,r10,32 476 addi r9,r9,32 477 478 stvx v28,0,r10 479 stvx v29,0,r9 480 addi r10,r10,32 481 addi r9,r9,32 482 483 stvx v30,0,r10 484 stvx v31,0,r9 485 addi r10,r10,32 486 addi r9,r9,32 487 488 mfvscr v0 489 mfspr r0,VRSAVE 490 stvx v0,0,r10 491 stw r0,0(r9) 492 493L(has_no_vec): 494/* 495 Store either a NULL or a quadword aligned pointer to the Vector register 496 array into *v_regs. 497*/ 498 std r8,(SIGCONTEXT_V_REGS_PTR)(r3) 499 500 mr r31,r4 501 addi r5,r3,UCONTEXT_SIGMASK 502 addi r4,r4,UCONTEXT_SIGMASK 503 li r3,SIG_SETMASK 504 bl JUMPTARGET(__sigprocmask) 505 nop 506 cmpdi r3,0 507 bne L(error_exit) 508 509 ld r8,.LC__dl_hwcap@toc(r2) 510 ld r10,(SIGCONTEXT_V_REGS_PTR)(r31) 511# ifdef SHARED 512/* Load _rtld-global._dl_hwcap. */ 513 ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8) 514# else 515 ld r8,0(r8) /* Load extern _dl_hwcap. */ 516# endif 517 andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16) 518 beq L(has_no_vec2) 519 520 cmpdi r10,0 521 beq L(has_no_vec2) 522 lwz r0,(33*16)(r10) 523 524 li r9,(16*32) 525 mtspr VRSAVE,r0 526 cmpwi r0,0 527 beq L(has_no_vec2) 528 529 lvx v19,r9,r10 530 la r9,(16)(r10) 531 532 lvx v0,0,r10 533 lvx v1,0,r9 534 addi r10,r10,32 535 addi r9,r9,32 536 537 mtvscr v19 538 lvx v2,0,r10 539 lvx v3,0,r9 540 addi r10,r10,32 541 addi r9,r9,32 542 543 lvx v4,0,r10 544 lvx v5,0,r9 545 addi r10,r10,32 546 addi r9,r9,32 547 548 lvx v6,0,r10 549 lvx v7,0,r9 550 addi r10,r10,32 551 addi r9,r9,32 552 553 lvx v8,0,r10 554 lvx v9,0,r9 555 addi r10,r10,32 556 addi r9,r9,32 557 558 lvx v10,0,r10 559 lvx v11,0,r9 560 addi r10,r10,32 561 addi r9,r9,32 562 563 lvx v12,0,r10 564 lvx v13,0,r9 565 addi r10,r10,32 566 addi r9,r9,32 567 568 lvx v14,0,r10 569 lvx v15,0,r9 570 addi r10,r10,32 571 addi r9,r9,32 572 573 lvx v16,0,r10 574 lvx v17,0,r9 575 addi r10,r10,32 576 addi r9,r9,32 577 578 lvx v18,0,r10 579 lvx v19,0,r9 580 addi r10,r10,32 581 addi r9,r9,32 582 583 lvx v20,0,r10 584 lvx v21,0,r9 585 addi r10,r10,32 586 addi r9,r9,32 587 588 lvx v22,0,r10 589 lvx v23,0,r9 590 addi r10,r10,32 591 addi r9,r9,32 592 593 lvx v24,0,r10 594 lvx v25,0,r9 595 addi r10,r10,32 596 addi r9,r9,32 597 598 lvx v26,0,r10 599 lvx v27,0,r9 600 addi r10,r10,32 601 addi r9,r9,32 602 603 lvx v28,0,r10 604 lvx v29,0,r9 605 addi r10,r10,32 606 addi r9,r9,32 607 608 lvx v30,0,r10 609 lvx v31,0,r9 610 addi r10,r10,32 611 addi r9,r9,32 612 613 lvx v10,0,r10 614 lvx v11,0,r9 615 addi r10,r10,32 616 addi r9,r9,32 617 618L(has_no_vec2): 619 620 lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31) 621 lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31) 622 lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31) 623 624# ifdef _ARCH_PWR6 625 /* Use the extended four-operand version of the mtfsf insn. */ 626 .machine push 627 .machine "power6" 628 629 mtfsf 0xff,fp0,1,0 630 631 .machine pop 632# else 633 /* Availability of DFP indicates a 64-bit FPSCR. */ 634 andi. r6,r8,PPC_FEATURE_HAS_DFP 635 beq 7f 636 637 .machine push 638 .machine "power6" 639 640 mtfsf 0xff,fp0,1,0 641 642 .machine pop 643 644 b 8f 645 /* Continue to operate on the FPSCR as if it were 32-bits. */ 6467: 647 mtfsf 0xff,fp0 6488: 649#endif /* _ARCH_PWR6 */ 650 651 lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31) 652 lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31) 653 lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31) 654 lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31) 655 lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31) 656 lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31) 657 lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31) 658 lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31) 659 lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31) 660 lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31) 661 lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31) 662 lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31) 663 lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31) 664 lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31) 665 lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31) 666 lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31) 667 lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31) 668 lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31) 669 lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31) 670 lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31) 671 lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31) 672 lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31) 673 lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31) 674 lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31) 675 lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31) 676 lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31) 677 lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31) 678 lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31) 679 lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31) 680 lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31) 681 682 ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31) 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) 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) 696 mtcr r0 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) 718 719 /* Now we branch to the "Next Instruction Pointer" from the saved 720 context. With the powerpc64 instruction set there is no good way to 721 do this (from user state) without clobbering either the LR or CTR. 722 The makecontext and swapcontext functions depend on the callers 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 729 730L(error_exit): 731 ld r0,128+FRAME_LR_SAVE(r1) 732 addi r1,r1,128 733 mtlr r0 734 ld r31,-8(r1) 735 blr 736 737PSEUDO_END(__swapcontext) 738 739versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4) 740