summaryrefslogtreecommitdiff
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)
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;
-}