/* Save current context and install the given one.
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002-2019 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
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., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
#include <sysdep.h>
#include <rtld-global-offsets.h>
#include <shlib-compat.h>
-#include "kernel-features.h"
#define __ASSEMBLY__
#include <asm/ptrace.h>
#include "ucontext_i.h"
#include <asm/errno.h>
+ .section ".toc","aw"
+.LC__dl_hwcap:
+#ifdef SHARED
+ .tc _rtld_global_ro[TC],_rtld_global_ro
+#else
+ .tc _dl_hwcap[TC],_dl_hwcap
+#endif
+
#if SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)
+ .section ".text"
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)
cmpdi r0,0
bne L(nv_do_sigret)
+ 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
+
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)
+
+# ifdef _ARCH_PWR6
+ /* Use the extended four-operand version of the mtfsf insn. */
+ .machine push
+ .machine "power6"
+
+ mtfsf 0xff,fp0,1,0
+
+ .machine pop
+# else
+ /* Availability of DFP indicates a 64-bit FPSCR. */
+ andi. r6,r8,PPC_FEATURE_HAS_DFP
+ beq 5f
+
+ .machine push
+ .machine "power6"
+
+ mtfsf 0xff,fp0,1,0
+
+ .machine pop
+
+ b 6f
+ /* Continue to operate on the FPSCR as if it were 32-bits. */
+5:
mtfsf 0xff,fp0
+6:
+#endif /* _ARCH_PWR6 */
+
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)
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)
- 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)
#endif
- .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"
-
.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)
la r10,(SIGCONTEXT_V_RESERVE+8)(r3)
la r9,(SIGCONTEXT_V_RESERVE+24)(r3)
- andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
clrrdi r10,r10,4
beq L(has_no_vec)
# else
ld r8,0(r8) /* Load extern _dl_hwcap. */
# endif
- andis. r8,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ andis. r6,r8,(PPC_FEATURE_HAS_ALTIVEC >> 16)
beq L(has_no_vec2)
cmpdi r10,0
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)
+
+# ifdef _ARCH_PWR6
+ /* Use the extended four-operand version of the mtfsf insn. */
+ .machine push
+ .machine "power6"
+
+ mtfsf 0xff,fp0,1,0
+
+ .machine pop
+# else
+ /* Availability of DFP indicates a 64-bit FPSCR. */
+ andi. r6,r8,PPC_FEATURE_HAS_DFP
+ beq 7f
+
+ .machine push
+ .machine "power6"
+
+ mtfsf 0xff,fp0,1,0
+
+ .machine pop
+
+ b 8f
+ /* Continue to operate on the FPSCR as if it were 32-bits. */
+7:
mtfsf 0xff,fp0
+8:
+#endif /* _ARCH_PWR6 */
+
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)
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)
- 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(__swapcontext)