The 68LC040 generates a format 4 stack frame for floating point

exceptions, which puts the address of the instruction we faulted
on in a different location.  Copy it and handle as we normally would,
restoring the saved PC before returning.

The FPE should probably be reworked to take advantage of the 68LC040's
precalculated effective address, at some point.
This commit is contained in:
scottr 1996-10-07 03:16:47 +00:00
parent 45c47f41aa
commit f8b0c86aa8

View File

@ -1,4 +1,4 @@
/* $NetBSD: fpu_emulate.c,v 1.7 1996/10/04 18:07:24 scottr Exp $ */
/* $NetBSD: fpu_emulate.c,v 1.8 1996/10/07 03:16:47 scottr Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
@ -90,6 +90,7 @@ fpu_emulate(frame, fpf)
{
static struct instruction insn;
static struct fpemu fe;
u_int savedpc;
int word, optype, sig;
#ifdef DEBUG
@ -118,6 +119,22 @@ fpu_emulate(frame, fpf)
printf("ENTERING fpu_emulate: FPSR=%08x, FPCR=%08x\n",
fe.fe_fpsr, fe.fe_fpcr);
}
if (frame->f_format == 4) {
/*
* A format 4 is generated by the 68{EC,LC}040. The PC is
* already set to the instruction following the faulting
* instruction. We need to calculate that, anyway. The
* fslw is the PC of the faulted instruction, which is what
* we expect to be in f_pc.
*
* XXX - This is a hack; it assumes we at least know the
* sizes of all instructions we run across. This may not
* be true, so we save the PC in order to restore it later.
*/
savedpc = frame->f_pc;
frame->f_pc = frame->f_fmt4.f_fslw;
}
word = fusword((void *) (frame->f_pc));
if (word < 0) {
#ifdef DEBUG
@ -227,9 +244,8 @@ fpu_emulate(frame, fpf)
DUMP_INSN(&insn);
if (sig == 0) {
if (sig == 0)
frame->f_pc += insn.is_advance;
}
#if defined(DDB) && defined(DEBUG)
else {
printf(" fpu_emulate: sig=%d, opcode=%x, word1=%x\n",
@ -237,6 +253,8 @@ fpu_emulate(frame, fpf)
kdb_trap(-1, frame);
}
#endif
if (frame->f_format == 4)
frame->f_pc = savedpc; /* XXX Restore PC -- 68{EC,LC}040 only */
if (fpu_debug_level & DL_VERBOSE)
printf("EXITING fpu_emulate: w/FPSR=%08x, FPCR=%08x\n",