Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/arch/sparc/gen Save a few global registers during s...



details:   https://anonhg.NetBSD.org/src/rev/554699ab4925
branches:  trunk
changeset: 764684:554699ab4925
user:      martin <martin%NetBSD.org@localhost>
date:      Sat Apr 30 23:41:12 2011 +0000

description:
Save a few global registers during set/longjmp - at least the application
registers and the only currently used system register (%g7).
Sparc now passes the setjmp tests (and should be able to build perl again).

diffstat:

 lib/libc/arch/sparc/gen/_setjmp.S |  16 ++++++++++++++--
 lib/libc/arch/sparc/gen/longjmp.c |  29 +++++++++++++++++++++++++----
 lib/libc/arch/sparc/gen/setjmp.S  |  10 ++++++----
 3 files changed, 45 insertions(+), 10 deletions(-)

diffs (145 lines):

diff -r 30ab083892c3 -r 554699ab4925 lib/libc/arch/sparc/gen/_setjmp.S
--- a/lib/libc/arch/sparc/gen/_setjmp.S Sat Apr 30 23:39:08 2011 +0000
+++ b/lib/libc/arch/sparc/gen/_setjmp.S Sat Apr 30 23:41:12 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: _setjmp.S,v 1.8 2008/04/28 20:22:57 martin Exp $       */
+/*     $NetBSD: _setjmp.S,v 1.9 2011/04/30 23:41:12 martin Exp $       */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #include <machine/trap.h>
 
 #if defined(LIBC_SCCS) && !defined(lint)
-RCSID("$NetBSD: _setjmp.S,v 1.8 2008/04/28 20:22:57 martin Exp $")
+RCSID("$NetBSD: _setjmp.S,v 1.9 2011/04/30 23:41:12 martin Exp $")
 #endif /* LIBC_SCCS and not lint */
 
 /*
@@ -47,6 +47,12 @@
  */
 
 ENTRY(_setjmp)
+       /* store important globals, sigsetjmp compatible */
+       st      %g3, [%o0 + 16]
+       st      %g2, [%o0 + 24]
+       st      %g4, [%o0 + 48]
+       st      %g7, [%o0 + 52]
+
        st      %sp, [%o0+0]    /* store caller's stack pointer */
        st      %o7, [%o0+4]    /* and the return pc */
        retl
@@ -60,6 +66,12 @@
 0:
        t       ST_FLUSHWIN     ! flush register windows out to the stack
 
+       /* restore globals */
+       ld      [%o0 + 16], %g3
+       ld      [%o0 + 24], %g2
+       ld      [%o0 + 48], %g4
+       ld      [%o0 + 52], %g7
+
        /*
         * We restore the saved stack pointer to %fp, then issue
         * a `restore' instruction which will reload the register
diff -r 30ab083892c3 -r 554699ab4925 lib/libc/arch/sparc/gen/longjmp.c
--- a/lib/libc/arch/sparc/gen/longjmp.c Sat Apr 30 23:39:08 2011 +0000
+++ b/lib/libc/arch/sparc/gen/longjmp.c Sat Apr 30 23:41:12 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: longjmp.c,v 1.2 2008/04/28 20:22:57 martin Exp $       */
+/*     $NetBSD: longjmp.c,v 1.3 2011/04/30 23:41:12 martin Exp $       */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -35,11 +35,27 @@
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stddef.h>
 
 #define __LIBC12_SOURCE__
 #include <setjmp.h>
 #include <compat/include/setjmp.h>
 
+struct __jmp_buf_regs_t {
+       __greg_t        g4;
+       __greg_t        g7;
+       __greg_t        save_mask;
+};
+
+/*
+ * setjmp.S uses hard coded offsets into the jump_buf,
+ * make sure any changes cause a compile failure here
+ */
+__CTASSERT(56 == offsetof(struct __jmp_buf_regs_t,save_mask) +
+       sizeof(struct sigcontext));
+__CTASSERT(sizeof(sigjmp_buf) >= sizeof(struct __jmp_buf_regs_t) +
+       sizeof(struct sigcontext));
+
 /*
  * Use setcontext to reload the stack pointer, program counter <pc,npc>, and
  * set the return value in %o0.  The %i and %l registers will be reloaded
@@ -49,14 +65,15 @@
 __longjmp14(jmp_buf env, int val)
 {
        struct sigcontext *sc = (void *)env;
+       struct __jmp_buf_regs_t *r = (void*)&sc[1];
        ucontext_t uc;
 
        /* Ensure non-zero SP */
        if (sc->sc_sp == 0)
                goto err;
 
-       /* Initialise the fields we're going to use */
-       uc.uc_link = 0;
+       /* Initialise the context */
+       memset(&uc, 0, sizeof(uc));
 
        /*
         * Set _UC_{SET,CLR}STACK according to SS_ONSTACK.
@@ -71,8 +88,12 @@
        /* Extract PSR, PC, NPC and SP from jmp_buf */
        uc.uc_mcontext.__gregs[_REG_PSR] = sc->sc_psr;
        uc.uc_mcontext.__gregs[_REG_PC] = sc->sc_pc;
-       uc.uc_mcontext.__gregs[_REG_nPC] = sc->sc_npc;
+       uc.uc_mcontext.__gregs[_REG_nPC] = sc->sc_pc+4;
        uc.uc_mcontext.__gregs[_REG_O6] = sc->sc_sp;
+       uc.uc_mcontext.__gregs[_REG_G2] = sc->sc_g1;
+       uc.uc_mcontext.__gregs[_REG_G3] = sc->sc_npc;
+       uc.uc_mcontext.__gregs[_REG_G4] = r->g4;
+       uc.uc_mcontext.__gregs[_REG_G7] = r->g7;
 
        /* Set the return value; make sure it's non-zero */
        uc.uc_mcontext.__gregs[_REG_O0] = (val != 0 ? val : 1);
diff -r 30ab083892c3 -r 554699ab4925 lib/libc/arch/sparc/gen/setjmp.S
--- a/lib/libc/arch/sparc/gen/setjmp.S  Sat Apr 30 23:39:08 2011 +0000
+++ b/lib/libc/arch/sparc/gen/setjmp.S  Sat Apr 30 23:41:12 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: setjmp.S,v 1.11 2007/10/08 13:06:00 uwe Exp $  */
+/*     $NetBSD: setjmp.S,v 1.12 2011/04/30 23:41:13 martin Exp $       */
 
 /*
  * Copyright (c) 1992, 1993
@@ -40,7 +40,7 @@
 #if 0
        .asciz "@(#)setjmp.s    8.1 (Berkeley) 6/4/93"
 #else
-       RCSID("$NetBSD: setjmp.S,v 1.11 2007/10/08 13:06:00 uwe Exp $")
+       RCSID("$NetBSD: setjmp.S,v 1.12 2011/04/30 23:41:13 martin Exp $")
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -78,9 +78,11 @@
        st      %fp, [%i0 + 8]  /* sc.sc_sp = (caller's) sp */
        add     %i7, 8, %o0
        st      %o0, [%i0 + 12] /* sc.sc_pc = return_pc */
-       add     %i7, 12, %o0
-       st      %o0, [%i0 + 16] /* sc.sc_npc = return_pc + 4 */
+       st      %g3, [%i0 + 16] /* sc.sc_npc */
        st      %g0, [%i0 + 20] /* sc.sc_psr = (clean psr) */
+       st      %g2, [%i0 + 24]
+       st      %g4, [%i0 + 48]
+       st      %g7, [%i0 + 52]
        ret                     /* return 0 */
         restore        %g0, %g0, %o0
 



Home | Main Index | Thread Index | Old Index