summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbriggs <briggs@openbsd.org>1996-10-13 16:10:04 +0000
committerbriggs <briggs@openbsd.org>1996-10-13 16:10:04 +0000
commit72c5b1e71d98ed72c38b1b514db79b49bb676141 (patch)
tree293f7107910d6d36aafaae91dd3c0e6401423f96
parent* Fix from Bill Studenmund <wrstuden@loki.stanford.edu> for transmission (diff)
downloadwireguard-openbsd-72c5b1e71d98ed72c38b1b514db79b49bb676141.tar.xz
wireguard-openbsd-72c5b1e71d98ed72c38b1b514db79b49bb676141.zip
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.
-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,