diff options
author | briggs <briggs@cvs.openbsd.org> | 1996-10-13 16:10:05 +0000 |
---|---|---|
committer | briggs <briggs@cvs.openbsd.org> | 1996-10-13 16:10:05 +0000 |
commit | ce2580af680fa2afa666183cf0d513af9f79b20d (patch) | |
tree | b49b5a087ac1b5a13b2b5e0113b2defe0ce0e83e /sys/arch/m68k | |
parent | 98fbf78b776af38a4b050a83774ecd57d1cfee39 (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.c | 31 |
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, |