Update.
authorUlrich Drepper <drepper@redhat.com>
Wed, 18 Jun 2003 03:38:07 +0000 (03:38 +0000)
committerUlrich Drepper <drepper@redhat.com>
Wed, 18 Jun 2003 03:38:07 +0000 (03:38 +0000)
2003-06-17  Paul Mackerras  <paulus@samba.org>

* sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S: New file.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h: New file.
* sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: Adjust.

ChangeLog
sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S [new file with mode: 0644]
sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h

index 76ba21a5df9f19bd8bba78bc98250dd6398e62df..a118e6ed7c7d503569842dad56cfdc081f955b95 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2003-06-17  Paul Mackerras  <paulus@samba.org>
+
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S: New file.
+       * sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h: New file.
+       * sysdeps/unix/sysv/linux/powerpc/sys/ucontext.h: Adjust.
+
 2003-06-17  Jakub Jelinek  <jakub@redhat.com>
 
        * posix/regcomp.c (build_word_op): Use alnum instead of alpha class.
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/getcontext.S
new file mode 100644 (file)
index 0000000..9405d12
--- /dev/null
@@ -0,0 +1,126 @@
+/* Save current context.
+   Copyright (C) 2002 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+
+ENTRY(__getcontext)
+       stw     r0,_UC_GREGS+(PT_R0*4)(r3)
+       stw     r1,_UC_GREGS+(PT_R1*4)(r3)
+       mflr    r0
+       stwu    r1,-16(r1)
+       stw     r0,20(r1)
+       stw     r0,_UC_GREGS+(PT_LNK*4)(r3)
+       stw     r0,_UC_GREGS+(PT_NIP*4)(r3)
+       stw     r2,_UC_GREGS+(PT_R2*4)(r3)
+       stw     r4,_UC_GREGS+(PT_R4*4)(r3)
+       stw     r5,_UC_GREGS+(PT_R5*4)(r3)
+       stw     r6,_UC_GREGS+(PT_R6*4)(r3)
+       stw     r7,_UC_GREGS+(PT_R7*4)(r3)
+       stw     r8,_UC_GREGS+(PT_R8*4)(r3)
+       stw     r9,_UC_GREGS+(PT_R9*4)(r3)
+       stw     r10,_UC_GREGS+(PT_R10*4)(r3)
+       stw     r11,_UC_GREGS+(PT_R11*4)(r3)
+       stw     r12,_UC_GREGS+(PT_R12*4)(r3)
+       stw     r13,_UC_GREGS+(PT_R13*4)(r3)
+       stw     r14,_UC_GREGS+(PT_R14*4)(r3)
+       stw     r15,_UC_GREGS+(PT_R15*4)(r3)
+       stw     r16,_UC_GREGS+(PT_R16*4)(r3)
+       stw     r17,_UC_GREGS+(PT_R17*4)(r3)
+       stw     r18,_UC_GREGS+(PT_R18*4)(r3)
+       stw     r19,_UC_GREGS+(PT_R19*4)(r3)
+       stw     r20,_UC_GREGS+(PT_R20*4)(r3)
+       stw     r21,_UC_GREGS+(PT_R21*4)(r3)
+       stw     r22,_UC_GREGS+(PT_R22*4)(r3)
+       stw     r23,_UC_GREGS+(PT_R23*4)(r3)
+       stw     r24,_UC_GREGS+(PT_R24*4)(r3)
+       stw     r25,_UC_GREGS+(PT_R25*4)(r3)
+       stw     r26,_UC_GREGS+(PT_R26*4)(r3)
+       stw     r27,_UC_GREGS+(PT_R27*4)(r3)
+       stw     r28,_UC_GREGS+(PT_R28*4)(r3)
+       stw     r29,_UC_GREGS+(PT_R29*4)(r3)
+       stw     r30,_UC_GREGS+(PT_R30*4)(r3)
+       stw     r31,_UC_GREGS+(PT_R31*4)(r3)
+       mfctr   r0
+       stw     r0,_UC_GREGS+(PT_CTR*4)(r3)
+       mfxer   r0
+       stw     r0,_UC_GREGS+(PT_XER*4)(r3)
+       mfcr    r0
+       stw     r0,_UC_GREGS+(PT_CCR*4)(r3)
+
+       /* Set the return value of getcontext to "success".  R3 is the only 
+          register whose value is not preserved in the saved context.  */
+       li      r0,0
+       stw     r0,_UC_GREGS+(PT_R3*4)(r3)
+
+       /* Zero fill fields that can't be set in user state. */
+       stw     r0,_UC_GREGS+(PT_MSR*4)(r3)
+       stw     r0,_UC_GREGS+(PT_MQ*4)(r3)
+
+       /* Save the floating-point registers */
+       stfd    fp0,_UC_FREGS+(0*8)(r3)
+       stfd    fp1,_UC_FREGS+(1*8)(r3)
+       stfd    fp2,_UC_FREGS+(2*8)(r3)
+       stfd    fp3,_UC_FREGS+(3*8)(r3)
+       stfd    fp4,_UC_FREGS+(4*8)(r3)
+       stfd    fp5,_UC_FREGS+(5*8)(r3)
+       stfd    fp6,_UC_FREGS+(6*8)(r3)
+       stfd    fp7,_UC_FREGS+(7*8)(r3)
+       stfd    fp8,_UC_FREGS+(8*8)(r3)
+       stfd    fp9,_UC_FREGS+(9*8)(r3)
+       stfd    fp10,_UC_FREGS+(10*8)(r3)
+       stfd    fp11,_UC_FREGS+(11*8)(r3)
+       stfd    fp12,_UC_FREGS+(12*8)(r3)
+       stfd    fp13,_UC_FREGS+(13*8)(r3)
+       stfd    fp14,_UC_FREGS+(14*8)(r3)
+       stfd    fp15,_UC_FREGS+(15*8)(r3)
+       stfd    fp16,_UC_FREGS+(16*8)(r3)
+       stfd    fp17,_UC_FREGS+(17*8)(r3)
+       stfd    fp18,_UC_FREGS+(18*8)(r3)
+       stfd    fp19,_UC_FREGS+(19*8)(r3)
+       stfd    fp20,_UC_FREGS+(20*8)(r3)
+       stfd    fp21,_UC_FREGS+(21*8)(r3)
+       stfd    fp22,_UC_FREGS+(22*8)(r3)
+       stfd    fp23,_UC_FREGS+(23*8)(r3)
+       stfd    fp24,_UC_FREGS+(24*8)(r3)
+       stfd    fp25,_UC_FREGS+(25*8)(r3)
+       stfd    fp26,_UC_FREGS+(26*8)(r3)
+       stfd    fp27,_UC_FREGS+(27*8)(r3)
+       stfd    fp28,_UC_FREGS+(28*8)(r3)
+       stfd    fp29,_UC_FREGS+(29*8)(r3)
+       mffs    fp0
+       stfd    fp30,_UC_FREGS+(30*8)(r3)
+       stfd    fp31,_UC_FREGS+(31*8)(r3)
+       stfd    fp0,_UC_FREGS+(32*8)(r3)
+
+       addi    r5,r3,_UC_SIGMASK
+       li      r4,0
+       li      r3,SIG_BLOCK
+       bl      JUMPTARGET(sigprocmask)
+
+       lwz     r0,20(r1)
+       addi    r1,r1,16
+       mtlr    r0
+       blr
+PSEUDO_END(__getcontext)
+
+weak_alias(__getcontext, getcontext)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/makecontext.S
new file mode 100644 (file)
index 0000000..b875aa5
--- /dev/null
@@ -0,0 +1,105 @@
+/* Set up a context to call a function.
+   Copyright (C) 2002 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+
+ENTRY(__makecontext)
+       /* Set up the first 7 args to the function in its registers */
+       stw     r6,_UC_GREGS+(PT_R3*4)(r3)
+       stw     r7,_UC_GREGS+(PT_R4*4)(r3)
+       stw     r8,_UC_GREGS+(PT_R5*4)(r3)
+       stw     r9,_UC_GREGS+(PT_R6*4)(r3)
+       stw     r10,_UC_GREGS+(PT_R7*4)(r3)
+       lwz     r8,8(r1)
+       lwz     r9,12(r1)
+       stw     r8,_UC_GREGS+(PT_R8*4)(r3)
+       stw     r9,_UC_GREGS+(PT_R9*4)(r3)
+
+       /* Set the NIP to the start of the function */
+       stw     r4,_UC_GREGS+(PT_NIP*4)(r3)
+
+       /* Set the function's r31 to ucp->uc_link for the exitcode below. */
+       lwz     r7,_UC_LINK(r3)
+       stw     r7,_UC_GREGS+(PT_R31*4)(r3)
+
+       /* Set the function's LR to point to the exitcode below. */
+#ifdef PIC
+       mflr    r0
+       bl      1f
+1:     mflr    r6
+       addi    r6,r6,L(exitcode)-1b
+       mtlr    r0
+#else
+       lis     r6,L(exitcode)@ha
+       addi    r6,r6,L(exitcode)@l
+#endif
+       stw     r6,_UC_GREGS+(PT_LNK*4)(r3)
+
+       /*
+        * Set up the stack frame for the function.
+        * If we have more than 5 args to the function (8 args to makecontext),
+        * there will be some arguments on the stack which have to end up
+        * in registers.  If there are more than 8 args to the function,
+        * we have to copy (argc - 8) args from our stack to the functions'
+        * stack (and allow space for them in the frame).
+        */
+       lwz     r4,_UC_STACK_SP(r3)
+       lwz     r8,_UC_STACK_SIZE(r3)
+       add     r4,r4,r8
+       rlwinm  r4,r4,0,0,27    /* round down to 16-byte boundary */
+       addi    r7,r4,-16       /* stack frame for fn's caller */
+       cmpwi   r5,8
+       blt     2f              /* less than 8 args is easy */
+       lwz     r10,16(r1)
+       stw     r10,_UC_GREGS+(PT_R10*4)(r3)
+       beq     2f              /* if exactly 8 args */
+       subi    r9,r5,3
+       subi    r5,r5,8
+       rlwinm  r9,r9,2,0,27
+       subf    r7,r9,r4
+       mtctr   r5              /* copy the 9th and following args */
+       addi    r6,r1,16
+       addi    r8,r7,4
+3:     lwzu    r10,4(r6)
+       stwu    r10,4(r8)
+       bdnz    3b
+2:     stw     r7,_UC_GREGS+(PT_R1*4)(r3)
+       li      r6,0
+       stw     r6,0(r7)
+
+       blr
+
+/*
+ * If the function returns, it comes here.  We put ucp->uc_link in
+ * r31, which is a callee-saved register.  We have to continue with
+ * the context that r31 points to, or exit if it is 0.
+ */
+L(exitcode):
+       mr.     r3,r31
+       beq     4f
+       bl      JUMPTARGET(__setcontext)
+4:     bl      HIDDEN_JUMPTARGET(exit)
+       b       4b
+
+END(__makecontext)
+weak_alias(__makecontext, makecontext)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/setcontext.S
new file mode 100644 (file)
index 0000000..1539b40
--- /dev/null
@@ -0,0 +1,149 @@
+/* Jump to a new context.
+   Copyright (C) 2002 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+
+ENTRY(__setcontext)
+       mflr    r0
+       stwu    r1,-16(r1)
+       stw     r0,20(r1)
+       stw     r31,12(r1)
+       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
+        * 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(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(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(error_exit):
+       lwz     r31,12(r1)
+       lwz     r0,20(r1)
+       addi    r1,r1,16
+       mtlr    r0
+       blr
+       
+L(do_sigret):
+       addi    r1,r3,-0xd0
+       li      r0,SYS_ify(rt_sigreturn)
+       sc
+       /* NOTREACHED */
+
+PSEUDO_END(__setcontext)
+
+weak_alias(__setcontext, setcontext)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S b/sysdeps/unix/sysv/linux/powerpc/powerpc32/swapcontext.S
new file mode 100644 (file)
index 0000000..88cf0da
--- /dev/null
@@ -0,0 +1,233 @@
+/* Save current context and jump to a new context.
+   Copyright (C) 2002 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+#define __ASSEMBLY__
+#include <asm/ptrace.h>
+#include "ucontext_i.h"
+
+ENTRY(__swapcontext)
+       /* Save the current context */
+       stw     r0,_UC_GREGS+(PT_R0*4)(r3)
+       stw     r1,_UC_GREGS+(PT_R1*4)(r3)
+       mflr    r0
+       stwu    r1,-16(r1)
+       stw     r0,20(r1)
+       stw     r31,12(r1)
+       stw     r31,_UC_GREGS+(PT_R31*4)(r3)
+       mr      r31,r4                  /* new context pointer */
+       stw     r0,_UC_GREGS+(PT_LNK*4)(r3)
+       stw     r0,_UC_GREGS+(PT_NIP*4)(r3)
+       stw     r2,_UC_GREGS+(PT_R2*4)(r3)
+       stw     r4,_UC_GREGS+(PT_R4*4)(r3)
+       stw     r5,_UC_GREGS+(PT_R5*4)(r3)
+       stw     r6,_UC_GREGS+(PT_R6*4)(r3)
+       stw     r7,_UC_GREGS+(PT_R7*4)(r3)
+       stw     r8,_UC_GREGS+(PT_R8*4)(r3)
+       stw     r9,_UC_GREGS+(PT_R9*4)(r3)
+       stw     r10,_UC_GREGS+(PT_R10*4)(r3)
+       stw     r11,_UC_GREGS+(PT_R11*4)(r3)
+       stw     r12,_UC_GREGS+(PT_R12*4)(r3)
+       stw     r13,_UC_GREGS+(PT_R13*4)(r3)
+       stw     r14,_UC_GREGS+(PT_R14*4)(r3)
+       stw     r15,_UC_GREGS+(PT_R15*4)(r3)
+       stw     r16,_UC_GREGS+(PT_R16*4)(r3)
+       stw     r17,_UC_GREGS+(PT_R17*4)(r3)
+       stw     r18,_UC_GREGS+(PT_R18*4)(r3)
+       stw     r19,_UC_GREGS+(PT_R19*4)(r3)
+       stw     r20,_UC_GREGS+(PT_R20*4)(r3)
+       stw     r21,_UC_GREGS+(PT_R21*4)(r3)
+       stw     r22,_UC_GREGS+(PT_R22*4)(r3)
+       stw     r23,_UC_GREGS+(PT_R23*4)(r3)
+       stw     r24,_UC_GREGS+(PT_R24*4)(r3)
+       stw     r25,_UC_GREGS+(PT_R25*4)(r3)
+       stw     r26,_UC_GREGS+(PT_R26*4)(r3)
+       stw     r27,_UC_GREGS+(PT_R27*4)(r3)
+       stw     r28,_UC_GREGS+(PT_R28*4)(r3)
+       stw     r29,_UC_GREGS+(PT_R29*4)(r3)
+       stw     r30,_UC_GREGS+(PT_R30*4)(r3)
+       mfctr   r0
+       stw     r0,_UC_GREGS+(PT_CTR*4)(r3)
+       mfxer   r0
+       stw     r0,_UC_GREGS+(PT_XER*4)(r3)
+       mfcr    r0
+       stw     r0,_UC_GREGS+(PT_CCR*4)(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
+       stw     r0,_UC_GREGS+(PT_R3*4)(r3)
+
+       /* Zero fill fields that can't be set in user state. */
+       stw     r0,_UC_GREGS+(PT_MSR*4)(r3)
+       stw     r0,_UC_GREGS+(PT_MQ*4)(r3)
+
+       /* Save the floating-point registers */
+       stfd    fp0,_UC_FREGS+(0*8)(r3)
+       stfd    fp1,_UC_FREGS+(1*8)(r3)
+       stfd    fp2,_UC_FREGS+(2*8)(r3)
+       stfd    fp3,_UC_FREGS+(3*8)(r3)
+       stfd    fp4,_UC_FREGS+(4*8)(r3)
+       stfd    fp5,_UC_FREGS+(5*8)(r3)
+       stfd    fp6,_UC_FREGS+(6*8)(r3)
+       stfd    fp7,_UC_FREGS+(7*8)(r3)
+       stfd    fp8,_UC_FREGS+(8*8)(r3)
+       stfd    fp9,_UC_FREGS+(9*8)(r3)
+       stfd    fp10,_UC_FREGS+(10*8)(r3)
+       stfd    fp11,_UC_FREGS+(11*8)(r3)
+       stfd    fp12,_UC_FREGS+(12*8)(r3)
+       stfd    fp13,_UC_FREGS+(13*8)(r3)
+       stfd    fp14,_UC_FREGS+(14*8)(r3)
+       stfd    fp15,_UC_FREGS+(15*8)(r3)
+       stfd    fp16,_UC_FREGS+(16*8)(r3)
+       stfd    fp17,_UC_FREGS+(17*8)(r3)
+       stfd    fp18,_UC_FREGS+(18*8)(r3)
+       stfd    fp19,_UC_FREGS+(19*8)(r3)
+       stfd    fp20,_UC_FREGS+(20*8)(r3)
+       stfd    fp21,_UC_FREGS+(21*8)(r3)
+       stfd    fp22,_UC_FREGS+(22*8)(r3)
+       stfd    fp23,_UC_FREGS+(23*8)(r3)
+       stfd    fp24,_UC_FREGS+(24*8)(r3)
+       stfd    fp25,_UC_FREGS+(25*8)(r3)
+       stfd    fp26,_UC_FREGS+(26*8)(r3)
+       stfd    fp27,_UC_FREGS+(27*8)(r3)
+       stfd    fp28,_UC_FREGS+(28*8)(r3)
+       stfd    fp29,_UC_FREGS+(29*8)(r3)
+       mffs    fp0
+       stfd    fp30,_UC_FREGS+(30*8)(r3)
+       stfd    fp31,_UC_FREGS+(31*8)(r3)
+       stfd    fp0,_UC_FREGS+(32*8)(r3)
+
+       addi    r5,r3,_UC_SIGMASK
+       addi    r4,r4,_UC_SIGMASK
+       li      r3,SIG_SETMASK
+       bl      JUMPTARGET(sigprocmask)
+       cmpwi   r3,0
+       bne     L(error_exit)
+
+       /*
+        * If the 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
+        * 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(do_sigret)
+
+       /* 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(error_exit):
+       lwz     r31,12(r1)
+       lwz     r0,20(r1)
+       addi    r1,r1,16
+       mtlr    r0
+       blr
+
+L(do_sigret):
+       addi    r1,r31,-0xd0
+       li      r0,SYS_ify(rt_sigreturn)
+       sc
+       /* NOTREACHED */
+
+PSEUDO_END(__swapcontext)
+
+weak_alias(__swapcontext, swapcontext)
diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/ucontext_i.h
new file mode 100644 (file)
index 0000000..e88a025
--- /dev/null
@@ -0,0 +1,30 @@
+/* Offsets and other constants needed in the *context() function
+   implementation.
+   Copyright (C) 2002 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., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#define SIG_BLOCK      0
+#define SIG_SETMASK    2
+
+#define _UC_LINK       4
+#define _UC_STACK_SP   8
+#define _UC_STACK_SIZE 16
+#define _UC_SIGMASK    64
+#define _UC_GREGS      192
+#define _UC_FREGS      384
+#define _UC_VREGS      656
index 0f7b19c70c5e7ce6a17bbc414ab521dff2c00761..9ce93c8197c7e1c664dd269ee86e1dafae4fbfdf 100644 (file)
    included in <signal.h>.  */
 #include <bits/sigcontext.h>
 
-/* A machine context is exactly a sigcontext.  */
+#if __WORDSIZE == 32
+
+/* Number of general registers.  */
+#define NGREG  48
+
+/* Container for all general registers.  */
+typedef unsigned long gregset_t[NGREG];
+
+/* Container for floating-point registers and status */
+typedef struct _libc_fpstate
+{
+       double fpregs[32];
+       double fpscr;
+       unsigned int _pad[2];
+} fpregset_t;
+
+/* Container for Altivec/VMX registers and status.
+   Needs to be aligned on a 16-byte boundary. */
+typedef struct _libc_vrstate
+{
+       unsigned int vrregs[32][4];
+       unsigned int vscr;
+       unsigned int vrsave;
+       unsigned int _pad[2];
+} vrregset_t;
+
+/* Context to describe whole processor state.  */
+typedef struct
+{
+       gregset_t gregs;
+       fpregset_t fpregs;
+       vrregset_t vrregs __attribute__((__aligned__(16)));
+} mcontext_t;
+
+#else
+
+/* For 64-bit, a machine context is exactly a sigcontext.  */
 typedef struct sigcontext mcontext_t;
 
+#endif
+
 /* Userlevel context.  */
 typedef struct ucontext
   {
@@ -36,12 +74,14 @@ typedef struct ucontext
     struct ucontext *uc_link;
     stack_t uc_stack;
 #if __WORDSIZE == 32
-    mcontext_t uc_mcontext;
-    __sigset_t uc_sigmask;
-#else
+    /* These fields are for backwards compatibility. */
+    int uc_pad[7];
+    mcontext_t *uc_regs;
+    unsigned int uc_oldsigmask[2];
+    int uc_pad2;
+#endif
     sigset_t    uc_sigmask;
     mcontext_t  uc_mcontext;  /* last for extensibility */
-#endif
   } ucontext_t;
 
 #endif /* sys/ucontext.h */