aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-01-16 04:50:59 +0000
committerUlrich Drepper <drepper@redhat.com>2004-01-16 04:50:59 +0000
commit5ef6ae4bdb04ed21b8efc70566d22fab821ec6b2 (patch)
tree15f431839d8211e34b54bd4294f48a25770a0170 /sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
parent39b04aa39823faf1cc414e7f3eca4f43e01426e4 (diff)
downloadglibc-5ef6ae4bdb04ed21b8efc70566d22fab821ec6b2.zip
glibc-5ef6ae4bdb04ed21b8efc70566d22fab821ec6b2.tar.gz
glibc-5ef6ae4bdb04ed21b8efc70566d22fab821ec6b2.tar.bz2
Update.
2004-01-14 Steven Munroe <sjmunroe@us.ibm.com> * include/libc-symbols.h [HAVE_ASM_GLOBAL_DOT_NAME] (_symbol_version): Use C_SYMBOL_DOT_NAME to create '.'ed symbols. (_default_symbol_version): Use C_SYMBOL_DOT_NAME to create '.'ed symbols. * sysdeps/powerpc/Makefile: Add rtld-global-offsets.sym to gen-as-const-headers. * sysdeps/powerpc/elf/rtld-global-offsets.sym: New file. * sysdeps/powerpc/sysdep.h: Define v# symbols for vector registers. Define PPC_FEATURE_* masks for Aux Vector AT_HWCAP. * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_SWAPCONTEXT_SYSCALL): Define for PPC and 2.6.0 kernels. * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h [!__WORDSIZE == 32]: Declare mcontext_t inline and include altivec state for 64-bit. * sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions: Add GLIBC_2.3.4 versions for setcontext, getcontext, and swapcontext. * sysdeps/unix/sysv/linux/powerpc/powerpc64/Versions: Add GLIBC_2.3.4 versions for setcontext, getcontext, swapcontext, and makecontext. * sysdeps/unix/sysv/linux/powerpc/powerpc64/getcontext.S (__getcontext): Upgrade to save Altivec regs and version GLIBC_2_3_4. [SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)](__novec_getcontext): Compatible with GLIBC_2.3.3 release. * sysdeps/unix/sysv/linux/powerpc/powerpc64/makecontext.S (__makecontext): Use parm save area instead of compiler_dw to hold context pointer. * sysdeps/unix/sysv/linux/powerpc/powerpc64/setcontext.S (__setcontext): Upgrade to restore Altivec regs and version GLIBC_2_3_4. [SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)](__novec_setcontext): Compatible with GLIBC_2.3.3 release. * sysdeps/unix/sysv/linux/powerpc/powerpc64/swapcontext.S (__swapcontext): Upgrade to swap Altivec regs and version GLIBC_2_3_4. [SHLIB_COMPAT (libc, GLIBC_2_3, GLIBC_2_3_4)](__novec_swapcontext): Compatible with GLIBC_2.3.3 release. * sysdeps/unix/sysv/linux/powerpc/powerpc64/ucontext_i.h (SIGCONTEXT_V_REGS_PTR, SIGCONTEXT_V_RESERVE): Defined. 2004-01-12 Steven Munroe <sjmunroe@us.ibm.com> * sysdeps/unix/sysv/linux/powerpc/powerpc32/Versions: Add GLIBC_2.3.4 versions for setcontext, getcontext, swapcontext, and makecontext. * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S (__getcontext): Upgrade to save Altivec regs and version GLIBC_2_3_4. [SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)](__novec_getcontext): Compatible with GLIBC_2.3.3 release. * sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S (__makecontext): Upgrade to align for Altivec regs and version GLIBC_2_3_4. [SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)](__novec_makecontext): Compatible with GLIBC_2.3.3 release. * sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S (__setcontext): Upgrade to restore Altivec regs and version GLIBC_2_3_4. [SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)](__novec_setcontext): Compatible with GLIBC_2.3.3 release. * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S (__swapcontext): Upgrade to swap Altivec regs and version GLIBC_2_3_4. [SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)] (__novec_swapcontext): Compatible with GLIBC_2.3.3 release. * sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h: (_UC_VSCR, _UC_VRSAVE): Define. (_FRAME_BACKCHAIN, _FRAME_LR_SAVE,_FRAME_PARM_SAVE1,_FRAME_PARM_SAVE2, _FRAME_PARM_SAVE3, _FRAME_PARM_SAVE4): Defined.
Diffstat (limited to 'sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S')
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S253
1 files changed, 249 insertions, 4 deletions
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
index deb9461..cb27797 100644
--- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
+++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
@@ -1,5 +1,5 @@
/* Jump to a new context.
- Copyright (C) 2002 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004 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
@@ -18,6 +18,7 @@
02111-1307 USA. */
#include <sysdep.h>
+#include <rtld-global-offsets.h>
#include <shlib-compat.h>
#define __ASSEMBLY__
@@ -53,7 +54,122 @@ ENTRY(__setcontext)
bl JUMPTARGET(sigprocmask)
cmpwi r3,0
bne L(error_exit)
+
+#ifdef PIC
+ mflr r8
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r7
+#ifdef SHARED
+ lwz r7,_rtld_global@got(r7)
+ mtlr r8
+ lwz r7,RTLD_GLOBAL_DL_HWCAP_OFFSET(r7)
+#else
+ lwz r7,_dl_hwcap@got(r7)
+ mtlr r8
+ lwz r7,0(r7)
+#endif
+#else
+ lis r7,_dl_hwcap@ha
+ lwz r7,_dl_hwcap@l(r7)
+#endif
+ andis. r7,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16)
+ la r10,(_UC_VREGS)(r31)
+ beq L(has_no_vec)
+
+ lwz r0,(32*16)(r10)
+ li r9,(32*16)
+ cmpwi r0,0
+ mtspr VRSAVE,r0
+ 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 v11,0,r9
+ addi r19,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
+
+L(has_no_vec):
/* Restore the floating-point registers */
lfd fp31,_UC_FREGS+(32*8)(r31)
lfd fp0,_UC_FREGS+(0*8)(r31)
@@ -147,9 +263,138 @@ L(do_sigret):
PSEUDO_END (__setcontext)
-versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_3)
+versioned_symbol (libc, __setcontext, setcontext, GLIBC_2_3_4)
+
+#if SHLIB_COMPAT (libc, GLIBC_2_3_3, GLIBC_2_3_4)
+
+ENTRY(__novec_setcontext)
+ mflr r0
+ stwu r1,-16(r1)
+ stw r0,20(r1)
+ stw r31,12(r1)
+ lwz r31,_UC_REGS_PTR(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
+ * r0, xer, ctr. We don't restore r2 since it will be used as
+ * the TLS pointer.
+ */
+ lwz r0,_UC_GREGS+(PT_MSR*4)(r31)
+ cmpwi r0,0
+ bne L(novec_do_sigret)
+
+ /* Restore the signal mask */
+ li r5,0
+ addi r4,r3,_UC_SIGMASK
+ li r3,SIG_SETMASK
+ bl JUMPTARGET(sigprocmask)
+ cmpwi r3,0
+ bne L(novec_error_exit)
+
+ /* Restore the floating-point registers */
+ lfd fp31,_UC_FREGS+(32*8)(r31)
+ lfd fp0,_UC_FREGS+(0*8)(r31)
+ mtfsf 0xff,fp31
+ lfd fp1,_UC_FREGS+(1*8)(r31)
+ lfd fp2,_UC_FREGS+(2*8)(r31)
+ lfd fp3,_UC_FREGS+(3*8)(r31)
+ lfd fp4,_UC_FREGS+(4*8)(r31)
+ lfd fp5,_UC_FREGS+(5*8)(r31)
+ lfd fp6,_UC_FREGS+(6*8)(r31)
+ lfd fp7,_UC_FREGS+(7*8)(r31)
+ lfd fp8,_UC_FREGS+(8*8)(r31)
+ lfd fp9,_UC_FREGS+(9*8)(r31)
+ lfd fp10,_UC_FREGS+(10*8)(r31)
+ lfd fp11,_UC_FREGS+(11*8)(r31)
+ lfd fp12,_UC_FREGS+(12*8)(r31)
+ lfd fp13,_UC_FREGS+(13*8)(r31)
+ lfd fp14,_UC_FREGS+(14*8)(r31)
+ lfd fp15,_UC_FREGS+(15*8)(r31)
+ lfd fp16,_UC_FREGS+(16*8)(r31)
+ lfd fp17,_UC_FREGS+(17*8)(r31)
+ lfd fp18,_UC_FREGS+(18*8)(r31)
+ lfd fp19,_UC_FREGS+(19*8)(r31)
+ lfd fp20,_UC_FREGS+(20*8)(r31)
+ lfd fp21,_UC_FREGS+(21*8)(r31)
+ lfd fp22,_UC_FREGS+(22*8)(r31)
+ lfd fp23,_UC_FREGS+(23*8)(r31)
+ lfd fp24,_UC_FREGS+(24*8)(r31)
+ lfd fp25,_UC_FREGS+(25*8)(r31)
+ lfd fp26,_UC_FREGS+(26*8)(r31)
+ lfd fp27,_UC_FREGS+(27*8)(r31)
+ lfd fp28,_UC_FREGS+(28*8)(r31)
+ lfd fp29,_UC_FREGS+(29*8)(r31)
+ lfd fp30,_UC_FREGS+(30*8)(r31)
+ lfd fp31,_UC_FREGS+(31*8)(r31)
+
+ /* Restore LR and CCR, and set CTR to the NIP value */
+ lwz r3,_UC_GREGS+(PT_LNK*4)(r31)
+ lwz r4,_UC_GREGS+(PT_NIP*4)(r31)
+ lwz r5,_UC_GREGS+(PT_CCR*4)(r31)
+ mtlr r3
+ mtctr r4
+ mtcr r5
+
+ /* Restore the general registers */
+ lwz r1,_UC_GREGS+(PT_R1*4)(r31)
+ lwz r3,_UC_GREGS+(PT_R3*4)(r31)
+ lwz r4,_UC_GREGS+(PT_R4*4)(r31)
+ lwz r5,_UC_GREGS+(PT_R5*4)(r31)
+ lwz r6,_UC_GREGS+(PT_R6*4)(r31)
+ lwz r7,_UC_GREGS+(PT_R7*4)(r31)
+ lwz r8,_UC_GREGS+(PT_R8*4)(r31)
+ lwz r9,_UC_GREGS+(PT_R9*4)(r31)
+ lwz r10,_UC_GREGS+(PT_R10*4)(r31)
+ lwz r11,_UC_GREGS+(PT_R11*4)(r31)
+ lwz r12,_UC_GREGS+(PT_R12*4)(r31)
+ lwz r13,_UC_GREGS+(PT_R13*4)(r31)
+ lwz r14,_UC_GREGS+(PT_R14*4)(r31)
+ lwz r15,_UC_GREGS+(PT_R15*4)(r31)
+ lwz r16,_UC_GREGS+(PT_R16*4)(r31)
+ lwz r17,_UC_GREGS+(PT_R17*4)(r31)
+ lwz r18,_UC_GREGS+(PT_R18*4)(r31)
+ lwz r19,_UC_GREGS+(PT_R19*4)(r31)
+ lwz r20,_UC_GREGS+(PT_R20*4)(r31)
+ lwz r21,_UC_GREGS+(PT_R21*4)(r31)
+ lwz r22,_UC_GREGS+(PT_R22*4)(r31)
+ lwz r23,_UC_GREGS+(PT_R23*4)(r31)
+ lwz r24,_UC_GREGS+(PT_R24*4)(r31)
+ lwz r25,_UC_GREGS+(PT_R25*4)(r31)
+ lwz r26,_UC_GREGS+(PT_R26*4)(r31)
+ lwz r27,_UC_GREGS+(PT_R27*4)(r31)
+ lwz r28,_UC_GREGS+(PT_R28*4)(r31)
+ lwz r29,_UC_GREGS+(PT_R29*4)(r31)
+ lwz r30,_UC_GREGS+(PT_R30*4)(r31)
+ lwz r31,_UC_GREGS+(PT_R31*4)(r31)
+
+ bctr
+
+L(novec_error_exit):
+ lwz r31,12(r1)
+ lwz r0,20(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
+
+L(novec_do_sigret):
+ addi r1,r3,-0xd0
+ li r0,SYS_ify(rt_sigreturn)
+ sc
+ /* NOTREACHED */
+
+PSEUDO_END (__setcontext)
+
+compat_symbol (libc, __novec_setcontext, setcontext, GLIBC_2_3_3)
+
+#endif
-#if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_3)
+#if SHLIB_COMPAT (libc, GLIBC_2_1, GLIBC_2_3_3)
#define _ERRNO_H 1
#include <bits/errno.h>
@@ -159,6 +404,6 @@ ENTRY (__setcontext_stub)
b JUMPTARGET(__syscall_error)
END (__setcontext_stub)
-compat_symbol (libc, __setcontext_stub, setcontext, GLIBC_2_0)
+compat_symbol (libc, __setcontext_stub, setcontext, GLIBC_2_1)
#endif