about summary refs log tree commit diff
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-12-09 23:47:06 +0000
committerUlrich Drepper <drepper@redhat.com>1997-12-09 23:47:06 +0000
commit3bfd87851af1166be6d1b5cf099b3709131de553 (patch)
tree766729b78feec65c20ac4aaac370d6129f193fe6
parentb9ccfd5db26124960fd8a483edcf2de9c8d849a7 (diff)
downloadglibc-3bfd87851af1166be6d1b5cf099b3709131de553.tar.gz
glibc-3bfd87851af1166be6d1b5cf099b3709131de553.tar.xz
glibc-3bfd87851af1166be6d1b5cf099b3709131de553.zip
Backport setjmp/longjmp rewrite.
-rw-r--r--sysdeps/alpha/Makefile6
-rw-r--r--sysdeps/alpha/__longjmp.c92
-rw-r--r--sysdeps/alpha/bsd-_setjmp.S37
-rw-r--r--sysdeps/alpha/bsd-setjmp.S37
-rw-r--r--sysdeps/alpha/jmp_buf.h107
-rw-r--r--sysdeps/alpha/setjmp.S68
-rw-r--r--sysdeps/alpha/setjmp_aux.c76
7 files changed, 126 insertions, 297 deletions
diff --git a/sysdeps/alpha/Makefile b/sysdeps/alpha/Makefile
index 5fe8e4ee7f..6cf4a173a6 100644
--- a/sysdeps/alpha/Makefile
+++ b/sysdeps/alpha/Makefile
@@ -21,10 +21,6 @@ ifeq ($(subdir),gmon)
 sysdep_routines += _mcount
 endif
 
-ifeq ($(subdir),setjmp)
-sysdep_routines += setjmp_aux
-endif
-
 ifeq ($(subdir),gnulib)
 sysdep_routines += $(divrem)
 endif
@@ -45,6 +41,6 @@ endif
 
 divrem := divl divq reml remq
 
-# For now, build everything with full IEEE math support. 
+# For now, build everything with full IEEE math support.
 # TODO: build separate libm and libm-ieee.
 sysdep-CFLAGS += -mieee
diff --git a/sysdeps/alpha/__longjmp.c b/sysdeps/alpha/__longjmp.c
deleted file mode 100644
index 65b6804bd3..0000000000
--- a/sysdeps/alpha/__longjmp.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (C) 1992, 1994 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-/* Global register vars must come before any function defn.  */
-
-register long int
-  r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"),
-  r13 asm ("$13"), r14 asm ("$14");
-
-register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26");
-
-#if 1				/* XXX */
-register double
-  f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"),
-  f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9");
-#endif
-
-#include <setjmp.h>
-
-
-/* Jump to the position specified by ENV, causing the
-   setjmp call there to return VAL, or 1 if VAL is 0.  */
-void
-__longjmp (__jmp_buf env, int val)
-{
-  register long int retval asm ("$0");
-
-  /* Restore the integer registers.  */
-  r9 = env[0].__9;
-  r10 = env[0].__10;
-  r11 = env[0].__11;
-  r12 = env[0].__12;
-  r13 = env[0].__13;
-  r14 = env[0].__14;
-
-#if 1				/* XXX */
-  /* Restore the floating point registers.  */
-  f2 = env[0].__f2;
-  f3 = env[0].__f3;
-  f4 = env[0].__f4;
-  f5 = env[0].__f5;
-  f6 = env[0].__f6;
-  f7 = env[0].__f7;
-  f8 = env[0].__f8;
-  f9 = env[0].__f9;
-#endif
-
-  /* Set the return PC to that of setjmp's caller.  */
-  retpc = env[0].__pc;
-
-  /* Restore the FP and SP of setjmp's caller.  */
-  fp = env[0].__fp;
-  sp = env[0].__sp;
-
-  /* Return VAL (or 1 if VAL is zero) to setjmp's caller.
-
-     We use an asm here rather than a normal C return statement
-     just in case the compiler wanted to do some stack frobnication
-     in the function epilogue.  Since we have already restored
-     precisely the FP and SP the desired environment needs,
-     we must avoid the compiler doing anything with the stack.  */
-
-
-  asm volatile
-    ("cmoveq %1, 1, %0\n\t"	/* $0 = val ?: 1; */
-     "ret $31, (%2), 1"	/* return $0 */
-     : "=r" (retval)
-     /* The "0" constraint should force VAL into $0.  */
-     : "0" (val), "r" (retpc));
-
-  while (1)
-    {
-      /* The loop is just to avoid `volatile function does return' warnings.
-	 The instruction will only be executed once.  */
-      asm volatile ("");
-    }
-}
diff --git a/sysdeps/alpha/bsd-_setjmp.S b/sysdeps/alpha/bsd-_setjmp.S
deleted file mode 100644
index 1bb3e4ab37..0000000000
--- a/sysdeps/alpha/bsd-_setjmp.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  Alpha version.
-   Copyright (C) 1994, 1996 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
-   We cannot do it in C because it must be a tail-call, so frame-unwinding
-   in setjmp doesn't clobber the state restored by longjmp.  */
-
-#include <sysdep.h>
-
-ENTRY(_setjmp)
-	ldgp	$29,0($27)
-#ifdef PROF
-	.set noat
-	lda	AT, _mcount
-	jsr	AT, (AT), _mcount
-	.set at
-#endif
-	.prologue 1
-	bis	$31, $31, $17		/* Pass a second argument of zero.  */
-	jmp	$31, __sigsetjmp	/* Call __sigsetjmp.  */
-	END(_setjmp)
diff --git a/sysdeps/alpha/bsd-setjmp.S b/sysdeps/alpha/bsd-setjmp.S
deleted file mode 100644
index cf5bf189de..0000000000
--- a/sysdeps/alpha/bsd-setjmp.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  Alpha version.
-   Copyright (C) 1994, 1996 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
-   We cannot do it in C because it must be a tail-call, so frame-unwinding
-   in setjmp doesn't clobber the state restored by longjmp.  */
-
-#include <sysdep.h>
-
-ENTRY(setjmp)
-	ldgp	$29, 0($27)
-#ifdef PROF
-	.set noat
-	lda	AT, _mcount
-	jsr	AT, (AT), _mcount
-	.set at
-#endif
-	.prologue 1
-	bis	$31, 1, $17		/* Pass a second argument of one.  */
-	jmp	$31, __sigsetjmp	/* Call __sigsetjmp.  */
-	END(setjmp)
diff --git a/sysdeps/alpha/jmp_buf.h b/sysdeps/alpha/jmp_buf.h
index 6e6f6b4727..48585b424b 100644
--- a/sysdeps/alpha/jmp_buf.h
+++ b/sysdeps/alpha/jmp_buf.h
@@ -1,46 +1,73 @@
 /* Define the machine-dependent type `jmp_buf'.  Alpha version.
-Copyright (C) 1992 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
+   Copyright (C) 1992, 1997 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 Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
+   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
+   Library General Public License for more details.
 
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
 
-typedef struct
-  {
-    /* Integer registers:
-           $0 is the return value;
-	   $1-$8, $22-$25, $28 are call-used;
-	   $9-$14 we save here;
-	   $15 is the FP and we save it here;
-	   $16-$21 are input arguments (call-used);
-	   $26 is the return PC and we save it here;
-	   $27 is the procedure value (i.e., the address of __setjmp);
-	   $29 is the global pointer, which the caller will reconstruct
-	   from the return address restored in $26;
-	   $30 is the stack pointer and we save it here;
-	   $31 is always zero.  */
-    long int __9, __10, __11, __12, __13, __14;
-    long int *__pc, *__fp, *__sp;
+/* The previous jmp_buf.h had __jmp_buf defined as a structure.
+   We use an array of 'long int' instead, to make writing the
+   assembler easier. Naturally, user code should not depend on
+   either representation. */
 
-#if 1				/* XXX need predefine for TARGET_FPREGS */
-    /* Floating-point registers:
-           $f0 is the floating return value;
-	   $f1, $f10-$f15, $f22-$f30 are call-used;
-	   $f2-$f9 we save here;
-	   $f16-$21 are input args (call-used);
-	   $f31 is always zero.  */
-    double __f2, __f3, __f4, __f5, __f6, __f7, __f8, __f9;
-#endif	/* Have FP regs.  */
-  } __jmp_buf[1];
+/*
+ * Integer registers:
+ *    $0 is the return value (va);
+ *    $1-$8, $22-$25, $28 are call-used (t0-t7, t8-t11, at);
+ *    $9-$14 we save here (s0-s5);
+ *    $15 is the FP and we save it here (fp or s6);
+ *    $16-$21 are input arguments (call-used) (a0-a5);
+ *    $26 is the return PC and we save it here (ra);
+ *    $27 is the procedure value (i.e., the address of __setjmp) (pv or t12);
+ *    $29 is the global pointer, which the caller will reconstruct
+ *        from the return address restored in $26 (gp);
+ *    $30 is the stack pointer and we save it here (sp);
+ *    $31 is always zero (zero).
+ *
+ * Floating-point registers:
+ *    $f0 is the floating return value;
+ *    $f1, $f10-$f15, $f22-$f30 are call-used;
+ *    $f2-$f9 we save here;
+ *    $f16-$21 are input args (call-used);
+ *    $f31 is always zero.
+ *
+ * Note that even on Alpha hardware that does not have an FPU (there
+ * isn't such a thing currently) it is required to implement the FP
+ * registers.
+ */
+
+#if defined __USE_MISC || defined __ASSEMBLY__
+# define JB_S0  0
+# define JB_S1  1
+# define JB_S2  2
+# define JB_S3  3
+# define JB_S4  4
+# define JB_S5  5
+# define JB_PC  6
+# define JB_FP  7
+# define JB_SP  8
+# define JB_F2  9
+# define JB_F3  10
+# define JB_F4  11
+# define JB_F5  12
+# define JB_F6  13
+# define JB_F7  14
+# define JB_F8  15
+# define JB_F9  16
+#endif
+
+#ifndef __ASSEMBLY__
+typedef long int __jmp_buf[17];
+#endif
diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S
index 4b2e147b15..f1a34d10b4 100644
--- a/sysdeps/alpha/setjmp.S
+++ b/sysdeps/alpha/setjmp.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1994, 1996, 1997 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
@@ -16,13 +16,21 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#define __ASSEMBLY__
+
 #include <sysdep.h>
+#include <jmp_buf.h>
+
+       .ent __sigsetjmp
+       .global __sigsetjmp
+__sigsetjmp:
+       ldgp    gp, 0(pv)
 
-/* The function __sigsetjmp_aux saves all the registers, but it can't
-   reliably access the stack or frame pointers, so we pass them in as
-   extra arguments.  */
-ENTRY (__sigsetjmp)
-	ldgp	$29, 0($27)
+$sigsetjmp_local:
+       subq    sp, 16, sp
+       .frame  sp, 16, ra, 0
+       stq     ra, 0(sp)
+       .mask   0x04000000, -16
 #ifdef PROF
 	.set noat
 	lda	AT, _mcount
@@ -31,8 +39,48 @@ ENTRY (__sigsetjmp)
 #endif
 	.prologue 1
 
-	bis	$30, $30, $18		/* Pass SP as 3rd arg.  */
-	bis	$15, $15, $19		/* Pass FP as 4th arg.  */
-	jmp	$31, __sigsetjmp_aux	/* Call __sigsetjmp_aux.  */
+	stq	s0, JB_S0*8(a0)
+	stq	s1, JB_S1*8(a0)
+	stq	s2, JB_S2*8(a0)
+	stq	s3, JB_S3*8(a0)
+	stq	s4, JB_S4*8(a0)
+	stq	s5, JB_S5*8(a0)
+	stq	ra, JB_PC*8(a0)
+	addq	sp, 16, t0
+	stq	fp, JB_FP*8(a0)
+	stq	t0, JB_SP*8(a0)
+	stt	$f2, JB_F2*8(a0)
+	stt	$f3, JB_F3*8(a0)
+	stt	$f4, JB_F4*8(a0)
+	stt	$f5, JB_F5*8(a0)
+	stt	$f6, JB_F6*8(a0)
+	stt	$f7, JB_F7*8(a0)
+	stt	$f8, JB_F8*8(a0)
+	stt	$f9, JB_F9*8(a0)
+
+	/* Call to C to (potentially) save our signal mask.  */
+	jsr	ra, __sigjmp_save
+
+	ldq	ra, 0(sp)
+	addq	sp, 16, sp
+	ret
+
+END(__sigsetjmp)
+
+/* Put these traditional entry points in the same file so that we can
+   elide much of the nonsense in trying to jmp to the real function.  */
+
+ENTRY(__setjmp)
+	ldgp	gp, 0(pv)
+	mov	0, a1
+	br	$sigsetjmp_local
+END(__setjmp)
+
+ENTRY(setjmp)
+	ldgp	gp, 0(pv)
+	mov	1, a1
+	br	$sigsetjmp_local
+END(setjmp)
 
-	END(__sigsetjmp)
+weak_alias(__setjmp, _setjmp)
+weak_extern(setjmp)
diff --git a/sysdeps/alpha/setjmp_aux.c b/sysdeps/alpha/setjmp_aux.c
deleted file mode 100644
index 0f05f8b043..0000000000
--- a/sysdeps/alpha/setjmp_aux.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (C) 1992, 1994 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 Library General Public License as
-published by the Free Software Foundation; either version 2 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-/* Global register decls must come before any function defn.  */
-
-register long int
-  r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"),
-  r13 asm ("$13"), r14 asm ("$14");
-
-register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26");
-
-#if 1				/* XXX */
-register double
-  f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"),
-  f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9");
-#endif
-
-
-#include <setjmp.h>
-
-
-/* Save the current program position in ENV and return 0.  */
-int
-__sigsetjmp_aux (sigjmp_buf env, int savemask, long int *sp, long int *fp)
-{
-  /* Save the integer registers.  */
-  env[0].__jmpbuf[0].__9 = r9;
-  env[0].__jmpbuf[0].__10 = r10;
-  env[0].__jmpbuf[0].__11 = r11;
-  env[0].__jmpbuf[0].__12 = r12;
-  env[0].__jmpbuf[0].__13 = r13;
-  env[0].__jmpbuf[0].__14 = r14;
-
-#if 1				/* XXX */
-  /* Save the floating point registers.  */
-  env[0].__jmpbuf[0].__f2 = f2;
-  env[0].__jmpbuf[0].__f3 = f3;
-  env[0].__jmpbuf[0].__f4 = f4;
-  env[0].__jmpbuf[0].__f5 = f5;
-  env[0].__jmpbuf[0].__f6 = f6;
-  env[0].__jmpbuf[0].__f7 = f7;
-  env[0].__jmpbuf[0].__f8 = f8;
-  env[0].__jmpbuf[0].__f9 = f9;
-#endif
-
-  /* Save the return address of our caller, where longjmp will jump to.  */
-  env[0].__jmpbuf[0].__pc = retpc;
-
-  /* Save the FP and SP of our caller.  The __sigsetjmp entry point
-     simply puts these in the argument registers for us to fetch.  */
-  env[0].__jmpbuf[0].__fp = fp;
-  env[0].__jmpbuf[0].__sp = sp;
-
-  /* Save the signal mask if requested.  */
-  __sigjmp_save (env, savemask);
-
-  retpc = env[0].__jmpbuf[0].__pc;	/* restore ra, ugly... */
-
-  /* Return to the original caller of __sigsetjmp.  */
-  return 0;
-}