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).
This commit is contained in:
parent
9881f8de04
commit
251de2dee0
|
@ -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 @@ RCSID("$NetBSD: _setjmp.S,v 1.8 2008/04/28 20:22:57 martin Exp $")
|
|||
*/
|
||||
|
||||
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 @@ ENTRY(_longjmp)
|
|||
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
|
||||
|
|
|
@ -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 @@ void
|
|||
__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 @@ __longjmp14(jmp_buf env, int val)
|
|||
/* 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);
|
||||
|
|
|
@ -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 @@ ENTRY(__setjmp14)
|
|||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue