This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][BZ #6816][4/5] VSX implementation for *context routines (powerpc64)



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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]