diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2007-12-02 21:32:11 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2007-12-02 21:32:11 +0000 |
commit | aa81363682f39400f414c12a78466aa24c22562b (patch) | |
tree | ebb971be06b8859ef478f7a36ea93293ad887d55 /sys/arch/m88k | |
parent | 96d082fd0961b307d5402aec571fa59a275fde93 (diff) |
The beginning of a real floating-point exception handler for the 88110. The
existing code to enable TCFP was broken, as it was not setting the TCFP bit
in the right register.
So far, the exception handler will deliver SIGFPE in all cases. It will
eventually do the necessary rounding, and handle the odd-numbered register
pair operation, as I get time to write this (or see how much can be lifted
from the 88100 floating-point exception code).
Diffstat (limited to 'sys/arch/m88k')
-rw-r--r-- | sys/arch/m88k/m88k/eh_common.S | 9 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/m88110_fp.S | 309 | ||||
-rw-r--r-- | sys/arch/m88k/m88k/vectors_88110.S | 4 |
3 files changed, 227 insertions, 95 deletions
diff --git a/sys/arch/m88k/m88k/eh_common.S b/sys/arch/m88k/m88k/eh_common.S index 468cfc1a301..9d8ba04cc6b 100644 --- a/sys/arch/m88k/m88k/eh_common.S +++ b/sys/arch/m88k/m88k/eh_common.S @@ -1,4 +1,4 @@ -/* $OpenBSD: eh_common.S,v 1.40 2007/12/02 21:28:40 miod Exp $ */ +/* $OpenBSD: eh_common.S,v 1.41 2007/12/02 21:32:08 miod Exp $ */ /* * Mach Operating System * Copyright (c) 1993-1991 Carnegie Mellon University @@ -1593,10 +1593,9 @@ GLOBAL(m88110_overflow_handler) XCALL(_C_LABEL(m88110_trap), _ASM_LABEL(check_ast)) /* Floating-point precise handler */ -GLOBAL(m88110_fp_precise_handler) - PREP88110("FPU precise", 114,) - or r3, r0, r30 - XCALL(_ASM_LABEL(m88110_Xfp_precise), _ASM_LABEL(check_ast)) +GLOBAL(m88110_fpu_handler) + PREP88110("FPU", 114,) + XCALL(_ASM_LABEL(m88110_fpu_exception), _ASM_LABEL(check_ast)) /* MVME197 non-maskable interrupt handler (ABORT button) */ GLOBAL(m88110_nonmaskable) diff --git a/sys/arch/m88k/m88k/m88110_fp.S b/sys/arch/m88k/m88k/m88110_fp.S index 9b296235ea1..430a74d28a2 100644 --- a/sys/arch/m88k/m88k/m88110_fp.S +++ b/sys/arch/m88k/m88k/m88110_fp.S @@ -1,106 +1,239 @@ -/* $OpenBSD: m88110_fp.S,v 1.2 2004/08/09 20:52:11 miod Exp $ */ +/* $OpenBSD: m88110_fp.S,v 1.3 2007/12/02 21:32:08 miod Exp $ */ + /* - * Copyright (c) 1999 Steve Murphree, Jr. - * All rights reserved. + * Copyright (c) 2007, Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice, this permission notice, and the disclaimer below + * appear in all copies. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christopher G. Demetriou. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "assym.h" + +#include <machine/asm.h> +#include <machine/trap.h> + +/* FPECR bits */ +#define FIOV_BIT 7 +#define FUNIMP_BIT 6 +#define FPRV_BIT 5 +#define FROP_BIT 4 +#define FDVZ_BIT 3 +#define FUNF_BIT 2 +#define FOVF_BIT 1 +#define FINX_BIT 0 + +/* FPSR and FPCR exception bits */ +#define EFINV_BIT 4 +#define EFDVZ_BIT 3 +#define EFUNF_BIT 2 +#define EFOVF_BIT 1 +#define EFINX_BIT 0 + +ASENTRY(m88110_fpu_exception) + /* + * On entry, r30 point to the exception frame. + * Save our guts so that we can call other functions. + */ + subu r31, r31, 16 + st r1, r31, 0 + st r30, r31, 4 + + /* + * We never saved the floating point exception and control + * registers. Do it now, and then decide what kind of exception + * we've got. + * Note that we can access the control registers even if the + * FPU is disabled. + */ + fldcr r2, FPECR + fldcr r3, FPSR + fldcr r4, FPCR + st r2, r30, EF_FPECR * 4 + st r3, r30, EF_FPSR * 4 + st r4, r30, EF_FPCR * 4 + + /* + * Check for floating point unimplemented bit first, as other + * bits are undefined if this bit is set. + */ + bb1 FUNIMP_BIT, r2, _ASM_LABEL(m88110_funimp) + + /* + * Check for the other exceptions. + * + * FOVF and FUNF need to be checked before FINX. + */ + bb1 FIOV_BIT, r2, _ASM_LABEL(m88110_fiov) + bb1 FPRV_BIT, r2, _ASM_LABEL(m88110_fprv) + bb1 FROP_BIT, r2, _ASM_LABEL(m88110_frop) + bb1 FDVZ_BIT, r2, _ASM_LABEL(m88110_fdvz) + bb1 FUNF_BIT, r2, _ASM_LABEL(m88110_funf) + bb1 FOVF_BIT, r2, _ASM_LABEL(m88110_fovf) + bb1 FINX_BIT, r2, _ASM_LABEL(m88110_finx) + + /* + * If control goes here, we got a floating point exception, + * but no cause bit is set. This shouldn't happen; if it does, + * just fall through the unimplemented instruction code. + */ + +ASLOCAL(m88110_funimp) + /* + * Check if the fpu was enabled. + */ + ld r5, r30, EF_EPSR * 4 + /* FPE_FLTINV */ + bb1 PSR_FPU_DISABLE_BIT, r5, _ASM_LABEL(m88110_fpeflt) + + /* + * We should check the faulting instruction here. + * This can be: + * - fsqrt (unimplemented) + * - any valid fp instruction operating on an odd register pair + * - any bogus fp instruction. + */ + + /* XXX TBD */ + + br _ASM_LABEL(m88110_fpeflt) + +/* + * Floating-point integer overflow. * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * Register it in the status register, and if this exception is allowed + * in the control register, send a trap. */ +ASLOCAL(m88110_fiov) + set r3, r3, 1<EFINV_BIT> + fstcr r3, FPSR + + /* FPE_FLTSUB */ + bb1 EFINV_BIT, r4, _ASM_LABEL(m88110_fpeflt) + + jmp.n r1 + addu r31, r31, 16 -/* Floating point trouble routines */ /* - * August 1, 1999 - * smurph@OpenBSD.org + * Floating-point privilege violation. * - * Additions to support MVME197 (mc88110) mmu routines. + * This exception is caused by fldcr, fstcr or fxcr with either a + * non-existing register (fcr1-fcr61), or fcr0 from userland. + */ +ASLOCAL(m88110_fprv) + /* ILL_PRVREG */ + or r2, r0, T_PRIVINFLT + bsr.n _C_LABEL(m88110_trap) + or r3, r0, r30 + + ld r1, r31, 0 + jmp.n r1 + addu r31, r31, 16 + +/* + * Floating-point reserved operand. */ +ASLOCAL(m88110_frop) + set r3, r3, 1<EFINV_BIT> + fstcr r3, FPSR + + /* XXX TBD lots of analysis to do here... */ + + /* FPE_FLTINV */ + bb1 EFINV_BIT, r4, _ASM_LABEL(m88110_fpeflt) + + /* XXX TBD ... and then decide on a value... */ + + jmp.n r1 + addu r31, r31, 16 /* - * This is cheesy. I'm using the TCFP features of the mc88110 - * because it was easy. It is not 100% IEEE. But it may be - * close enough. We shall see... XXXsmurph - * Err... TCFP == "Time Critical Floating Point" + * Floating-point divide by zero. * - * The only two SFU1 exceptions that can occure in TCFP mode are: - * 1) Unimplemented Floating Point Instruction - * 2) Floating Point Privilege Violation + * Register it in the status register, and if this exception is allowed + * in the control register, send a trap. */ +ASLOCAL(m88110_fdvz) + set r3, r3, 1<EFDVZ_BIT> + fstcr r3, FPSR -#include "assym.h" -#include <machine/trap.h> -#include <machine/asm.h> + /* FPE_INTDIV */ + bb1 EFDVZ_BIT, r4, _ASM_LABEL(m88110_fpeflt) -ASENTRY(m88110_Xfp_precise) - or r29, r3, r0 /* r29 is now the E.F. */ - subu r31, r31, 16 - st r1, r31, 0 - st r29, r31, 4 + jmp.n r1 + addu r31, r31, 16 - ld r2, r29, EF_FPSR * 4 - ld r3, r29, EF_FPCR * 4 - ld r4, r29, EF_FPECR * 4 +/* + * Floating-point underflow. + */ +ASLOCAL(m88110_funf) + set r3, r3, 1<EFUNF_BIT> + set r3, r3, 1<EFINX_BIT> + fstcr r3, FPSR - /* - * Load into r1 the return address for the 0 handlers. Looking - * at FPECR, branch to the appropriate 0 handler. However, - * if none of the 0 bits are enabled, then a floating point - * instruction was issued with the floating point unit disabled. This - * will cause an unimplemented opcode 0. - */ + /* FPE_FLTUND */ + bb1 EFUNF_BIT, r4, _ASM_LABEL(m88110_fpeflt) + + /* FPE_FLTRES */ + bb1 EFINX_BIT, r4, _ASM_LABEL(m88110_fpeflt) + + /* XXX TBD check rounding mode, check destination register, write + default value to it/them. */ + + jmp.n r1 + addu r31, r31, 16 + + +/* + * Floating-point overflow. + */ +ASLOCAL(m88110_fovf) + set r3, r3, 1<EFOVF_BIT> + set r3, r3, 1<EFINX_BIT> + fstcr r3, FPSR + + /* FPE_FLTOVF */ + bb1 EFOVF_BIT, r4, _ASM_LABEL(m88110_fpeflt) + + /* FPE_FLTRES */ + bb1 EFINX_BIT, r4, _ASM_LABEL(m88110_fpeflt) + + /* XXX TBD check rounding mode, check destination register, write + default value to it/them. */ + + jmp.n r1 + addu r31, r31, 16 + +/* + * Floating-point inexact. + * + * Register it in the status register, and if this exception is allowed + * in the control register, send a trap. + */ +ASLOCAL(m88110_finx) + set r3, r3, 1<EFINX_BIT> + fstcr r3, FPSR + + /* FPE_FLTRES */ + bb1 EFINX_BIT, r4, _ASM_LABEL(m88110_fpeflt) + + jmp.n r1 + addu r31, r31, 16 + +ASLOCAL(m88110_fpeflt) + or r2, r0, T_FPEPFLT + bsr.n _C_LABEL(m88110_trap) + or r3, r0, r30 - bb0 6,r4, 2f /* branch to m88110_FPunimp if bit set */ - br _ASM_LABEL(m88110_FPuimp) -2: bb0 5,r4, 3f /* branch to m88110_FPpriviol if bit set */ - br _ASM_LABEL(m88110_FPpriviol) -3: - or.u r4, r4, 0xffff - -ASLOCAL(m88110_FPuimp) - subu r31,r31,16 /* allocate stack */ - st r1,r31,4 /* save return address */ - st r3,r31,0 /* save exception frame */ - or r2,r0,T_FPEPFLT /* load trap type */ - bsr.n _C_LABEL(m88110_trap) /* trap */ - or r3, r29, r0 - ld r1,r31,4 /* recover return address */ - jmp.n r1 - addu r31,r31,16 /* deallocate stack */ - -ASLOCAL(m88110_FPpriviol) - subu r31,r31,16 /* allocate stack */ - st r1,r31,4 /* save return address */ - st r3,r31,0 /* save exception frame */ - or r2,r0,T_PRIVINFLT /* load trap type */ - bsr.n _C_LABEL(m88110_trap) /* trap */ - or r3, r29, r0 - ld r1,r31,4 /* recover return address */ - jmp.n r1 - addu r31,r31,16 /* deallocate stack */ - -ENTRY(set_tcfp) - or.u r2, r0, hi16(0x200000) - or r2, r2, lo16(0x200000) + ld r1, r31, 0 jmp.n r1 - fstcr r2, fcr0 + addu r31, r31, 16 diff --git a/sys/arch/m88k/m88k/vectors_88110.S b/sys/arch/m88k/m88k/vectors_88110.S index b79e7d99699..de912a5ce40 100644 --- a/sys/arch/m88k/m88k/vectors_88110.S +++ b/sys/arch/m88k/m88k/vectors_88110.S @@ -1,4 +1,4 @@ -/* $OpenBSD: vectors_88110.S,v 1.4 2006/05/15 05:34:57 miod Exp $ */ +/* $OpenBSD: vectors_88110.S,v 1.5 2007/12/02 21:32:08 miod Exp $ */ /* * Mach Operating System * Copyright (c) 1991, 1992 Carnegie Mellon University @@ -64,7 +64,7 @@ GLOBAL(m88110_vector_list) UNKNOWN16 /* 6x */ VECTOR(m88110_unknown_handler) /* 70 */ VECTOR(m88110_unknown_handler) /* 71 */ - VECTOR(m88110_fp_precise_handler) /* 72 */ + VECTOR(m88110_fpu_handler) /* 72 */ VECTOR(m88110_unknown_handler) /* 73 */ VECTOR(m88110_unimplemented_handler) /* 74 */ VECTOR(m88110_unknown_handler) /* 75 */ |