summaryrefslogtreecommitdiff
path: root/sys/arch/m68k
diff options
context:
space:
mode:
authorbriggs <briggs@cvs.openbsd.org>1996-10-13 16:10:05 +0000
committerbriggs <briggs@cvs.openbsd.org>1996-10-13 16:10:05 +0000
commitce2580af680fa2afa666183cf0d513af9f79b20d (patch)
treeb49b5a087ac1b5a13b2b5e0113b2defe0ce0e83e /sys/arch/m68k
parent98fbf78b776af38a4b050a83774ecd57d1cfee39 (diff)
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.
Diffstat (limited to 'sys/arch/m68k')
-rw-r--r--sys/arch/m68k/fpe/fpu_emulate.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/sys/arch/m68k/fpe/fpu_emulate.c b/sys/arch/m68k/fpe/fpu_emulate.c
index 472ec39e52d..5504d7e2d71 100644
--- a/sys/arch/m68k/fpe/fpu_emulate.c
+++ b/sys/arch/m68k/fpe/fpu_emulate.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: fpu_emulate.c,v 1.5 1996/09/18 02:09:29 briggs Exp $ */
-/* $NetBSD: fpu_emulate.c,v 1.6 1996/05/15 07:31:55 leo Exp $ */
+/* $OpenBSD: fpu_emulate.c,v 1.6 1996/10/13 16:10:04 briggs Exp $ */
+/* $NetBSD: fpu_emulate.c,v 1.10 1996/10/13 03:19:12 christos Exp $ */
/*
* Copyright (c) 1995 Gordon W. Ross
@@ -91,6 +91,7 @@ fpu_emulate(frame, fpf)
{
static struct instruction insn;
static struct fpemu fe;
+ u_int savedpc;
int word, optype, sig;
#ifdef DEBUG
@@ -119,6 +120,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
@@ -228,9 +245,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",
@@ -238,6 +254,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",
@@ -488,11 +506,10 @@ fpu_emul_fmovm(fe, insn)
}
while ((0 <= regnum) && (regnum < 8)) {
- if (w1_post_incr) {
+ if (w1_post_incr)
regmask = 0x80 >> regnum;
- } else {
+ else
regmask = 1 << regnum;
- }
if (regmask & reglist) {
if (fpu_to_mem) {
sig = fpu_store_ea(frame, insn, &insn->is_ea0,