Store the initial NPX control word appropriate for the emulation in the saved

FPU state, and use it when initializing the FPU on demand.
This commit is contained in:
mycroft 1998-01-24 13:19:46 +00:00
parent a9a7cc88d1
commit a963fe5864
11 changed files with 54 additions and 22 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: freebsd_machdep.c,v 1.15 1998/01/24 12:42:22 mycroft Exp $ */
/* $NetBSD: freebsd_machdep.c,v 1.16 1998/01/24 13:19:46 mycroft Exp $ */
/*-
* Copyright (c) 1993, 1994, 1995, 1996 Charles M. Hannum. All rights reserved.
@ -67,8 +67,10 @@ freebsd_setregs(p, epp, stack)
struct exec_package *epp;
u_long stack;
{
register struct pcb *pcb = &p->p_addr->u_pcb;
setregs(p, epp, stack);
pcb->pcb_savefpu.sv_env.en_cw = __FreeBSD_NPXCW__;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: ibcs2_machdep.c,v 1.3 1997/10/16 04:23:37 mycroft Exp $ */
/* $NetBSD: ibcs2_machdep.c,v 1.4 1998/01/24 13:19:47 mycroft Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -39,7 +39,9 @@
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/exec.h>
#include <sys/user.h>
#include <machine/npx.h>
#include <machine/reg.h>
#include <machine/vmparam.h>
#include <machine/ibcs2_machdep.h>
@ -50,9 +52,11 @@ ibcs2_setregs(p, epp, stack)
struct exec_package *epp;
u_long stack;
{
register struct pcb *pcb = &p->p_addr->u_pcb;
register struct trapframe *tf;
setregs(p, epp, stack);
pcb->pcb_savefpu.sv_env.en_cw = __iBCS2_NPXCW__;
tf = p->p_md.md_regs;
tf->tf_eax = 0x2000000; /* XXX base of heap */
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_machdep.c,v 1.38 1998/01/24 12:45:16 mycroft Exp $ */
/* $NetBSD: linux_machdep.c,v 1.39 1998/01/24 13:19:48 mycroft Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@ -55,6 +55,7 @@
#include <sys/device.h>
#include <sys/syscallargs.h>
#include <sys/filedesc.h>
#include <sys/exec_elf.h>
#include <compat/linux/linux_types.h>
#include <compat/linux/linux_signal.h>
@ -102,7 +103,9 @@ linux_setregs(p, epp, stack)
struct exec_package *epp;
u_long stack;
{
register struct pcb *pcb = &p->p_addr->u_pcb;
pcb->pcb_savefpu.sv_env.en_cw = __Linux_NPXCW__;
setregs(p, epp, stack);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: machdep.c,v 1.275 1998/01/23 00:44:06 mycroft Exp $ */
/* $NetBSD: machdep.c,v 1.276 1998/01/24 13:19:50 mycroft Exp $ */
/*-
* Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@ -1406,6 +1406,7 @@ setregs(p, pack, stack)
p->p_md.md_flags &= ~MDP_USEDFPU;
pcb->pcb_flags = 0;
pcb->pcb_savefpu.sv_env.en_cw = __NetBSD_NPXCW__;
tf = p->p_md.md_regs;
__asm("movl %w0,%%gs" : : "r" (LSEL(LUDATA_SEL, SEL_UPL)));

View File

@ -1,4 +1,4 @@
/* $NetBSD: math_emulate.c,v 1.19 1996/10/13 03:19:48 christos Exp $ */
/* $NetBSD: math_emulate.c,v 1.20 1998/01/24 13:19:53 mycroft Exp $ */
/*
* expediant "port" of linux 8087 emulator to 386BSD, with apologies -wfj
@ -72,7 +72,7 @@ int
math_emulate(info)
struct trapframe *info;
{
u_short code;
u_short cw, code;
temp_real tmp;
char * address;
u_long oldeip;
@ -82,8 +82,10 @@ math_emulate(info)
/* ever used fp? */
if ((curproc->p_md.md_flags & MDP_USEDFPU) == 0) {
curproc->p_md.md_flags |= MDP_USEDFPU;
cw = curproc->p_addr->u_pcb.pcb_savefpu.sv_env.en_cw;
fninit();
I387.cwd = cw;
curproc->p_md.md_flags |= MDP_USEDFPU;
}
if (I387.cwd & I387.swd & 0x3f)

View File

@ -1,4 +1,4 @@
/* $NetBSD: process_machdep.c,v 1.25 1998/01/24 12:11:15 mycroft Exp $ */
/* $NetBSD: process_machdep.c,v 1.26 1998/01/24 13:19:55 mycroft Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998
@ -157,9 +157,16 @@ process_read_fpregs(p, regs)
npxsave();
#endif
} else {
/* Fake a FNINIT. */
u_short cw;
/*
* Fake a FNINIT.
* The initial control word was already set by setregs(), so
* save it temporarily.
*/
cw = frame->sv_env.en_cw;
bzero(frame, sizeof(*frame));
frame->sv_env.en_cw = __INITIAL_NPXCW__;
frame->sv_env.en_cw = cw;
frame->sv_env.en_sw = 0;
frame->sv_env.en_tw = 0xffff;
p->p_md.md_flags |= MDP_USEDFPU;

View File

@ -1,4 +1,4 @@
/* $NetBSD: svr4_machdep.c,v 1.33 1998/01/24 12:45:19 mycroft Exp $ */
/* $NetBSD: svr4_machdep.c,v 1.34 1998/01/24 13:19:56 mycroft Exp $ */
/*
* Copyright (c) 1994 Christos Zoulas
@ -44,6 +44,7 @@
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/syscallargs.h>
#include <sys/exec_elf.h>
#include <compat/svr4/svr4_types.h>
#include <compat/svr4/svr4_ucontext.h>
@ -69,7 +70,9 @@ svr4_setregs(p, epp, stack)
struct exec_package *epp;
u_long stack;
{
register struct pcb *pcb = &p->p_addr->u_pcb;
pcb->pcb_savefpu.sv_env.en_cw = __SVR4_NPXCW__;
setregs(p, epp, stack);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: npx.h,v 1.11 1994/10/27 04:16:11 cgd Exp $ */
/* $NetBSD: npx.h,v 1.12 1998/01/24 13:19:57 mycroft Exp $ */
/*-
* Copyright (c) 1990 The Regents of the University of California.
@ -88,9 +88,14 @@ struct emcsts {
long em_dl; /* memory mapped D low register when swtched */
};
/* Intel prefers long real (53 bit) precision */
#define __iBCS_NPXCW__ 0x262
#define __INITIAL_NPXCW__ 0x037f
/* Intel prefers long real (53 bit) precision. */
#define __iBCS2_NPXCW__ 0x0262
/* NetBSD uses double precision with IEEE rounding and (lack of) exceptions. */
#define __NetBSD_NPXCW__ 0x127f
#define __FreeBSD_NPXCW__ 0x1272 /* XXX */
#define __Linux_NPXCW__ 0x037f /* XXX */
#define __SVR4_NPXCW__ 0x0262 /* XXX */
/*
* The standard control word from finit is 0x37F, giving:
@ -115,6 +120,4 @@ struct emcsts {
* trapping denormals.
*/
#define __INITIAL_NPXCW__ __NetBSD_NPXCW__
#endif /* !_I386_NPX_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: npx.c,v 1.62 1998/01/23 00:44:15 mycroft Exp $ */
/* $NetBSD: npx.c,v 1.63 1998/01/24 13:19:59 mycroft Exp $ */
#if 0
#define IPRINTF(x) printf x
@ -497,7 +497,7 @@ int
npxdna(p)
struct proc *p;
{
static u_short control = __INITIAL_NPXCW__;
u_short cw;
if (npx_type == NPX_NONE) {
IPRINTF(("Emul"));
@ -513,8 +513,8 @@ npxdna(p)
clts();
if ((p->p_md.md_flags & MDP_USEDFPU) == 0) {
p->p_md.md_flags |= MDP_USEDFPU;
IPRINTF(("Init"));
cw = p->p_addr->u_pcb.pcb_savefpu.sv_env.en_cw;
if (npxproc != 0 && npxproc != p)
npxsave1();
else {
@ -524,7 +524,8 @@ npxdna(p)
npx_nointr = 0;
}
npxproc = p;
fldcw(&control);
fldcw(&cw);
p->p_md.md_flags |= MDP_USEDFPU;
} else {
if (npxproc != 0) {
#ifdef DIAGNOSTIC

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_machdep.c,v 1.38 1998/01/24 12:45:16 mycroft Exp $ */
/* $NetBSD: linux_machdep.c,v 1.39 1998/01/24 13:19:48 mycroft Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@ -55,6 +55,7 @@
#include <sys/device.h>
#include <sys/syscallargs.h>
#include <sys/filedesc.h>
#include <sys/exec_elf.h>
#include <compat/linux/linux_types.h>
#include <compat/linux/linux_signal.h>
@ -102,7 +103,9 @@ linux_setregs(p, epp, stack)
struct exec_package *epp;
u_long stack;
{
register struct pcb *pcb = &p->p_addr->u_pcb;
pcb->pcb_savefpu.sv_env.en_cw = __Linux_NPXCW__;
setregs(p, epp, stack);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: linux_machdep.c,v 1.38 1998/01/24 12:45:16 mycroft Exp $ */
/* $NetBSD: linux_machdep.c,v 1.39 1998/01/24 13:19:48 mycroft Exp $ */
/*
* Copyright (c) 1995 Frank van der Linden
@ -55,6 +55,7 @@
#include <sys/device.h>
#include <sys/syscallargs.h>
#include <sys/filedesc.h>
#include <sys/exec_elf.h>
#include <compat/linux/linux_types.h>
#include <compat/linux/linux_signal.h>
@ -102,7 +103,9 @@ linux_setregs(p, epp, stack)
struct exec_package *epp;
u_long stack;
{
register struct pcb *pcb = &p->p_addr->u_pcb;
pcb->pcb_savefpu.sv_env.en_cw = __Linux_NPXCW__;
setregs(p, epp, stack);
}