This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH][BZ #6816][4/5] VSX implementation for *context routines (powerpc64)
- From: Carlos Eduardo Seo <cseo at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Date: Tue, 05 Aug 2008 19:44:47 -0300
- Subject: [PATCH][BZ #6816][4/5] VSX implementation for *context routines (powerpc64)
- Openpgp: id=8BFFA900
VSX implementation for getcontext, setcontext and swapcontext (powerpc64).
--
Carlos Eduardo Seo
Software Engineer
IBM Linux Technology Center
2008-07-31 Carlos Eduardo Seo <cseo@linux.vnet.ibm.com>
Steven Munroe <sjmunroe@us.ibm.com>
[BZ #6816]
* sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext-common.S:
New file. Moved all common code to this file, which is included
by getcontext.S. Added a new scheme necessary for handling VSX
registers, in addition to the existing one.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext-common.S:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext-common.S:
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S: Added
new ucontext size and symbol versioning code for GLIBC 2.9. Also
making use of the new getcontext-common.S file.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S: Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S: Likewise.
Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext-common.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext-common.S 2008-07-31 16:44:25.000000000 -0500
@@ -0,0 +1,508 @@
+/* Save current context, powerpc64 common.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This is the common implementation of getcontext for powerpc64.
+ It not complete in itself should be included in to a framework that
+ defines:
+ __CONTEXT_FUNC_NAME
+ and if appropriate:
+ __CONTEXT_ENABLE_VRS
+ __CONTEXT_ENABLE_VSRS
+ Any archecture that implements the Vector unit is assumed to also
+ implement the floating unit. */
+
+
+ENTRY(__CONTEXT_FUNC_NAME)
+ CALL_MCOUNT 1
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
+ std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
+ mflr r0
+ std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
+ std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
+ std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
+ std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
+ std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
+ std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
+ std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
+ std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
+ std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
+ std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
+ std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
+ std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
+ std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
+ std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
+ std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
+ std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
+ std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
+ std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
+ std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
+ std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
+ std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
+ std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
+ std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
+ std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
+ std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
+ std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
+ std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
+ std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
+ mfctr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
+ mfxer r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
+ mfcr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
+
+ /* Set the return value of swapcontext to "success". R3 is the only
+ register whose value is not preserved in the saved context. */
+ li r0,0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
+
+ /* Zero fill fields that can't be set in user state or are unused. */
+ std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
+
+ /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
+ field. Struct pt_regs and elf_gregset_t are the same thing.
+ We kept the regs field for backwards compatibility with
+ libraries built before we extended sigcontext. */
+ addi r0,r3,SIGCONTEXT_GP_REGS
+ std r0,SIGCONTEXT_PT_REGS(r3)
+
+# ifdef __CONTEXT_ENABLE_VSRS
+ /* We will check first if we have VSX capability. If so, proceed
+ with the new method for storing the VSX quadwords. Otherwise,
+ use the old method. */
+
+ ld r8,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
+# else
+ ld r8,0(r8) /* Load extern _dl_hwcap. */
+# endif
+ la r6,(SIGCONTEXT_VS_REGS)(r3)
+
+ andi. r8,r8,PPC_FEATURE_HAS_VSX
+ clrrdi r6,r6,4
+ beq 4f /* L(has_no_vs) */
+
+ /* We save the Altivec registers first. */
+ la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
+ la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
+
+ clrrdi r10,r10,4
+ clrrdi r9,r9,4
+ mr r8,r10 /* Capture *v_regs value in r5. */
+
+ stvx v0,0,r10
+ stvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v2,0,r10
+ stvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v4,0,r10
+ stvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v6,0,r10
+ stvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v8,0,r10
+ stvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v10,0,r10
+ stvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v12,0,r10
+ stvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v14,0,r10
+ stvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v16,0,r10
+ stvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v18,0,r10
+ stvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v20,0,r10
+ stvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v22,0,r10
+ stvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v24,0,r10
+ stvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v26,0,r10
+ stvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v28,0,r10
+ stvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v30,0,r10
+ stvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mfvscr v0
+ mfspr r0,VRSAVE
+ stvx v0,0,r10
+ stw r0,0(r9)
+
+# ifdef HAVE_ASM_PPC_VSX
+ /* Only proceed with this if binutils can handle .machine "power7". */
+
+ /* Proceeding to the FP registers and the doubleword 1
+ of the first 32 VSR registers. */
+ la r7,(SIGCONTEXT_FP_REGS)(r3)
+ la r6,(SIGCONTEXT_VS_REGS)(r3)
+
+ /* Save fp0 and fp1 into vs32. */
+ xxmrghd vs32,vs0,vs1
+ /* Save vs0[1] and vs1[1] into vs33. */
+ xxmrgld vs33,vs0,vs1
+ /* Save f0 and f1. */
+ stxvd2x vs32,0,r7
+ /* Save vs0[1] and vs1[1]. */
+ stxvd2x vs33,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs34,vs2,vs3
+ xxmrgld vs35,vs2,vs3
+ stxvd2x vs34,0,r7
+ stxvd2x vs35,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs36,vs4,vs5
+ xxmrgld vs37,vs4,vs5
+ stxvd2x vs36,0,r7
+ stxvd2x vs37,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs38,vs6,vs7
+ xxmrgld vs39,vs6,vs7
+ stxvd2x vs38,0,r7
+ stxvd2x vs39,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs40,vs8,vs9
+ xxmrgld vs41,vs8,vs9
+ stxvd2x vs40,0,r7
+ stxvd2x vs41,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs42,vs10,vs11
+ xxmrgld vs43,vs10,vs11
+ stxvd2x vs42,0,r7
+ stxvd2x vs43,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs44,vs12,vs13
+ xxmrgld vs45,vs12,vs13
+ stxvd2x vs44,0,r7
+ stxvd2x vs45,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs46,vs14,vs15
+ xxmrgld vs47,vs14,vs15
+ stxvd2x vs46,0,r7
+ stxvd2x vs47,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs48,vs16,vs17
+ xxmrgld vs49,vs16,vs17
+ stxvd2x vs48,0,r7
+ stxvd2x vs49,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs50,vs18,vs19
+ xxmrgld vs51,vs18,vs19
+ stxvd2x vs50,0,r7
+ stxvd2x vs51,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs52,vs20,vs21
+ xxmrgld vs53,vs20,vs21
+ stxvd2x vs52,0,r7
+ stxvd2x vs53,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs54,vs22,vs23
+ xxmrgld vs55,vs22,vs23
+ stxvd2x vs54,0,r7
+ stxvd2x vs55,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs56,vs24,vs25
+ xxmrgld vs57,vs24,vs25
+ stxvd2x vs56,0,r7
+ stxvd2x vs57,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs58,vs26,vs27
+ xxmrgld vs59,vs26,vs27
+ stxvd2x vs58,0,r7
+ stxvd2x vs59,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs60,vs28,vs29
+ xxmrgld vs61,vs28,vs29
+ stxvd2x vs60,0,r7
+ stxvd2x vs61,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs62,vs30,vs31
+ xxmrgld vs63,vs30,vs31
+ stxvd2x vs62,0,r7
+ stxvd2x vs63,0,r6
+
+#else
+# warning "Binutils does not support VSX instructions."
+# endif
+ b 3f /* L(has_no_vec) */
+# endif /* __CONTEXT_ENABLE_VSRS */
+4: /* L(has_no_vs): */
+ /* Old method for storing the registers values. */
+ stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
+ stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
+ stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
+ stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
+ stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
+ stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
+ stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
+ stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
+ stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
+ stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
+ stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
+ stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
+ stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
+ stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
+ stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
+ stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
+ stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
+ stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
+ stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
+ stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
+ stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
+ stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
+ stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
+ stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
+ stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
+ stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
+ stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
+ stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
+ stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
+ stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
+ mffs fp0
+ stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
+ stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
+ stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
+
+# ifdef __CONTEXT_ENABLE_VRS
+ ld r5,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ ld r5,0(r5) /* Load extern _dl_hwcap. */
+# endif
+ la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
+ la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
+
+ andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+
+ clrrdi r10,r10,4
+ beq 3f /* L(has_no_vec) */
+ clrrdi r9,r9,4
+ mr r5,r10 /* Capture *v_regs value in r5. */
+
+ stvx v0,0,r10
+ stvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v2,0,r10
+ stvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v4,0,r10
+ stvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v6,0,r10
+ stvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v8,0,r10
+ stvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v10,0,r10
+ stvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v12,0,r10
+ stvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v14,0,r10
+ stvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v16,0,r10
+ stvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v18,0,r10
+ stvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v20,0,r10
+ stvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v22,0,r10
+ stvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v24,0,r10
+ stvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v26,0,r10
+ stvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v28,0,r10
+ stvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v30,0,r10
+ stvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mfvscr v0
+ mfspr r0,VRSAVE
+ stvx v0,0,r10
+ stw r0,0(9)
+
+# endif /* __CONTEXT_ENABLE_VRS */
+3: /* L(has_no_vec): */
+/*
+ Store either a NULL or a quadword aligned pointer to the Vector register
+ array into *v_regs.
+*/
+ std r5,(SIGCONTEXT_V_REGS_PTR)(r3)
+
+ addi r5,r3,UCONTEXT_SIGMASK
+ li r4,0
+ li r3,SIG_BLOCK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+#endif
+
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+PSEUDO_END(__CONTEXT_FUNC_NAME)
Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S 2008-07-31 16:40:07.000000000 -0500
+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S 2008-07-31 16:40:17.000000000 -0500
@@ -27,385 +27,87 @@
#include <asm/errno.h>
#include "ucontext_i.h"
-
-#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
-ENTRY(__novec_getcontext)
- CALL_MCOUNT 1
-#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
- std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
- std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
- mflr r0
- std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset (128)
- std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
- std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
- std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
- std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
- std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
- std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
- std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
- std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
- std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
- std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
- std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
- std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
- std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
- std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
- std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
- std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
- std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
- std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
- std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
- std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
- std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
- std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
- std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
- std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
- std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
- std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
- std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
- std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
- mfctr r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
- mfxer r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
- mfcr r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
-
- /* Set the return value of swapcontext to "success". R3 is the only
- register whose value is not preserved in the saved context. */
- li r0,0
- std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
-
- /* Zero fill fields that can't be set in user state or are unused. */
- std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
-
- /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
- field. Struct pt_regs and elf_gregset_t are the same thing.
- We kept the regs field for backwards compatibility with
- libraries built before we extended sigcontext. */
- addi r0,r3,SIGCONTEXT_GP_REGS
- std r0,SIGCONTEXT_PT_REGS(r3)
-
- stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
- stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
- stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
- stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
- stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
- stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
- stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
- stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
- stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
- stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
- stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
- stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
- stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
- stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
- stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
- stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
- stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
- stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
- stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
- stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
- stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
- stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
- stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
- stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
- stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
- stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
- stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
- stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
- stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
- stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
- mffs fp0
- stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
- stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
- stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
-
- addi r5,r3,UCONTEXT_SIGMASK
- li r4,0
- li r3,SIG_BLOCK
- bl JUMPTARGET(__sigprocmask)
- nop
+#define __CONTEXT_FUNC_NAME __getcontext
+#define __CONTEXT_ENABLE_VRS 1
+#define __CONTEXT_ENABLE_VSRS 1
+
+/* Size of ucontext in GLIBC_2.3.4 and later. */
+#define _UC_SIZE_2_3_4 1440
+#define _UC_SIZE_2_9 1696
+
+#ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ .section ".text";
+ENTRY (__getcontext)
+ li r4,0
+ li r5,_UC_SIZE_2_9;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,1f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+1:
+ b __syscall_error
+END(__getcontext)
#else
- /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
- mflr r0
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset(128)
- li r3,ENOSYS
- bl JUMPTARGET(__syscall_error)
- nop
- li r3,-1
-#endif
-
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- blr
-PSEUDO_END(__novec_getcontext)
-
-compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3)
-
-#endif
-
- .section ".toc","aw"
+ .section ".toc","aw"
.LC__dl_hwcap:
-#ifdef SHARED
+
+# ifdef SHARED
.tc _rtld_global_ro[TC],_rtld_global_ro
-#else
+# else
.tc _dl_hwcap[TC],_dl_hwcap
-#endif
+# endif
.section ".text"
+# include "getcontext-common.S"
+#endif
- .machine "altivec"
-ENTRY(__getcontext)
- CALL_MCOUNT 1
-#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
- std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
- std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
- mflr r0
- std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset (128)
- std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
- std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
- std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
- std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
- std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
- std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
- std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
- std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
- std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
- std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
- std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
- std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
- std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
- std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
- std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
- std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
- std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
- std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
- std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
- std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
- std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
- std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
- std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
- std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
- std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
- std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
- std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
- std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
- mfctr r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
- mfxer r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
- mfcr r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
-
- /* Set the return value of swapcontext to "success". R3 is the only
- register whose value is not preserved in the saved context. */
- li r0,0
- std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
-
- /* Zero fill fields that can't be set in user state or are unused. */
- std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
-
- /* Set the PT_REGS pointer to the address of sigcontext's gp_regs
- field. Struct pt_regs and elf_gregset_t are the same thing.
- We kept the regs field for backwards compatibility with
- libraries built before we extended sigcontext. */
- addi r0,r3,SIGCONTEXT_GP_REGS
- std r0,SIGCONTEXT_PT_REGS(r3)
-
- stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
- stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
- stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
- stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
- stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
- stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
- stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
- stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
- stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
- stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
- stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
- stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
- stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
- stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
- stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
- stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
- stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
- stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
- stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
- stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
- stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
- stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
- stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
- stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
- stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
- stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
- stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
- stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
- stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
- stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
- mffs fp0
- stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
- stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
- stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
+versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_9)
- ld r5,.LC__dl_hwcap@toc(r2)
+#if SHLIB_COMPAT (libc, GLIBC_2_3_4, GLIBC_2_9)
+ compat_text_section
+#ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ENTRY (__novsx_getcontext)
+ li r4,0
+ li r5,_UC_SIZE_2_3_4;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,2f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+2:
+ b __syscall_error
+END (__novsx_getcontext)
+#else
+# undef __CONTEXT_ENABLE_VSRS
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novsx_getcontext
# ifdef SHARED
-/* Load _rtld-global._dl_hwcap. */
- ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+ .tc _rtld_global_ro[TC],_rtld_global_ro
# else
- ld r5,0(r5) /* Load extern _dl_hwcap. */
+ .tc _dl_hwcap[TC],_dl_hwcap
# endif
- la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
- la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
-
- andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ .section ".text"
+ .machine "altivec"
+# include "getcontext-common.S"
- clrrdi r10,r10,4
- beq L(has_no_vec)
- clrrdi r9,r9,4
- mr r5,r10 /* Capture *v_regs value in r5. */
-
- stvx v0,0,r10
- stvx v1,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v2,0,r10
- stvx v3,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v4,0,r10
- stvx v5,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v6,0,r10
- stvx v7,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v8,0,r10
- stvx v9,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v10,0,r10
- stvx v11,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v12,0,r10
- stvx v13,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v14,0,r10
- stvx v15,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v16,0,r10
- stvx v17,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v18,0,r10
- stvx v19,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v20,0,r10
- stvx v21,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v22,0,r10
- stvx v23,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v24,0,r10
- stvx v25,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v26,0,r10
- stvx v27,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v28,0,r10
- stvx v29,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v30,0,r10
- stvx v31,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- mfvscr v0
- mfspr r0,VRSAVE
- stvx v0,0,r10
- stw r0,0(9)
-
-L(has_no_vec):
-/*
- Store either a NULL or a quadword aligned pointer to the Vector register
- array into *v_regs.
-*/
- std r5,(SIGCONTEXT_V_REGS_PTR)(r3)
-
- addi r5,r3,UCONTEXT_SIGMASK
- li r4,0
- li r3,SIG_BLOCK
- bl JUMPTARGET(__sigprocmask)
- nop
-#else
- /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
- mflr r0
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset (128)
- li r3,ENOSYS
- bl JUMPTARGET(__syscall_error)
- nop
- li r3,-1
+ .previous
+#endif
+compat_symbol (libc, __novsx_getcontext, getcontext, GLIBC_2_3_4)
#endif
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- blr
-PSEUDO_END(__getcontext)
+#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+ compat_text_section
+
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novec_getcontext
+# undef __CONTEXT_ENABLE_VSRS
+# undef __CONTEXT_ENABLE_VRS
+
+# include "getcontext-common.S"
+
+ .previous
+
+compat_symbol (libc, __novec_getcontext, getcontext, GLIBC_2_3)
+
+#endif
-versioned_symbol (libc, __getcontext, getcontext, GLIBC_2_3_4)
Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext-common.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext-common.S 2008-07-31 16:46:31.000000000 -0500
@@ -0,0 +1,541 @@
+/* Jump to a new context powerpc64 common.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This is the common implementation of setcontext for powerpc64.
+ It not complete in itself should be included in to a framework that
+ defines:
+ __CONTEXT_FUNC_NAME
+ and if appropriate:
+ __CONTEXT_ENABLE_VRS
+ __CONTEXT_ENABLE_VSRS
+ Any archecture that implements the Vector unit is assumed to also
+ implement the floating unit. */
+
+
+ENTRY(__CONTEXT_FUNC_NAME)
+ CALL_MCOUNT 1
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ mflr r0
+ std r31,-8(1)
+ cfi_offset(r31,-8)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ mr r31,r3
+
+/*
+ * If this ucontext refers to the point where we were interrupted
+ * by a signal, we have to use the rt_sigreturn system call to
+ * return to the context so we get both LR and CTR restored.
+ *
+ * Otherwise, the context we are restoring is either just after
+ * a procedure call (getcontext/swapcontext) or at the beginning
+ * of a procedure call (makecontext), so we don't need to restore
+ * msr and ctr. We don't restore r13 since it will be used as
+ * the TLS pointer. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+ cmpdi r0,0
+ bne 2f /* L(do_sigret) */
+
+ li r5,0
+ addi r4,r3,UCONTEXT_SIGMASK
+ li r3,SIG_SETMASK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+ cmpdi r3,0
+ bne 1f /* L(error_exit) */
+
+# ifdef __CONTEXT_ENABLE_VSRS
+ /* We will check first if we have VSX capability. If so, proceed
+ with the new method for storing the VSX quadwords. Otherwise,
+ use the old method. */
+ ld r5,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ ld r5,0(r5) /* Load extern _dl_hwcap. */
+# endif
+ andi. r5,r5,PPC_FEATURE_HAS_VSX
+ ld r6,(SIGCONTEXT_VS_REGS)(r31)
+ beq 4f /* L(has_no_vs) */
+
+# ifdef HAVE_ASM_PPC_VSX
+ /* Only proceed with this if binutils can handle .machine "power7". */
+
+/* Using VMX registers as temps to minimize the number of loads for
+ restoring the FP and the doubleword 1 of VSR[0-31]. */
+ la r7,(SIGCONTEXT_FP_REGS_PTR)(r31)
+ la r6,(SIGCONTEXT_VS_REGS)(r31)
+ /* Load f0 and f1 register state into vs32. */
+ lxvd2x vs32,0,r7
+ /* Load vs0[1] and vs1[1] register state into vs33. */
+ lxvd2x vs33,0,r6
+ /* Merge f0 and vs0[1] register state into vs0. */
+ xxmrghd vs0,vs32,vs33
+ /* Merge f1 and vs1[1] register state into vs1. */
+ xxmrgld vs1,vs32,vs33
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs34,0,r7
+ lxvd2x vs35,0,r6
+ xxmrghd vs2,vs34,vs35
+ xxmrghd vs3,vs34,vs35
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs36,0,r7
+ lxvd2x vs37,0,r6
+ xxmrghd vs4,vs36,vs37
+ xxmrghd vs5,vs36,vs37
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs38,0,r7
+ lxvd2x vs39,0,r6
+ xxmrghd vs6,vs38,vs39
+ xxmrghd vs7,vs38,vs39
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs40,0,r7
+ lxvd2x vs41,0,r6
+ xxmrghd vs8,vs40,vs41
+ xxmrghd vs9,vs40,vs41
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs42,0,r7
+ lxvd2x vs43,0,r6
+ xxmrghd vs10,vs42,vs43
+ xxmrghd vs11,vs42,vs43
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs44,0,r7
+ lxvd2x vs45,0,r6
+ xxmrghd vs12,vs44,vs45
+ xxmrghd vs13,vs44,vs45
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs46,0,r7
+ lxvd2x vs47,0,r6
+ xxmrghd vs14,vs46,vs47
+ xxmrghd vs15,vs46,vs47
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs48,0,r7
+ lxvd2x vs49,0,r6
+ xxmrghd vs16,vs48,vs49
+ xxmrghd vs17,vs48,vs49
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs50,0,r7
+ lxvd2x vs51,0,r6
+ xxmrghd vs18,vs50,vs51
+ xxmrghd vs19,vs50,vs51
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs52,0,r7
+ lxvd2x vs53,0,r6
+ xxmrghd vs20,vs52,vs53
+ xxmrghd vs21,vs52,vs53
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs54,0,r7
+ lxvd2x vs55,0,r6
+ xxmrghd vs22,vs54,vs55
+ xxmrghd vs23,vs54,vs55
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs56,0,r7
+ lxvd2x vs57,0,r6
+ xxmrghd vs24,vs56,vs57
+ xxmrghd vs25,vs56,vs57
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs58,0,r7
+ lxvd2x vs59,0,r6
+ xxmrghd vs26,vs58,vs59
+ xxmrghd vs27,vs58,vs59
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs60,0,r7
+ lxvd2x vs61,0,r6
+ xxmrghd vs28,vs60,vs61
+ xxmrghd vs29,vs60,vs61
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs62,0,r7
+ lxvd2x vs63,0,r6
+ xxmrghd vs30,vs62,vs63
+ xxmrghd vs31,vs62,vs63
+
+#else
+# warning "Binutils does not support VSX instructions."
+# endif
+
+ /* Now we may proceed restoring the VMX registers. */
+ ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
+ cmpdi r10,0
+ lwz r0,(33*16)(r10)
+
+ li r9,(16*32)
+ mtspr VRSAVE,r0
+ cmpwi r0,0
+
+ lvx v19,r9,r10
+ la r9,(16)(r10)
+
+ lvx v0,0,r10
+ lvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mtvscr v19
+ lvx v2,0,r10
+ lvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v4,0,r10
+ lvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v6,0,r10
+ lvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v8,0,r10
+ lvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v12,0,r10
+ lvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v14,0,r10
+ lvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v16,0,r10
+ lvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v18,0,r10
+ lvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v20,0,r10
+ lvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v22,0,r10
+ lvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v24,0,r10
+ lvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v26,0,r10
+ lvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v28,0,r10
+ lvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v30,0,r10
+ lvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ b 3f /* L(has_no_vec) */
+
+# endif /* __CONTEXT_ENABLE_VSRS */
+4: /* L(has_no_vs): */
+ /* Old method for restoring the registers contents. */
+# ifdef __CONTEXT_ENABLE_VRS
+ ld r5,.LC__dl_hwcap@toc(r2)
+ ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+# else
+ ld r5,0(r5) /* Load extern _dl_hwcap. */
+# endif
+ andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq 3f /* L(has_no_vec) */
+
+ cmpdi r10,0
+ beq 3f /* L(has_no_vec) */
+ lwz r0,(33*16)(r10)
+
+ li r9,(16*32)
+ mtspr VRSAVE,r0
+ cmpwi r0,0
+ beq 3f /* L(has_no_vec) */
+
+ lvx v19,r9,r10
+ la r9,(16)(r10)
+
+ lvx v0,0,r10
+ lvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mtvscr v19
+ lvx v2,0,r10
+ lvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v4,0,r10
+ lvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v6,0,r10
+ lvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v8,0,r10
+ lvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v12,0,r10
+ lvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v14,0,r10
+ lvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v16,0,r10
+ lvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v18,0,r10
+ lvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v20,0,r10
+ lvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v22,0,r10
+ lvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v24,0,r10
+ lvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v26,0,r10
+ lvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v28,0,r10
+ lvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v30,0,r10
+ lvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+# endif /* __CONTEXT_ENABLE_VRS */
+3: /* L(has_no_vec): */
+ lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
+ lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
+ lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
+ mtfsf 0xff,fp0
+ lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
+ lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
+ lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
+ lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
+ lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
+ lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
+ lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
+ lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
+ lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
+ lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
+ lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
+ lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
+ lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
+ lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
+ lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
+ lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
+ lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
+ lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
+ lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
+ lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
+ lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
+ lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
+ lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
+ lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
+ lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
+ lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
+ lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
+ lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
+ lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
+ lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
+
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
+ ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
+ mtlr r0
+ ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
+ ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
+ mtxer r0
+ ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
+ ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
+ ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
+ ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
+ ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
+ ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
+ mtcr r0
+ ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
+ ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
+ ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
+ /* Don't reload the thread ID or TLS pointer (r13). */
+ ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
+ ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
+ ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
+ ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
+ ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
+ ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
+ ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
+ ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
+ ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
+ ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
+ ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
+ ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
+ ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
+ ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
+ ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
+ ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
+ ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
+
+ /* Now we branch to the "Next Instruction Pointer" from the saved
+ context. With the powerpc64 instruction set there is no good way to
+ do this (from user state) without clobbering either the LR or CTR.
+ The makecontext and swapcontext functions depend on the callers
+ LR being preserved so we use the CTR. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
+ mtctr r0
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
+ ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
+ bctr
+
+1: /* L(error_exit): */
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ ld r31,-8(r1)
+ blr
+
+ /* At this point we assume that the ucontext was created by a
+ rt_signal and we should use rt_sigreturn to restore the original
+ state. As of the 2.4.21 kernel the ucontext is the first thing
+ (offset 0) in the rt_signal frame and rt_sigreturn expects the
+ ucontext address in R1. Normally the rt-signal trampoline handles
+ this by popping dummy frame before the rt_signal syscall. In our
+ case the stack may not be in its original (signal handler return with
+ R1 pointing at the dummy frame) state. We do have the ucontext
+ address in R3, so simply copy R3 to R1 before the syscall. */
+2: /* L(do_sigret): */
+ mr r1,r3,
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* No return. */
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+#endif
+
+PSEUDO_END(__CONTEXT_FUNC_NAME)
Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S 2008-07-31 16:40:07.000000000 -0500
+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S 2008-07-31 16:40:17.000000000 -0500
@@ -27,443 +27,92 @@
#include "ucontext_i.h"
#include <asm/errno.h>
-#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
-ENTRY(__novec_setcontext)
- CALL_MCOUNT 1
-#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
- mflr r0
- std r31,-8(1)
- cfi_offset(r31,-8)
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset (128)
- mr r31,r3
-
-/*
- * If this ucontext refers to the point where we were interrupted
- * by a signal, we have to use the rt_sigreturn system call to
- * return to the context so we get both LR and CTR restored.
- *
- * Otherwise, the context we are restoring is either just after
- * a procedure call (getcontext/swapcontext) or at the beginning
- * of a procedure call (makecontext), so we don't need to restore
- * msr and ctr. We don't restore r13 since it will be used as
- * the TLS pointer. */
- ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
- cmpdi r0,0
- bne L(nv_do_sigret)
-
- li r5,0
- addi r4,r3,UCONTEXT_SIGMASK
- li r3,SIG_SETMASK
- bl JUMPTARGET(__sigprocmask)
- nop
- cmpdi r3,0
- bne L(nv_error_exit)
-
- lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
- lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
- lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
- mtfsf 0xff,fp0
- lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
- lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
- lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
- lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
- lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
- lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
- lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
- lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
- lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
- lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
- lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
- lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
- lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
- lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
- lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
- lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
- lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
- lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
- lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
- lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
- lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
- lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
- lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
- lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
- lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
- lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
- lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
- lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
- lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
- lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
-
- ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
- ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
- mtlr r0
- ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
- ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
- ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
- mtxer r0
- ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
- ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
- ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
- mtcr r0
- ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
- ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
- ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
- ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
- ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
- ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
- ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
- /* Don't reload the thread ID or TLS pointer (r13). */
- ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
- ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
- ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
- ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
- ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
- ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
- ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
- ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
- ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
- ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
- ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
- ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
- ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
- ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
- ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
- ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
- ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
-
- /* Now we branch to the "Next Instruction Pointer" from the saved
- context. With the powerpc64 instruction set there is no good way to
- do this (from user state) without clobbering either the LR or CTR.
- The makecontext and swapcontext functions depend on the callers
- LR being preserved so we use the CTR. */
- ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
- mtctr r0
- ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
- ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
- bctr
-
-L(nv_error_exit):
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- ld r31,-8(r1)
- blr
-
- /* At this point we assume that the ucontext was created by a
- rt_signal and we should use rt_sigreturn to restore the original
- state. As of the 2.4.21 kernel the ucontext is the first thing
- (offset 0) in the rt_signal frame and rt_sigreturn expects the
- ucontext address in R1. Normally the rt-signal trampoline handles
- this by popping dummy frame before the rt_signal syscall. In our
- case the stack may not be in its original (signal handler return with
- R1 pointing at the dummy frame) state. We do have the ucontext
- address in R3, so simply copy R3 to R1 before the syscall. */
-L(nv_do_sigret):
- mr r1,r3,
- li r0,SYS_ify(rt_sigreturn)
- sc
- /* No return. */
+#define __CONTEXT_FUNC_NAME __setcontext
+#define __CONTEXT_ENABLE_VRS 1
+#define __CONTEXT_ENABLE_VSRS 1
+
+/* Size of ucontext in GLIBC_2.3.4 and later. */
+#define _UC_SIZE_2_3_4 1440
+#define _UC_SIZE_2_9 1696
+
+#ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ .section ".text";
+ENTRY (__setcontext)
+ mr r4,r3
+ li r3,0
+ li r5,_UC_SIZE_2_9;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,1f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+1:
+ b __syscall_error
+END(__setcontext)
#else
- /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
- mflr r0
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset(lr,FRAME_LR_SAVE)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset(128)
- li r3,ENOSYS
- bl JUMPTARGET(__syscall_error)
- nop
- li r3,-1
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- blr
-#endif
-
-PSEUDO_END(__novec_setcontext)
-
-compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3)
-
-#endif
-
- .section ".toc","aw"
+ .section ".toc","aw"
.LC__dl_hwcap:
-#ifdef SHARED
+
+# ifdef SHARED
.tc _rtld_global_ro[TC],_rtld_global_ro
-#else
+# else
.tc _dl_hwcap[TC],_dl_hwcap
-#endif
+# endif
.section ".text"
+#ifdef __CONTEXT_ENABLE_VRS
- .machine "altivec"
-ENTRY(__setcontext)
- CALL_MCOUNT 1
-#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
- mflr r0
- std r31,-8(1)
- cfi_offset(r31,-8)
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset (128)
- mr r31,r3
-
-/*
- * If this ucontext refers to the point where we were interrupted
- * by a signal, we have to use the rt_sigreturn system call to
- * return to the context so we get both LR and CTR restored.
- *
- * Otherwise, the context we are restoring is either just after
- * a procedure call (getcontext/swapcontext) or at the beginning
- * of a procedure call (makecontext), so we don't need to restore
- * msr and ctr. We don't restore r13 since it will be used as
- * the TLS pointer. */
- ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
- cmpdi r0,0
- bne L(do_sigret)
-
- li r5,0
- addi r4,r3,UCONTEXT_SIGMASK
- li r3,SIG_SETMASK
- bl JUMPTARGET(__sigprocmask)
- nop
- cmpdi r3,0
- bne L(error_exit)
+#endif
+# include "setcontext-common.S"
+#endif
- ld r5,.LC__dl_hwcap@toc(r2)
- ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
+versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_9)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3_4, GLIBC_2_9)
+ compat_text_section
+#ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ENTRY (__novsx_setcontext)
+ mr r4,r3
+ li r3,0
+ li r5,_UC_SIZE_2_3_4;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,2f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+2:
+ b __syscall_error
+END (__novsx_setcontext)
+#else
+# undef __CONTEXT_ENABLE_VSRS
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novsx_setcontext
# ifdef SHARED
-/* Load _rtld-global._dl_hwcap. */
- ld r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
+ .tc _rtld_global_ro[TC],_rtld_global_ro
# else
- ld r5,0(r5) /* Load extern _dl_hwcap. */
+ .tc _dl_hwcap[TC],_dl_hwcap
# endif
- andis. r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
- beq L(has_no_vec)
+ .section ".text"
+ .machine "altivec"
+# include "setcontext-common.S"
- cmpdi r10,0
- beq L(has_no_vec)
- lwz r0,(33*16)(r10)
-
- li r9,(16*32)
- mtspr VRSAVE,r0
- cmpwi r0,0
- beq L(has_no_vec)
-
- lvx v19,r9,r10
- la r9,(16)(r10)
-
- lvx v0,0,r10
- lvx v1,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- mtvscr v19
- lvx v2,0,r10
- lvx v3,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v4,0,r10
- lvx v5,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v6,0,r10
- lvx v7,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v8,0,r10
- lvx v9,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v10,0,r10
- lvx v11,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v12,0,r10
- lvx v13,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v14,0,r10
- lvx v15,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v16,0,r10
- lvx v17,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v18,0,r10
- lvx v19,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v20,0,r10
- lvx v21,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v22,0,r10
- lvx v23,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v24,0,r10
- lvx v25,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v26,0,r10
- lvx v27,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v28,0,r10
- lvx v29,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v30,0,r10
- lvx v31,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v10,0,r10
- lvx v11,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
-L(has_no_vec):
- lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
- lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
- lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
- mtfsf 0xff,fp0
- lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
- lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
- lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
- lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
- lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
- lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
- lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
- lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
- lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
- lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
- lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
- lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
- lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
- lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
- lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
- lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
- lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
- lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
- lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
- lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
- lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
- lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
- lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
- lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
- lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
- lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
- lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
- lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
- lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
- lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
-
- ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
- ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
- mtlr r0
- ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
- ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
- ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
- mtxer r0
- ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
- ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
- ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
- ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
- ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
- ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
- ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
- mtcr r0
- ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
- ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
- ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
- /* Don't reload the thread ID or TLS pointer (r13). */
- ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
- ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
- ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
- ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
- ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
- ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
- ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
- ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
- ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
- ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
- ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
- ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
- ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
- ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
- ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
- ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
- ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
-
- /* Now we branch to the "Next Instruction Pointer" from the saved
- context. With the powerpc64 instruction set there is no good way to
- do this (from user state) without clobbering either the LR or CTR.
- The makecontext and swapcontext functions depend on the callers
- LR being preserved so we use the CTR. */
- ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
- mtctr r0
- ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
- ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
- bctr
-
-L(error_exit):
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- ld r31,-8(r1)
- blr
-
- /* At this point we assume that the ucontext was created by a
- rt_signal and we should use rt_sigreturn to restore the original
- state. As of the 2.4.21 kernel the ucontext is the first thing
- (offset 0) in the rt_signal frame and rt_sigreturn expects the
- ucontext address in R1. Normally the rt-signal trampoline handles
- this by popping dummy frame before the rt_signal syscall. In our
- case the stack may not be in its original (signal handler return with
- R1 pointing at the dummy frame) state. We do have the ucontext
- address in R3, so simply copy R3 to R1 before the syscall. */
-L(do_sigret):
- mr r1,r3,
- li r0,SYS_ify(rt_sigreturn)
- sc
- /* No return. */
-#else
- /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
- mflr r0
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset (128)
- li r3,ENOSYS
- bl JUMPTARGET(__syscall_error)
- nop
- li r3,-1
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- blr
+ .previous
+#endif
+compat_symbol (libc, __novsx_setcontext, setcontext, GLIBC_2_3_4)
#endif
-PSEUDO_END(__setcontext)
+#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+
+ compat_text_section
+
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novec_setcontext
+# undef __CONTEXT_ENABLE_VSRS
+# undef __CONTEXT_ENABLE_VRS
+
+# include "setcontext-common.S"
-versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)
+ .previous
+
+compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3)
+
+#endif
Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext-common.S
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext-common.S 2008-07-31 16:47:07.000000000 -0500
@@ -0,0 +1,989 @@
+/* Save current context and jump to a new context.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+/* This is the common implementation of setcontext for powerpc64.
+ It not complete in itself should be included in to a framework that
+ defines:
+ __CONTEXT_FUNC_NAME
+ and if appropriate:
+ __CONTEXT_ENABLE_VRS
+ __CONTEXT_ENABLE_VSRS
+ Any archecture that implements the Vector unit is assumed to also
+ implement the floating unit. */
+
+
+ENTRY(__CONTEXT_FUNC_NAME)
+ CALL_MCOUNT 2
+#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
+ std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
+ mflr r0
+ std r31,-8(1)
+ cfi_offset(r31,-8)
+ std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset(128)
+ std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
+ std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
+ std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
+ std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
+ std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
+ std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
+ std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
+ std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
+ std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
+ std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
+ std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
+ std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
+ std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
+ std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
+ std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
+ std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
+ std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
+ std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
+ std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
+ std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
+ std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
+ std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
+ std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
+ std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
+ std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
+ std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
+ std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
+ std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
+ mfctr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
+ mfxer r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
+ mfcr r0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
+
+ /* Set the return value of swapcontext to "success". R3 is the only
+ register whose value is not preserved in the saved context. */
+ li r0,0
+ std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
+
+ /* Zero fill fields that can't be set in user state or are unused. */
+ std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
+ std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
+
+ /* Set the PT_REGS pointer to the address of sigcontext gp_regs
+ field. Struct pt_regs and elf_gregset_t are the same thing.
+ We kept the regs field for backwards compatibility with
+ libraries built before we extended sigcontext. */
+ addi r0,r3,SIGCONTEXT_GP_REGS
+ std r0,SIGCONTEXT_PT_REGS(r3)
+
+# ifdef __CONTEXT_ENABLE_VSRS
+ /* We will check first if we have VSX capability. If so, proceed
+ with the new method for storing the VSX quadwords. Otherwise,
+ use the old method. */
+
+ ld r8,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
+# else
+ ld r8,0(r8) /* Load extern _dl_hwcap. */
+# endif
+ la r6,(SIGCONTEXT_VS_REGS)(r3)
+
+ andi. r8,r8,PPC_FEATURE_HAS_VSX
+ clrrdi r6,r6,4
+ beq 4f /* L(has_no_vs) */
+
+ /* We save the Altivec registers first. */
+ la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
+ la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
+
+ clrrdi r10,r10,4
+ clrrdi r9,r9,4
+ mr r8,r10 /* Capture *v_regs value in r5. */
+
+ stvx v0,0,r10
+ stvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v2,0,r10
+ stvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v4,0,r10
+ stvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v6,0,r10
+ stvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v8,0,r10
+ stvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v10,0,r10
+ stvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v12,0,r10
+ stvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v14,0,r10
+ stvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v16,0,r10
+ stvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v18,0,r10
+ stvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v20,0,r10
+ stvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v22,0,r10
+ stvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v24,0,r10
+ stvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v26,0,r10
+ stvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v28,0,r10
+ stvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v30,0,r10
+ stvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mfvscr v0
+ mfspr r0,VRSAVE
+ stvx v0,0,r10
+ stw r0,0(r9)
+
+# ifdef HAVE_ASM_PPC_VSX
+ /* Only proceed with this if binutils can handle .machine "power7". */
+
+ /* Proceeding to the FP registers and the doubleword 1
+ of the first 32 VSR registers. */
+ la r7,(SIGCONTEXT_FP_REGS)(r3)
+ la r6,(SIGCONTEXT_VS_REGS)(r3)
+
+ /* Save fp0 and fp1 into vs32. */
+ xxmrghd vs32,vs0,vs1
+ /* Save vs0[1] and vs1[1] into vs33. */
+ xxmrgld vs33,vs0,vs1
+ /* Save f0 and f1. */
+ stxvd2x vs32,0,r7
+ /* Save vs0[1] and vs1[1]. */
+ stxvd2x vs33,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs34,vs2,vs3
+ xxmrgld vs35,vs2,vs3
+ stxvd2x vs34,0,r7
+ stxvd2x vs35,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs36,vs4,vs5
+ xxmrgld vs37,vs4,vs5
+ stxvd2x vs36,0,r7
+ stxvd2x vs37,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs38,vs6,vs7
+ xxmrgld vs39,vs6,vs7
+ stxvd2x vs38,0,r7
+ stxvd2x vs39,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs40,vs8,vs9
+ xxmrgld vs41,vs8,vs9
+ stxvd2x vs40,0,r7
+ stxvd2x vs41,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs42,vs10,vs11
+ xxmrgld vs43,vs10,vs11
+ stxvd2x vs42,0,r7
+ stxvd2x vs43,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs44,vs12,vs13
+ xxmrgld vs45,vs12,vs13
+ stxvd2x vs44,0,r7
+ stxvd2x vs45,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs46,vs14,vs15
+ xxmrgld vs47,vs14,vs15
+ stxvd2x vs46,0,r7
+ stxvd2x vs47,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs48,vs16,vs17
+ xxmrgld vs49,vs16,vs17
+ stxvd2x vs48,0,r7
+ stxvd2x vs49,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs50,vs18,vs19
+ xxmrgld vs51,vs18,vs19
+ stxvd2x vs50,0,r7
+ stxvd2x vs51,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs52,vs20,vs21
+ xxmrgld vs53,vs20,vs21
+ stxvd2x vs52,0,r7
+ stxvd2x vs53,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs54,vs22,vs23
+ xxmrgld vs55,vs22,vs23
+ stxvd2x vs54,0,r7
+ stxvd2x vs55,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs56,vs24,vs25
+ xxmrgld vs57,vs24,vs25
+ stxvd2x vs56,0,r7
+ stxvd2x vs57,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs58,vs26,vs27
+ xxmrgld vs59,vs26,vs27
+ stxvd2x vs58,0,r7
+ stxvd2x vs59,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs60,vs28,vs29
+ xxmrgld vs61,vs28,vs29
+ stxvd2x vs60,0,r7
+ stxvd2x vs61,0,r6
+ addi r7,r7,16
+ addi r6,r6,16
+
+ xxmrghd vs62,vs30,vs31
+ xxmrgld vs63,vs30,vs31
+ stxvd2x vs62,0,r7
+ stxvd2x vs63,0,r6
+
+#else
+# warning "Binutils does not support VSX instructions."
+# endif
+ b 3f /* L(has_no_vec) */
+# endif /* __CONTEXT_ENABLE_VSRS */
+4: /* L(has_no_vs): */
+ /* Old method for storing the registers values. */
+ stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
+ stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
+ stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
+ stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
+ stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
+ stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
+ stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
+ stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
+ stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
+ stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
+ stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
+ stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
+ stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
+ stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
+ stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
+ stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
+ stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
+ stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
+ stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
+ stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
+ stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
+ stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
+ stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
+ stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
+ stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
+ stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
+ stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
+ stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
+ stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
+ stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
+ mffs fp0
+ stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
+ stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
+ stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
+
+# ifdef __CONTEXT_ENABLE_VRS
+ ld r8,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
+# else
+ ld r8,0(r8) /* Load extern _dl_hwcap. */
+# endif
+ la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
+ la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
+
+ andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+
+ clrrdi r10,r10,4
+ beq 3f /* L(has_no_vec) */
+
+ clrrdi r9,r9,4
+ mr r8,r10 /* Capture *v_regs value in r5. */
+
+ stvx v0,0,r10
+ stvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v2,0,r10
+ stvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v4,0,r10
+ stvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v6,0,r10
+ stvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v8,0,r10
+ stvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v10,0,r10
+ stvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v12,0,r10
+ stvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v14,0,r10
+ stvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v16,0,r10
+ stvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v18,0,r10
+ stvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v20,0,r10
+ stvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v22,0,r10
+ stvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v24,0,r10
+ stvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v26,0,r10
+ stvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v28,0,r10
+ stvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ stvx v30,0,r10
+ stvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mfvscr v0
+ mfspr r0,VRSAVE
+ stvx v0,0,r10
+ stw r0,0(r9)
+
+# endif /* __CONTEXT_ENABLE_VRS */
+3: /* L(has_no_vec): */
+/*
+ Store either a NULL or a quadword aligned pointer to the Vector register
+ array into *v_regs.
+*/
+ std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
+
+ mr r31,r4
+ addi r5,r3,UCONTEXT_SIGMASK
+ addi r4,r4,UCONTEXT_SIGMASK
+ li r3,SIG_SETMASK
+ bl JUMPTARGET(__sigprocmask)
+ nop
+ cmpdi r3,0
+ bne 1f /* L(error_exit) */
+
+/*
+ * If this new ucontext refers to the point where we were interrupted
+ * by a signal, we have to use the rt_sigreturn system call to
+ * return to the context so we get both LR and CTR restored.
+ *
+ * Otherwise, the context we are restoring is either just after
+ * a procedure call (getcontext/swapcontext) or at the beginning
+ * of a procedure call (makecontext), so we don't need to restore
+ * msr and ctr. We don't restore r13 since it will be used as
+ * the TLS pointer. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
+ cmpdi r0,0
+ bne 2f /* L(do_sigret) */
+
+#ifdef __CONTEXT_ENABLE_VSRS
+ /* We will check first if we have VSX capability. If so, proceed
+ with the new method for storing the VSX quadwords. Otherwise,
+ use the old method. */
+ ld r8,.LC__dl_hwcap@toc(r2)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
+# else
+ ld r8,0(r8) /* Load extern _dl_hwcap. */
+# endif
+ andi. r8,r8,PPC_FEATURE_HAS_VSX
+ ld r6,(SIGCONTEXT_VS_REGS)(r31)
+ beq 6f /* L(has_no_vs2) */
+
+# ifdef HAVE_ASM_PPC_VSX
+ /* Only proceed with this if binutils can handle .machine "power7". */
+
+/* Using VMX registers as temps to minimize the number of loads for
+ restoring the FP and the doubleword 1 of VSR[0-31]. */
+ la r7,(SIGCONTEXT_FP_REGS_PTR)(r31)
+ la r6,(SIGCONTEXT_VS_REGS)(r31)
+ /* Load f0 and f1 register state into vs32. */
+ lxvd2x vs32,0,r7
+ /* Load vs0[1] and vs1[1] register state into vs33. */
+ lxvd2x vs33,0,r6
+ /* Merge f0 and vs0[1] register state into vs0. */
+ xxmrghd vs0,vs32,vs33
+ /* Merge f1 and vs1[1] register state into vs1. */
+ xxmrgld vs1,vs32,vs33
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs34,0,r7
+ lxvd2x vs35,0,r6
+ xxmrghd vs2,vs34,vs35
+ xxmrghd vs3,vs34,vs35
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs36,0,r7
+ lxvd2x vs37,0,r6
+ xxmrghd vs4,vs36,vs37
+ xxmrghd vs5,vs36,vs37
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs38,0,r7
+ lxvd2x vs39,0,r6
+ xxmrghd vs6,vs38,vs39
+ xxmrghd vs7,vs38,vs39
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs40,0,r7
+ lxvd2x vs41,0,r6
+ xxmrghd vs8,vs40,vs41
+ xxmrghd vs9,vs40,vs41
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs42,0,r7
+ lxvd2x vs43,0,r6
+ xxmrghd vs10,vs42,vs43
+ xxmrghd vs11,vs42,vs43
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs44,0,r7
+ lxvd2x vs45,0,r6
+ xxmrghd vs12,vs44,vs45
+ xxmrghd vs13,vs44,vs45
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs46,0,r7
+ lxvd2x vs47,0,r6
+ xxmrghd vs14,vs46,vs47
+ xxmrghd vs15,vs46,vs47
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs48,0,r7
+ lxvd2x vs49,0,r6
+ xxmrghd vs16,vs48,vs49
+ xxmrghd vs17,vs48,vs49
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs50,0,r7
+ lxvd2x vs51,0,r6
+ xxmrghd vs18,vs50,vs51
+ xxmrghd vs19,vs50,vs51
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs52,0,r7
+ lxvd2x vs53,0,r6
+ xxmrghd vs20,vs52,vs53
+ xxmrghd vs21,vs52,vs53
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs54,0,r7
+ lxvd2x vs55,0,r6
+ xxmrghd vs22,vs54,vs55
+ xxmrghd vs23,vs54,vs55
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs56,0,r7
+ lxvd2x vs57,0,r6
+ xxmrghd vs24,vs56,vs57
+ xxmrghd vs25,vs56,vs57
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs58,0,r7
+ lxvd2x vs59,0,r6
+ xxmrghd vs26,vs58,vs59
+ xxmrghd vs27,vs58,vs59
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs60,0,r7
+ lxvd2x vs61,0,r6
+ xxmrghd vs28,vs60,vs61
+ xxmrghd vs29,vs60,vs61
+ addi r7,r7,16
+ addi r6,r6,16
+
+ lxvd2x vs62,0,r7
+ lxvd2x vs63,0,r6
+ xxmrghd vs30,vs62,vs63
+ xxmrghd vs31,vs62,vs63
+
+#else
+# warning "Binutils does not support VSX instructions."
+# endif
+
+ /* Now we may proceed restoring the VMX registers. */
+ ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
+ cmpdi r10,0
+ lwz r0,(33*16)(r10)
+
+ li r9,(16*32)
+ mtspr VRSAVE,r0
+ cmpwi r0,0
+
+ lvx v19,r9,r10
+ la r9,(16)(r10)
+
+ lvx v0,0,r10
+ lvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mtvscr v19
+ lvx v2,0,r10
+ lvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v4,0,r10
+ lvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v6,0,r10
+ lvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v8,0,r10
+ lvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v12,0,r10
+ lvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v14,0,r10
+ lvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v16,0,r10
+ lvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v18,0,r10
+ lvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v20,0,r10
+ lvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v22,0,r10
+ lvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v24,0,r10
+ lvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v26,0,r10
+ lvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v28,0,r10
+ lvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v30,0,r10
+ lvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ b 5f /* L(has_no_vec2) */
+
+#endif /* __CONTEXT_ENABLE_VSRS */
+6: /* L(has_no_vs2): */
+#ifdef __CONTEXT_ENABLE_VRS
+ /* Old method for restoring the registers contents. */
+ ld r8,.LC__dl_hwcap@toc(r2)
+ ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
+# ifdef SHARED
+/* Load _rtld-global._dl_hwcap. */
+ ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
+# else
+ ld r8,0(r8) /* Load extern _dl_hwcap. */
+# endif
+ andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ beq 5f /* L(has_no_vec2) */
+
+ cmpdi r10,0
+ beq 5f /* L(has_no_vec2) */
+ lwz r0,(33*16)(r10)
+
+ li r9,(16*32)
+ mtspr VRSAVE,r0
+ cmpwi r0,0
+ beq 5f /* L(has_no_vec2) */
+
+ lvx v19,r9,r10
+ la r9,(16)(r10)
+
+ lvx v0,0,r10
+ lvx v1,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ mtvscr v19
+ lvx v2,0,r10
+ lvx v3,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v4,0,r10
+ lvx v5,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v6,0,r10
+ lvx v7,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v8,0,r10
+ lvx v9,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v12,0,r10
+ lvx v13,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v14,0,r10
+ lvx v15,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v16,0,r10
+ lvx v17,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v18,0,r10
+ lvx v19,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v20,0,r10
+ lvx v21,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v22,0,r10
+ lvx v23,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v24,0,r10
+ lvx v25,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v26,0,r10
+ lvx v27,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v28,0,r10
+ lvx v29,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v30,0,r10
+ lvx v31,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+ lvx v10,0,r10
+ lvx v11,0,r9
+ addi r10,r10,32
+ addi r9,r9,32
+
+#endif /* __CONTEXT_ENABLE_VRS */
+5: /* L(has_no_vec2): */
+
+ lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
+ lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
+ lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
+ mtfsf 0xff,fp0
+ lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
+ lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
+ lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
+ lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
+ lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
+ lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
+ lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
+ lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
+ lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
+ lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
+ lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
+ lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
+ lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
+ lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
+ lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
+ lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
+ lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
+ lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
+ lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
+ lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
+ lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
+ lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
+ lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
+ lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
+ lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
+ lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
+ lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
+ lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
+ lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
+ lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
+
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
+ ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
+ mtlr r0
+ ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
+ ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
+ mtxer r0
+ ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
+ ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
+ ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
+ ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
+ ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
+ ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
+ mtcr r0
+ ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
+ ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
+ ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
+ /* Don't reload the thread ID or TLS pointer (r13). */
+ ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
+ ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
+ ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
+ ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
+ ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
+ ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
+ ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
+ ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
+ ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
+ ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
+ ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
+ ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
+ ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
+ ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
+ ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
+ ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
+ ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
+
+ /* Now we branch to the "Next Instruction Pointer" from the saved
+ context. With the powerpc64 instruction set there is no good way to
+ do this (from user state) without clobbering either the LR or CTR.
+ The makecontext and swapcontext functions depend on the callers
+ LR being preserved so we use the CTR. */
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
+ mtctr r0
+ ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
+ ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
+ bctr
+
+1: /* L(error_exit): */
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ ld r31,-8(r1)
+ blr
+
+ /* At this point we assume that the ucontext was created by a
+ rt_signal and we should use rt_sigreturn to restore the original
+ state. As of the 2.4.21 kernel the ucontext is the first thing
+ (offset 0) in the rt_signal frame and rt_sigreturn expects the
+ ucontext address in R1. Normally the rt-signal trampoline handles
+ this by popping dummy frame before the rt_signal syscall. In our
+ case the stack may not be in its original (signal handler return with
+ R1 pointing at the dummy frame) state. We do have the ucontext
+ address in R3, so simply copy R3 to R1 before the syscall. */
+2: /* L(do_sigret): */
+ mr r1,r3,
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* No return. */
+#else
+ /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
+ mflr r0
+ std r0,FRAME_LR_SAVE(r1)
+ cfi_offset (lr, FRAME_LR_SAVE)
+ stdu r1,-128(r1)
+ cfi_adjust_cfa_offset (128)
+ li r3,ENOSYS
+ bl JUMPTARGET(__syscall_error)
+ nop
+ li r3,-1
+ ld r0,128+FRAME_LR_SAVE(r1)
+ addi r1,r1,128
+ mtlr r0
+ blr
+#endif
+
+PSEUDO_END(__CONTEXT_FUNC_NAME)
Index: libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S
===================================================================
--- libc.orig/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S 2008-07-31 16:40:07.000000000 -0500
+++ libc/sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S 2008-07-31 16:40:17.000000000 -0500
@@ -27,743 +27,85 @@
#include "ucontext_i.h"
#include <asm/errno.h>
-#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
-ENTRY(__novec_swapcontext)
- CALL_MCOUNT 2
-#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
- std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
- std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
- mflr r0
- std r31,-8(1)
- cfi_offset(r31,-8)
- std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset (128)
- std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
- std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
- std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
- std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
- std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
- std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
- std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
- std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
- std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
- std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
- std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
- std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
- std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
- std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
- std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
- std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
- std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
- std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
- std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
- std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
- std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
- std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
- std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
- std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
- std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
- std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
- std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
- std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
- mfctr r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
- mfxer r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
- mfcr r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
-
- /* Set the return value of swapcontext to "success". R3 is the only
- register whose value is not preserved in the saved context. */
- li r0,0
- std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
-
- /* Zero fill fields that can't be set in user state or are unused. */
- std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
-
- /* Set the PT_REGS pointer to the address of sigcontext gp_regs
- field. Struct pt_regs and elf_gregset_t are the same thing.
- We kept the regs field for backwards compatibility with
- libraries built before we extended sigcontext. */
- addi r0,r3,SIGCONTEXT_GP_REGS
- std r0,SIGCONTEXT_PT_REGS(r3)
-
- stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
- stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
- stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
- stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
- stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
- stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
- stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
- stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
- stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
- stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
- stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
- stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
- stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
- stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
- stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
- stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
- stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
- stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
- stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
- stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
- stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
- stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
- stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
- stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
- stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
- stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
- stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
- stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
- stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
- stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
- mffs fp0
- stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
- stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
- stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
-
- mr r31,r4
- addi r5,r3,UCONTEXT_SIGMASK
- addi r4,r4,UCONTEXT_SIGMASK
- li r3,SIG_SETMASK
- bl JUMPTARGET(__sigprocmask)
- nop
- cmpdi r3,0
- bne L(nv_error_exit)
-
-/*
- * If this new ucontext refers to the point where we were interrupted
- * by a signal, we have to use the rt_sigreturn system call to
- * return to the context so we get both LR and CTR restored.
- *
- * Otherwise, the context we are restoring is either just after
- * a procedure call (getcontext/swapcontext) or at the beginning
- * of a procedure call (makecontext), so we don't need to restore
- * msr and ctr. We don't restore r13 since it will be used as
- * the TLS pointer. */
- ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
- cmpdi r0,0
- bne L(nv_do_sigret)
-
- lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
- lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
- lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
- mtfsf 0xff,fp0
- lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
- lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
- lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
- lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
- lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
- lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
- lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
- lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
- lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
- lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
- lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
- lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
- lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
- lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
- lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
- lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
- lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
- lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
- lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
- lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
- lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
- lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
- lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
- lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
- lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
- lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
- lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
- lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
- lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
- lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
-
- ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
- ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
- mtlr r0
- ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
- ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
- ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
- mtxer r0
- ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
- ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
- ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
- mtcr r0
- ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
- ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
- ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
- ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
- ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
- ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
- ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
- /* Don't reload the thread ID or TLS pointer (r13). */
- ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
- ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
- ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
- ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
- ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
- ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
- ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
- ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
- ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
- ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
- ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
- ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
- ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
- ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
- ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
- ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
- ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
-
- /* Now we branch to the "Next Instruction Pointer" from the saved
- context. With the powerpc64 instruction set there is no good way to
- do this (from user state) without clobbering either the LR or CTR.
- The makecontext and swapcontext functions depend on the callers
- LR being preserved so we use the CTR. */
- ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
- mtctr r0
- ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
- ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
- bctr
-
-L(nv_error_exit):
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- ld r31,-8(r1)
- blr
-
- /* At this point we assume that the ucontext was created by a
- rt_signal and we should use rt_sigreturn to restore the original
- state. As of the 2.4.21 kernel the ucontext is the first thing
- (offset 0) in the rt_signal frame and rt_sigreturn expects the
- ucontext address in R1. Normally the rt-signal trampoline handles
- this by popping dummy frame before the rt_signal syscall. In our
- case the stack may not be in its original (signal handler return with
- R1 pointing at the dummy frame) state. We do have the ucontext
- address in R3, so simply copy R3 to R1 before the syscall. */
-L(nv_do_sigret):
- mr r1,r3,
- li r0,SYS_ify(rt_sigreturn)
- sc
- /* No return. */
+#define __CONTEXT_FUNC_NAME __swapcontext
+#define __CONTEXT_ENABLE_VRS 1
+#define __CONTEXT_ENABLE_VSRS 1
+
+/* Size of ucontext in GLIBC_2.3.4 and later. */
+#define _UC_SIZE_2_3_4 1440
+#define _UC_SIZE_2_9 1696
+
+#ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ .section ".text";
+ENTRY (__swapcontext)
+ li r5,_UC_SIZE_2_9;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,1f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+1:
+ b __syscall_error
+END(__swapcontext)
#else
- /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
- mflr r0
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset(lr,FRAME_LR_SAVE)
- stdu r1,-128(r1)
- li r3,ENOSYS
- bl JUMPTARGET(__syscall_error)
- nop
- li r3,-1
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- blr
-#endif
-
-PSEUDO_END(__novec_swapcontext)
-
-compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
+ .section ".toc","aw"
+.LC__dl_hwcap:
+# ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+# else
+ .tc _dl_hwcap[TC],_dl_hwcap
+# endif
+ .section ".text"
+# include "swapcontext-common.S"
#endif
- .section ".toc","aw"
-.LC__dl_hwcap:
-#ifdef SHARED
+versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_9)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3_4, GLIBC_2_9)
+ compat_text_section
+# ifdef __ASSUME_SWAPCONTEXT_SYSCALL
+ENTRY (__novsx_swapcontext)
+ li r5,_UC_SIZE_2_3_4;
+ DO_CALL (SYS_ify (swapcontext));
+ bso- cr0,2f
+/* the kernel does not set the return code for the success case */
+ li r3,0
+ blr
+2:
+ b __syscall_error
+END (__novsx_swapcontext)
+# else
+# undef __CONTEXT_ENABLE_VSRS
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novsx_swapcontext
+# ifdef SHARED
.tc _rtld_global_ro[TC],_rtld_global_ro
-#else
+# else
.tc _dl_hwcap[TC],_dl_hwcap
-#endif
+# endif
.section ".text"
-
.machine "altivec"
-ENTRY(__swapcontext)
- CALL_MCOUNT 2
-#ifdef __ASSUME_NEW_RT_SIGRETURN_SYSCALL
- std r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r3)
- std r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r3)
- mflr r0
- std r31,-8(1)
- cfi_offset(r31,-8)
- std r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r3)
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- std r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r3)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset(128)
- std r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r3)
- std r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r3)
- std r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r3)
- std r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r3)
- std r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r3)
- std r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r3)
- std r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r3)
- std r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r3)
- std r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r3)
- std r13,(SIGCONTEXT_GP_REGS+(PT_R13*8))(r3)
- std r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r3)
- std r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r3)
- std r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r3)
- std r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r3)
- std r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r3)
- std r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r3)
- std r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r3)
- std r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r3)
- std r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r3)
- std r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r3)
- std r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r3)
- std r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r3)
- std r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r3)
- std r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r3)
- std r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r3)
- std r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r3)
- std r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r3)
- std r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r3)
- mfctr r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_CTR*8))(r3)
- mfxer r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r3)
- mfcr r0
- std r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r3)
-
- /* Set the return value of swapcontext to "success". R3 is the only
- register whose value is not preserved in the saved context. */
- li r0,0
- std r0,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r3)
-
- /* Zero fill fields that can't be set in user state or are unused. */
- std r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(34*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_SOFTE*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(40*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(41*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(42*8))(r3)
- std r0,(SIGCONTEXT_GP_REGS+(PT_RESULT*8))(r3)
-
- /* Set the PT_REGS pointer to the address of sigcontext gp_regs
- field. Struct pt_regs and elf_gregset_t are the same thing.
- We kept the regs field for backwards compatibility with
- libraries built before we extended sigcontext. */
- addi r0,r3,SIGCONTEXT_GP_REGS
- std r0,SIGCONTEXT_PT_REGS(r3)
-
- stfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r3)
- stfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r3)
- stfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r3)
- stfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r3)
- stfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r3)
- stfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r3)
- stfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r3)
- stfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r3)
- stfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r3)
- stfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r3)
- stfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r3)
- stfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r3)
- stfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r3)
- stfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r3)
- stfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r3)
- stfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r3)
- stfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r3)
- stfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r3)
- stfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r3)
- stfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r3)
- stfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r3)
- stfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r3)
- stfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r3)
- stfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r3)
- stfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r3)
- stfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r3)
- stfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r3)
- stfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r3)
- stfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r3)
- stfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r3)
- mffs fp0
- stfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r3)
- stfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r3)
- stfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r3)
-
- ld r8,.LC__dl_hwcap@toc(r2)
-#ifdef SHARED
-/* Load _rtld-global._dl_hwcap. */
- ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
-#else
- ld r8,0(r8) /* Load extern _dl_hwcap. */
+# include "swapcontext-common.S"
+
+ .previous
+# endif
+compat_symbol (libc, __novsx_swapcontext, swapcontext, GLIBC_2_3_4)
#endif
- la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
- la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
- andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
- clrrdi r10,r10,4
- beq L(has_no_vec)
+ compat_text_section
- clrrdi r9,r9,4
- mr r8,r10 /* Capture *v_regs value in r5. */
-
- stvx v0,0,r10
- stvx v1,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v2,0,r10
- stvx v3,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v4,0,r10
- stvx v5,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v6,0,r10
- stvx v7,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v8,0,r10
- stvx v9,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v10,0,r10
- stvx v11,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v12,0,r10
- stvx v13,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v14,0,r10
- stvx v15,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v16,0,r10
- stvx v17,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v18,0,r10
- stvx v19,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v20,0,r10
- stvx v21,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v22,0,r10
- stvx v23,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v24,0,r10
- stvx v25,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v26,0,r10
- stvx v27,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v28,0,r10
- stvx v29,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- stvx v30,0,r10
- stvx v31,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- mfvscr v0
- mfspr r0,VRSAVE
- stvx v0,0,r10
- stw r0,0(r9)
-
-L(has_no_vec):
-/*
- Store either a NULL or a quadword aligned pointer to the Vector register
- array into *v_regs.
-*/
- std r8,(SIGCONTEXT_V_REGS_PTR)(r3)
-
- mr r31,r4
- addi r5,r3,UCONTEXT_SIGMASK
- addi r4,r4,UCONTEXT_SIGMASK
- li r3,SIG_SETMASK
- bl JUMPTARGET(__sigprocmask)
- nop
- cmpdi r3,0
- bne L(error_exit)
-
-/*
- * If this new ucontext refers to the point where we were interrupted
- * by a signal, we have to use the rt_sigreturn system call to
- * return to the context so we get both LR and CTR restored.
- *
- * Otherwise, the context we are restoring is either just after
- * a procedure call (getcontext/swapcontext) or at the beginning
- * of a procedure call (makecontext), so we don't need to restore
- * msr and ctr. We don't restore r13 since it will be used as
- * the TLS pointer. */
- ld r0,(SIGCONTEXT_GP_REGS+(PT_MSR*8))(r31)
- cmpdi r0,0
- bne L(do_sigret)
+# undef __CONTEXT_FUNC_NAME
+# define __CONTEXT_FUNC_NAME __novec_swapcontext
+# undef __CONTEXT_ENABLE_VSRS
+# undef __CONTEXT_ENABLE_VRS
- ld r8,.LC__dl_hwcap@toc(r2)
- ld r10,(SIGCONTEXT_V_REGS_PTR)(r31)
-# ifdef SHARED
-/* Load _rtld-global._dl_hwcap. */
- ld r8,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r8)
-# else
- ld r8,0(r8) /* Load extern _dl_hwcap. */
-# endif
- andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
- beq L(has_no_vec2)
+# include "swapcontext-common.S"
- cmpdi r10,0
- beq L(has_no_vec2)
- lwz r0,(33*16)(r10)
-
- li r9,(16*32)
- mtspr VRSAVE,r0
- cmpwi r0,0
- beq L(has_no_vec2)
-
- lvx v19,r9,r10
- la r9,(16)(r10)
-
- lvx v0,0,r10
- lvx v1,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- mtvscr v19
- lvx v2,0,r10
- lvx v3,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v4,0,r10
- lvx v5,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v6,0,r10
- lvx v7,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v8,0,r10
- lvx v9,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v10,0,r10
- lvx v11,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v12,0,r10
- lvx v13,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v14,0,r10
- lvx v15,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v16,0,r10
- lvx v17,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v18,0,r10
- lvx v19,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v20,0,r10
- lvx v21,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v22,0,r10
- lvx v23,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v24,0,r10
- lvx v25,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v26,0,r10
- lvx v27,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v28,0,r10
- lvx v29,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v30,0,r10
- lvx v31,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
- lvx v10,0,r10
- lvx v11,0,r9
- addi r10,r10,32
- addi r9,r9,32
-
-L(has_no_vec2):
-
- lfd fp0,(SIGCONTEXT_FP_REGS+(32*8))(r31)
- lfd fp31,(SIGCONTEXT_FP_REGS+(PT_R31*8))(r31)
- lfd fp30,(SIGCONTEXT_FP_REGS+(PT_R30*8))(r31)
- mtfsf 0xff,fp0
- lfd fp29,(SIGCONTEXT_FP_REGS+(PT_R29*8))(r31)
- lfd fp28,(SIGCONTEXT_FP_REGS+(PT_R28*8))(r31)
- lfd fp27,(SIGCONTEXT_FP_REGS+(PT_R27*8))(r31)
- lfd fp26,(SIGCONTEXT_FP_REGS+(PT_R26*8))(r31)
- lfd fp25,(SIGCONTEXT_FP_REGS+(PT_R25*8))(r31)
- lfd fp24,(SIGCONTEXT_FP_REGS+(PT_R24*8))(r31)
- lfd fp23,(SIGCONTEXT_FP_REGS+(PT_R23*8))(r31)
- lfd fp22,(SIGCONTEXT_FP_REGS+(PT_R22*8))(r31)
- lfd fp21,(SIGCONTEXT_FP_REGS+(PT_R21*8))(r31)
- lfd fp20,(SIGCONTEXT_FP_REGS+(PT_R20*8))(r31)
- lfd fp19,(SIGCONTEXT_FP_REGS+(PT_R19*8))(r31)
- lfd fp18,(SIGCONTEXT_FP_REGS+(PT_R18*8))(r31)
- lfd fp17,(SIGCONTEXT_FP_REGS+(PT_R17*8))(r31)
- lfd fp16,(SIGCONTEXT_FP_REGS+(PT_R16*8))(r31)
- lfd fp15,(SIGCONTEXT_FP_REGS+(PT_R15*8))(r31)
- lfd fp14,(SIGCONTEXT_FP_REGS+(PT_R14*8))(r31)
- lfd fp13,(SIGCONTEXT_FP_REGS+(PT_R13*8))(r31)
- lfd fp12,(SIGCONTEXT_FP_REGS+(PT_R12*8))(r31)
- lfd fp11,(SIGCONTEXT_FP_REGS+(PT_R11*8))(r31)
- lfd fp10,(SIGCONTEXT_FP_REGS+(PT_R10*8))(r31)
- lfd fp9,(SIGCONTEXT_FP_REGS+(PT_R9*8))(r31)
- lfd fp8,(SIGCONTEXT_FP_REGS+(PT_R8*8))(r31)
- lfd fp7,(SIGCONTEXT_FP_REGS+(PT_R7*8))(r31)
- lfd fp6,(SIGCONTEXT_FP_REGS+(PT_R6*8))(r31)
- lfd fp5,(SIGCONTEXT_FP_REGS+(PT_R5*8))(r31)
- lfd fp4,(SIGCONTEXT_FP_REGS+(PT_R4*8))(r31)
- lfd fp3,(SIGCONTEXT_FP_REGS+(PT_R3*8))(r31)
- lfd fp2,(SIGCONTEXT_FP_REGS+(PT_R2*8))(r31)
- lfd fp1,(SIGCONTEXT_FP_REGS+(PT_R1*8))(r31)
- lfd fp0,(SIGCONTEXT_FP_REGS+(PT_R0*8))(r31)
-
- ld r0,(SIGCONTEXT_GP_REGS+(PT_LNK*8))(r31)
- ld r1,(SIGCONTEXT_GP_REGS+(PT_R1*8))(r31)
- mtlr r0
- ld r2,(SIGCONTEXT_GP_REGS+(PT_R2*8))(r31)
- ld r0,(SIGCONTEXT_GP_REGS+(PT_XER*8))(r31)
- ld r3,(SIGCONTEXT_GP_REGS+(PT_R3*8))(r31)
- mtxer r0
- ld r4,(SIGCONTEXT_GP_REGS+(PT_R4*8))(r31)
- ld r0,(SIGCONTEXT_GP_REGS+(PT_CCR*8))(r31)
- ld r5,(SIGCONTEXT_GP_REGS+(PT_R5*8))(r31)
- ld r6,(SIGCONTEXT_GP_REGS+(PT_R6*8))(r31)
- ld r7,(SIGCONTEXT_GP_REGS+(PT_R7*8))(r31)
- ld r8,(SIGCONTEXT_GP_REGS+(PT_R8*8))(r31)
- ld r9,(SIGCONTEXT_GP_REGS+(PT_R9*8))(r31)
- mtcr r0
- ld r10,(SIGCONTEXT_GP_REGS+(PT_R10*8))(r31)
- ld r11,(SIGCONTEXT_GP_REGS+(PT_R11*8))(r31)
- ld r12,(SIGCONTEXT_GP_REGS+(PT_R12*8))(r31)
- /* Don't reload the thread ID or TLS pointer (r13). */
- ld r14,(SIGCONTEXT_GP_REGS+(PT_R14*8))(r31)
- ld r15,(SIGCONTEXT_GP_REGS+(PT_R15*8))(r31)
- ld r16,(SIGCONTEXT_GP_REGS+(PT_R16*8))(r31)
- ld r17,(SIGCONTEXT_GP_REGS+(PT_R17*8))(r31)
- ld r18,(SIGCONTEXT_GP_REGS+(PT_R18*8))(r31)
- ld r19,(SIGCONTEXT_GP_REGS+(PT_R19*8))(r31)
- ld r20,(SIGCONTEXT_GP_REGS+(PT_R20*8))(r31)
- ld r21,(SIGCONTEXT_GP_REGS+(PT_R21*8))(r31)
- ld r22,(SIGCONTEXT_GP_REGS+(PT_R22*8))(r31)
- ld r23,(SIGCONTEXT_GP_REGS+(PT_R23*8))(r31)
- ld r24,(SIGCONTEXT_GP_REGS+(PT_R24*8))(r31)
- ld r25,(SIGCONTEXT_GP_REGS+(PT_R25*8))(r31)
- ld r26,(SIGCONTEXT_GP_REGS+(PT_R26*8))(r31)
- ld r27,(SIGCONTEXT_GP_REGS+(PT_R27*8))(r31)
- ld r28,(SIGCONTEXT_GP_REGS+(PT_R28*8))(r31)
- ld r29,(SIGCONTEXT_GP_REGS+(PT_R29*8))(r31)
- ld r30,(SIGCONTEXT_GP_REGS+(PT_R30*8))(r31)
-
- /* Now we branch to the "Next Instruction Pointer" from the saved
- context. With the powerpc64 instruction set there is no good way to
- do this (from user state) without clobbering either the LR or CTR.
- The makecontext and swapcontext functions depend on the callers
- LR being preserved so we use the CTR. */
- ld r0,(SIGCONTEXT_GP_REGS+(PT_NIP*8))(r31)
- mtctr r0
- ld r0,(SIGCONTEXT_GP_REGS+(PT_R0*8))(r31)
- ld r31,(SIGCONTEXT_GP_REGS+(PT_R31*8))(r31)
- bctr
-
-L(error_exit):
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- ld r31,-8(r1)
- blr
-
- /* At this point we assume that the ucontext was created by a
- rt_signal and we should use rt_sigreturn to restore the original
- state. As of the 2.4.21 kernel the ucontext is the first thing
- (offset 0) in the rt_signal frame and rt_sigreturn expects the
- ucontext address in R1. Normally the rt-signal trampoline handles
- this by popping dummy frame before the rt_signal syscall. In our
- case the stack may not be in its original (signal handler return with
- R1 pointing at the dummy frame) state. We do have the ucontext
- address in R3, so simply copy R3 to R1 before the syscall. */
-L(do_sigret):
- mr r1,r3,
- li r0,SYS_ify(rt_sigreturn)
- sc
- /* No return. */
-#else
- /* If the kernel is not at least 2.4.21 then generate a ENOSYS stub. */
- mflr r0
- std r0,FRAME_LR_SAVE(r1)
- cfi_offset (lr, FRAME_LR_SAVE)
- stdu r1,-128(r1)
- cfi_adjust_cfa_offset (128)
- li r3,ENOSYS
- bl JUMPTARGET(__syscall_error)
- nop
- li r3,-1
- ld r0,128+FRAME_LR_SAVE(r1)
- addi r1,r1,128
- mtlr r0
- blr
-#endif
+ .previous
-PSEUDO_END(__swapcontext)
+compat_symbol (libc, __novec_swapcontext, swapcontext, GLIBC_2_3)
-versioned_symbol (libc, __swapcontext, swapcontext, GLIBC_2_3_4)
+#endif