summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2013-03-25 19:08:57 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2013-03-25 19:08:57 +0000
commit6c1e632ba5b6c594fb8792d8739d841d7b320ca3 (patch)
treec9bbd86f58228e8f631c33cea3637112244cfd6d
parent2a5c5d0d6c30acc8f4c48a4f4c6300ad2397e8bd (diff)
Remove the m68k FPU emulator; it was only used by the mac68k port which has been
lying in the Attic for quite awhile; none of the remaining m68k-based ports support FPU-less systems; assuming my HP332 cpu board is in working condition, give me memory boards for it to have at least 8MB and a chassis, and I'll consider bringing this code back. But then, the 332 has an FPU socket, and I'd rather write a new glue to use the MI softloat code (bug-free) than try and fix the bugs in this.
-rw-r--r--sys/arch/m68k/fpe/README155
-rw-r--r--sys/arch/m68k/fpe/files.fpe22
-rw-r--r--sys/arch/m68k/fpe/fpu_add.c205
-rw-r--r--sys/arch/m68k/fpe/fpu_arith.h171
-rw-r--r--sys/arch/m68k/fpe/fpu_arith_proto.h74
-rw-r--r--sys/arch/m68k/fpe/fpu_calcea.c767
-rw-r--r--sys/arch/m68k/fpe/fpu_div.c263
-rw-r--r--sys/arch/m68k/fpe/fpu_emulate.c1166
-rw-r--r--sys/arch/m68k/fpe/fpu_emulate.h319
-rw-r--r--sys/arch/m68k/fpe/fpu_explode.c280
-rw-r--r--sys/arch/m68k/fpe/fpu_fmovecr.c119
-rw-r--r--sys/arch/m68k/fpe/fpu_fscale.c333
-rw-r--r--sys/arch/m68k/fpe/fpu_fstore.c132
-rw-r--r--sys/arch/m68k/fpe/fpu_getexp.c77
-rw-r--r--sys/arch/m68k/fpe/fpu_implode.c488
-rw-r--r--sys/arch/m68k/fpe/fpu_int.c124
-rw-r--r--sys/arch/m68k/fpe/fpu_log.c602
-rw-r--r--sys/arch/m68k/fpe/fpu_mul.c212
-rw-r--r--sys/arch/m68k/fpe/fpu_rem.c232
-rw-r--r--sys/arch/m68k/fpe/fpu_sqrt.c360
-rw-r--r--sys/arch/m68k/fpe/fpu_subr.c209
21 files changed, 0 insertions, 6310 deletions
diff --git a/sys/arch/m68k/fpe/README b/sys/arch/m68k/fpe/README
deleted file mode 100644
index ba738da39e4..00000000000
--- a/sys/arch/m68k/fpe/README
+++ /dev/null
@@ -1,155 +0,0 @@
-# $OpenBSD: README,v 1.4 2007/11/25 16:40:04 jmc Exp $
-* $NetBSD: README,v 1.4 1995/11/05 04:23:00 briggs Exp $
-* NetBSD/m68k FPE (floating point emulation) README file
-* Created Oct/??/95 by kenn@remus.rutgers.edu (Ken Nakata)
-* Last updated Nov/04/95 by kenn
-
-1. INSTALLATION AND COMPILATION
-
-To compile a kernel with FPE built-in, do the following:
-
-1) Add a line "options FPU_EMULATE" to your config file. If you are
-going to use the resulted kernel on a machine with an FPU for
-debugging purpose, add "options DEBUG_WITH_FPU" as well.
-
-2) Follow the usual procedure to build a new kernel.
-
-NOTE: If you add "options DEBUG_WITH_FPU", FPE will accept cpID=6 as
-emulated FPU. You will need a modified gas that generates cpID=6 for
-floating point instructions, instead of normal cpID=1. Apply the
-following patch to the gas source:
-
-*** /usr/src/gnu/usr.bin/gas/config/tc-m68k.c Mon Nov 21 16:30:41 1994
---- gas/config/tc-m68k.c Fri Sep 29 07:59:06 1995
-***************
-*** 1275,1281 ****
- /* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
- memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
- the_ins.operands[0].mode=MSCR;
-! the_ins.operands[0].reg=COPNUM; /* COP #1 */
- opsfound++;
- }
-
---- 1275,1281 ----
- /* memcpy((char *)(&the_ins.operands[1]), (char *)(&the_ins.operands[0]), opsfound*sizeof(the_ins.operands[0])); */
- memset((char *)(&the_ins.operands[0]), '\0', sizeof(the_ins.operands[0]));
- the_ins.operands[0].mode=MSCR;
-! the_ins.operands[0].reg=COP5; /* COP #6 */
- opsfound++;
- }
-
-
-Also, with the DEBUG_WITH_FPU option, you will be able to run only ONE
-process that uses FPE at once to get correct results.
-
-
-2. MISSING PARTS
-
-For missing instructions, refer to the Section 3. Other than that,
-there is one thing that is missing from this version of FPE: packed
-BCD support.
-
-I have no plan to support it since it's rarely used. However, all we
-need to support it is explosion/implosion functions between the
-internal FP representation and the m68k PBCD format, so you are more
-than welcome to write such functions if you wish to.
-
-
-3. IMPLEMENTED INSTRUCTIONS
-
-This is the list of implemented and unimplemented FPU instructions.
-All 040's directly supported type 0 instructions are already
-implemented except FSGLDIV and FSGLMUL.
-
-Type field = bit 8-6 of opcode word
-
-* Implemented Instructions
-
-Type=0: FMOVE (mem->FPr), FINT, FINTRZ, FSQRT, FABS, FNEG, FGETEXP,
- FGETMAN, FDIV, FADD, FMUL, FSGLDIV(*), FSCALE, FSGLMUL(*), FSUB,
- FCMP, FTST, FMOVE (FPr->mem), FMOVEM (FPr), FMOVEM (FPcr),
- FMOVECR, FLOGNP1, FLOGN, FLOG10, FLOG2, FMOD, FREM
-
-Type=1: FDBcc, FScc, FTRAPcc,
-
-Type=2: FBcc (word, incl. FNOP)
-
-Type=3: FBcc (long)
-
-Type=4: none
-
-Type=5: none
-
- *: currently FSGLMUL and FSGLDIV are just aliases of
- FMUL and FDIV, respectively
-
-* Unimplemented Instructions
-
-Type=0: FSINH, FETOXM1, FTANH, FATAN, FASIN, FATANH, FSIN, FTAN,
- FETOX, FTWOTOX, FTENTOX, FCOSH, FACOS, FCOS, FSINCOS
-
-Type=1: none
-
-Type=2: none
-
-Type=3: none
-
-Type=4: FSAVE
-
-Type=5: FRESTORE
-
-
-4. HOW TO ADD A NEW INSTRUCTION SUPPORT
-
-Since we need not support FSAVE and FRESTORE operations, all
-instructions we have to implement are type 0, all of which are
-arithmetic operations. It is particularly easy to add a new
-arithmetic instruction to the existing ones (not that it is easy to
-write a "stable" function to perform floating point operation. That's
-entirely another matter). In "fpu_emulate.c", there's a function
-fpu_emul_arith() which calls emulation functions for all arithmetic
-operations. In it, there's a large switch() { case ... } which
-dispatches each instruction emulator. An emulation function of any
-type 0 arithmetic instruction follows this prototype:
-
- struct fpn *fpu_op(struct fpemu *fe);
-
-Where fe is a pointer to a struct fpemu in which frame, fpframe, and
-fetched operands are accessible. That's right, you don't have to
-fetch the operands by yourself in your emulation function. For
-instance, the parts calling FSQRT, FSUB, FADD and FTST look like:
-
- switch(word1 & 0x3F) {
-[...]
- case 0x04: /* fsqrt */
- res = fpu_sqrt(fe);
- break;
-[...]
- case 0x28: /* fsub */
- fe->fe_f2.fp_sign = !fe->fe_f2.fp_sign; /* f2 = -f2 */
- case 0x22: /* fadd */
- res = fpu_add(fe);
- break;
-[...]
- case 0x3A: /* ftst */
- res = &fe->fe_f2;
- no_store = 1;
- break;
-[...]
- default:
- sig = SIGILL;
- } /* switch */
-
-Here, fe->fe_f1 and fe->fe_f2 are fetched operands. You can use
-fe->fe_f3 for storing the result, or you can return a pointer to
-either operand if you want to. At any rate, you have to follow
-the following rules:
-
- 1) A dyadic instruction takes two operands fe->fe_f1 and fe->fe_f2.
- 2) A monadic instruction takes one operand fe->fe_f2 (NOT fe_f1).
- 3) Must return a pointer to struct fpn where the result is stored,
- and assign the pointer to the variable "res".
- 4) If exceptions are detected, set corresponding bits in fe->fe_fpsr.
- The rest is taken care of in fpu_emul_arith().
- 5) Condition code does not need to be calculated. It's taken care of in
- fpu_emul_arith().
diff --git a/sys/arch/m68k/fpe/files.fpe b/sys/arch/m68k/fpe/files.fpe
deleted file mode 100644
index a10c479e163..00000000000
--- a/sys/arch/m68k/fpe/files.fpe
+++ /dev/null
@@ -1,22 +0,0 @@
-# $OpenBSD: files.fpe,v 1.3 2006/01/16 22:08:26 miod Exp $
-# $NetBSD: files.fpe,v 1.2 1995/11/03 04:51:51 briggs Exp $
-
-# files for m68k floating point emulator.
-# Included by ports that need it.
-
-file arch/m68k/fpe/fpu_add.c fpu_emulate
-file arch/m68k/fpe/fpu_calcea.c fpu_emulate
-file arch/m68k/fpe/fpu_div.c fpu_emulate
-file arch/m68k/fpe/fpu_emulate.c fpu_emulate
-file arch/m68k/fpe/fpu_explode.c fpu_emulate
-file arch/m68k/fpe/fpu_fmovecr.c fpu_emulate
-file arch/m68k/fpe/fpu_fscale.c fpu_emulate
-file arch/m68k/fpe/fpu_fstore.c fpu_emulate
-file arch/m68k/fpe/fpu_getexp.c fpu_emulate
-file arch/m68k/fpe/fpu_implode.c fpu_emulate
-file arch/m68k/fpe/fpu_int.c fpu_emulate
-file arch/m68k/fpe/fpu_log.c fpu_emulate
-file arch/m68k/fpe/fpu_mul.c fpu_emulate
-file arch/m68k/fpe/fpu_rem.c fpu_emulate
-file arch/m68k/fpe/fpu_sqrt.c fpu_emulate
-file arch/m68k/fpe/fpu_subr.c fpu_emulate
diff --git a/sys/arch/m68k/fpe/fpu_add.c b/sys/arch/m68k/fpe/fpu_add.c
deleted file mode 100644
index ac53572b3ef..00000000000
--- a/sys/arch/m68k/fpe/fpu_add.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/* $OpenBSD: fpu_add.c,v 1.4 2006/01/16 22:08:26 miod Exp $ */
-/* $NetBSD: fpu_add.c,v 1.5 2003/08/07 16:28:10 agc Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- * @(#)fpu_add.c 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Perform an FPU add (return x + y).
- *
- * To subtract, negate y and call add.
- */
-
-#include <sys/types.h>
-#include <sys/systm.h>
-
-#include <machine/reg.h>
-
-#include "fpu_arith.h"
-#include "fpu_emulate.h"
-
-struct fpn *
-fpu_add(fe)
- struct fpemu *fe;
-{
- struct fpn *x = &fe->fe_f1, *y = &fe->fe_f2, *r;
- u_int r0, r1, r2;
- int rd;
-
- /*
- * Put the `heavier' operand on the right (see fpu_emu.h).
- * Then we will have one of the following cases, taken in the
- * following order:
- *
- * - y = NaN. Implied: if only one is a signalling NaN, y is.
- * The result is y.
- * - y = Inf. Implied: x != NaN (is 0, number, or Inf: the NaN
- * case was taken care of earlier).
- * If x = -y, the result is NaN. Otherwise the result
- * is y (an Inf of whichever sign).
- * - y is 0. Implied: x = 0.
- * If x and y differ in sign (one positive, one negative),
- * the result is +0 except when rounding to -Inf. If same:
- * +0 + +0 = +0; -0 + -0 = -0.
- * - x is 0. Implied: y != 0.
- * Result is y.
- * - other. Implied: both x and y are numbers.
- * Do addition a la Hennessey & Patterson.
- */
- ORDER(x, y);
- if (ISNAN(y))
- return (y);
- if (ISINF(y)) {
- if (ISINF(x) && x->fp_sign != y->fp_sign)
- return (fpu_newnan(fe));
- return (y);
- }
- rd = (fe->fe_fpcr & FPCR_ROUND);
- if (ISZERO(y)) {
- if (rd != FPCR_MINF) /* only -0 + -0 gives -0 */
- y->fp_sign &= x->fp_sign;
- else /* any -0 operand gives -0 */
- y->fp_sign |= x->fp_sign;
- return (y);
- }
- if (ISZERO(x))
- return (y);
- /*
- * We really have two numbers to add, although their signs may
- * differ. Make the exponents match, by shifting the smaller
- * number right (e.g., 1.011 => 0.1011) and increasing its
- * exponent (2^3 => 2^4). Note that we do not alter the exponents
- * of x and y here.
- */
- r = &fe->fe_f3;
- r->fp_class = FPC_NUM;
- if (x->fp_exp == y->fp_exp) {
- r->fp_exp = x->fp_exp;
- r->fp_sticky = 0;
- } else {
- if (x->fp_exp < y->fp_exp) {
- /*
- * Try to avoid subtract case iii (see below).
- * This also guarantees that x->fp_sticky = 0.
- */
- SWAP(x, y);
- }
- /* now x->fp_exp > y->fp_exp */
- r->fp_exp = x->fp_exp;
- r->fp_sticky = fpu_shr(y, x->fp_exp - y->fp_exp);
- }
- r->fp_sign = x->fp_sign;
- if (x->fp_sign == y->fp_sign) {
- FPU_DECL_CARRY
-
- /*
- * The signs match, so we simply add the numbers. The result
- * may be `supernormal' (as big as 1.111...1 + 1.111...1, or
- * 11.111...0). If so, a single bit shift-right will fix it
- * (but remember to adjust the exponent).
- */
- /* r->fp_mant = x->fp_mant + y->fp_mant */
- FPU_ADDS(r->fp_mant[2], x->fp_mant[2], y->fp_mant[2]);
- FPU_ADDCS(r->fp_mant[1], x->fp_mant[1], y->fp_mant[1]);
- FPU_ADDC(r0, x->fp_mant[0], y->fp_mant[0]);
- if ((r->fp_mant[0] = r0) >= FP_2) {
- (void) fpu_shr(r, 1);
- r->fp_exp++;
- }
- } else {
- FPU_DECL_CARRY
-
- /*
- * The signs differ, so things are rather more difficult.
- * H&P would have us negate the negative operand and add;
- * this is the same as subtracting the negative operand.
- * This is quite a headache. Instead, we will subtract
- * y from x, regardless of whether y itself is the negative
- * operand. When this is done one of three conditions will
- * hold, depending on the magnitudes of x and y:
- * case i) |x| > |y|. The result is just x - y,
- * with x's sign, but it may need to be normalized.
- * case ii) |x| = |y|. The result is 0 (maybe -0)
- * so must be fixed up.
- * case iii) |x| < |y|. We goofed; the result should
- * be (y - x), with the same sign as y.
- * We could compare |x| and |y| here and avoid case iii,
- * but that would take just as much work as the subtract.
- * We can tell case iii has occurred by an overflow.
- *
- * N.B.: since x->fp_exp >= y->fp_exp, x->fp_sticky = 0.
- */
- /* r->fp_mant = x->fp_mant - y->fp_mant */
- FPU_SET_CARRY(y->fp_sticky);
- FPU_SUBCS(r2, x->fp_mant[2], y->fp_mant[2]);
- FPU_SUBCS(r1, x->fp_mant[1], y->fp_mant[1]);
- FPU_SUBC(r0, x->fp_mant[0], y->fp_mant[0]);
- if (r0 < FP_2) {
- /* cases i and ii */
- if ((r0 | r1 | r2) == 0) {
- /* case ii */
- r->fp_class = FPC_ZERO;
- r->fp_sign = (rd == FPCR_MINF);
- return (r);
- }
- } else {
- /*
- * Oops, case iii. This can only occur when the
- * exponents were equal, in which case neither
- * x nor y have sticky bits set. Flip the sign
- * (to y's sign) and negate the result to get y - x.
- */
-#ifdef DIAGNOSTIC
- if (x->fp_exp != y->fp_exp || r->fp_sticky)
- panic("fpu_add");
-#endif
- r->fp_sign = y->fp_sign;
- FPU_SUBS(r2, 0, r2);
- FPU_SUBCS(r1, 0, r1);
- FPU_SUBC(r0, 0, r0);
- }
- r->fp_mant[2] = r2;
- r->fp_mant[1] = r1;
- r->fp_mant[0] = r0;
- if (r0 < FP_1)
- fpu_norm(r);
- }
- return (r);
-}
diff --git a/sys/arch/m68k/fpe/fpu_arith.h b/sys/arch/m68k/fpe/fpu_arith.h
deleted file mode 100644
index bceb7f25f38..00000000000
--- a/sys/arch/m68k/fpe/fpu_arith.h
+++ /dev/null
@@ -1,171 +0,0 @@
-/* $OpenBSD: fpu_arith.h,v 1.5 2011/09/17 08:38:07 miod Exp $ */
-/* $NetBSD: fpu_arith.h,v 1.3 2003/08/07 16:28:10 agc Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- * @(#)fpu_arith.h 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Extended-precision arithmetic.
- *
- * We hold the notion of a `carry register', which may or may not be a
- * machine carry bit or register. On the SPARC, it is just the machine's
- * carry bit.
- *
- * In the worst case, you can compute the carry from x+y as
- * (unsigned)(x + y) < (unsigned)x
- * and from x+y+c as
- * ((unsigned)(x + y + c) <= (unsigned)x && (y|c) != 0)
- * for example.
- */
-
-#ifndef FPE_USE_ASM
-
-/* set up for extended-precision arithmetic */
-#define FPU_DECL_CARRY quad_t fpu_carry, fpu_tmp;
-
-/*
- * We have three kinds of add:
- * add with carry: r = x + y + c
- * add (ignoring current carry) and set carry: c'r = x + y + 0
- * add with carry and set carry: c'r = x + y + c
- * The macros use `C' for `use carry' and `S' for `set carry'.
- * Note that the state of the carry is undefined after ADDC and SUBC,
- * so if all you have for these is `add with carry and set carry',
- * that is OK.
- *
- * The same goes for subtract, except that we compute x - y - c.
- *
- * Finally, we have a way to get the carry into a `regular' variable,
- * or set it from a value. SET_CARRY turns 0 into no-carry, nonzero
- * into carry; GET_CARRY sets its argument to 0 or 1.
- */
-#define FPU_ADDC(r, x, y) \
- (r) = (x) + (y) + (!!fpu_carry)
-#define FPU_ADDS(r, x, y) \
- { \
- fpu_tmp = (quad_t)(x) + (quad_t)(y); \
- (r) = (u_int)fpu_tmp; \
- fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); \
- }
-#define FPU_ADDCS(r, x, y) \
- { \
- fpu_tmp = (quad_t)(x) + (quad_t)(y) + (!!fpu_carry); \
- (r) = (u_int)fpu_tmp; \
- fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); \
- }
-#define FPU_SUBC(r, x, y) \
- (r) = (x) - (y) - (!!fpu_carry)
-#define FPU_SUBS(r, x, y) \
- { \
- fpu_tmp = (quad_t)(x) - (quad_t)(y); \
- (r) = (u_int)fpu_tmp; \
- fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); \
- }
-#define FPU_SUBCS(r, x, y) \
- { \
- fpu_tmp = (quad_t)(x) - (quad_t)(y) - (!!fpu_carry); \
- (r) = (u_int)fpu_tmp; \
- fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); \
- }
-
-#define FPU_GET_CARRY(r) (r) = (!!fpu_carry)
-#define FPU_SET_CARRY(v) fpu_carry = ((v) != 0)
-
-#else
-
-/* set up for extended-precision arithmetic */
-#define FPU_DECL_CARRY int fpu_tmp;
-
-/*
- * We have three kinds of add:
- * add with carry: r = x + y + c
- * add (ignoring current carry) and set carry: c'r = x + y + 0
- * add with carry and set carry: c'r = x + y + c
- * The macros use `C' for `use carry' and `S' for `set carry'.
- * Note that the state of the carry is undefined after ADDC and SUBC,
- * so if all you have for these is `add with carry and set carry',
- * that is OK.
- *
- * The same goes for subtract, except that we compute x - y - c.
- *
- * Finally, we have a way to get the carry into a `regular' variable,
- * or set it from a value. SET_CARRY turns 0 into no-carry, nonzero
- * into carry; GET_CARRY sets its argument to 0 or 1.
- */
-#define FPU_ADDC(r, x, y) \
- { \
- asm volatile("movel %1,%0" : "=d"(fpu_tmp) : "g"(x)); \
- asm volatile("addxl %1,%0" : "=d"(fpu_tmp) : "d"(y)); \
- asm volatile("movel %1,%0" : "=g"(r) : "r"(fpu_tmp)); \
- }
-#define FPU_ADDS(r, x, y) \
- { \
- asm volatile("movel %1,%0" : "=d"(fpu_tmp) : "g"(x)); \
- asm volatile("addl %1,%0" : "=d"(fpu_tmp) : "g"(y)); \
- asm volatile("movel %1,%0" : "=g"(r) : "r"(fpu_tmp)); \
- }
-#define FPU_ADDCS(r, x, y) FPU_ADDC(r, x, y)
-
-#define FPU_SUBC(r, x, y) \
- { \
- asm volatile("movel %1,%0" : "=d"(fpu_tmp) : "g"(x)); \
- asm volatile("subxl %1,%0" : "=d"(fpu_tmp) : "d"(y)); \
- asm volatile("movel %1,%0" : "=g"(r) : "r"(fpu_tmp)); \
- }
-#define FPU_SUBS(r, x, y) \
- { \
- asm volatile("movel %1,%0" : "=d"(fpu_tmp) : "g"(x)); \
- asm volatile("subl %1,%0" : "=d"(fpu_tmp) : "g"(y)); \
- asm volatile("movel %1,%0" : "=g"(r) : "r"(fpu_tmp)); \
- }
-#define FPU_SUBCS(r, x, y) FPU_SUBC(r, x, y)
-
-#define FPU_GET_CARRY(r) \
- { \
- asm volatile("moveq #0,%0" : "=d"(r)); \
- asm volatile("addxl %0,%0" : "+d"(r)); \
- }
-#define FPU_SET_CARRY(v) \
- { \
- asm volatile("moveq #0,%0" : "=d"(fpu_tmp)); \
- asm volatile("subl %1,%0" : "=d"(fpu_tmp) : "g"(v)); \
- }
-
-#endif /* FPE_USE_ASM */
diff --git a/sys/arch/m68k/fpe/fpu_arith_proto.h b/sys/arch/m68k/fpe/fpu_arith_proto.h
deleted file mode 100644
index 8976c8c55e4..00000000000
--- a/sys/arch/m68k/fpe/fpu_arith_proto.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* $OpenBSD: fpu_arith_proto.h,v 1.4 2006/01/16 22:08:26 miod Exp $ */
-/* $NetBSD: fpu_arith_proto.h,v 1.1 1995/11/03 04:47:00 briggs Exp $ */
-
-/*
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * @(#)fpu_arith_proto.c 10/24/95
- */
-
-#ifndef _FPU_ARITH_PROTO_H_
-#define _FPU_ARITH_PROTO_H_
-
-/*
- * Arithmetic functions - called from fpu_emul_arith().
- * Each of these may modify its inputs (f1,f2) and/or the temporary.
- * Each returns a pointer to the result and/or sets exceptions.
- */
-
-/* fpu_add.c */
-struct fpn *fpu_add(struct fpemu *fe);
-
-/* fpu_div.c */
-struct fpn *fpu_div(struct fpemu *fe);
-
-/* fpu_getexp.c */
-struct fpn *fpu_getexp(struct fpemu *fe);
-struct fpn *fpu_getman(struct fpemu *fe);
-
-/* fpu_int.c */
-struct fpn *fpu_intrz(struct fpemu *fe);
-struct fpn *fpu_int(struct fpemu *fe);
-
-/* fpu_log.c */
-struct fpn *fpu_log10(struct fpemu *fe);
-struct fpn *fpu_log2(struct fpemu *fe);
-struct fpn *fpu_logn(struct fpemu *fe);
-struct fpn *fpu_lognp1(struct fpemu *fe);
-
-/* fpu_mulc */
-struct fpn *fpu_mul(struct fpemu *fe);
-
-/* fpu_rem.c */
-struct fpn *fpu_rem(struct fpemu *fe);
-struct fpn *fpu_mod(struct fpemu *fe);
-
-/* fpu_sqrt.c */
-struct fpn *fpu_sqrt(struct fpemu *fe);
-
-#endif /* _FPU_ARITH_PROTO_H_ */
diff --git a/sys/arch/m68k/fpe/fpu_calcea.c b/sys/arch/m68k/fpe/fpu_calcea.c
deleted file mode 100644
index 8d76a849158..00000000000
--- a/sys/arch/m68k/fpe/fpu_calcea.c
+++ /dev/null
@@ -1,767 +0,0 @@
-/* $OpenBSD: fpu_calcea.c,v 1.11 2006/01/30 21:23:22 miod Exp $ */
-/* $NetBSD: fpu_calcea.c,v 1.16 2004/02/13 11:36:14 wiz Exp $ */
-
-/*
- * Copyright (c) 1995 Gordon W. Ross
- * portion Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- * 4. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Gordon Ross
- *
- * 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.
- */
-
-#include <sys/param.h>
-#include <sys/signal.h>
-#include <sys/systm.h>
-#include <machine/frame.h>
-
-#include "fpu_emulate.h"
-
-/*
- * Prototypes of local functions
- */
-int decode_ea6(struct frame *frame, struct instruction *insn,
- struct insn_ea *ea, int modreg, int *typ);
-int fetch_immed(struct frame *frame, struct instruction *insn,
- int *dst);
-int fetch_disp(struct frame *frame, struct instruction *insn,
- int size, int *res);
-int calc_ea(struct insn_ea *ea, char *ptr, char **eaddr);
-
-/*
- * Helper routines for dealing with "effective address" values.
- */
-
-/*
- * Decode an effective address into internal form.
- * Returns zero on success, else signal number.
- */
-int
-fpu_decode_ea(struct frame *frame, struct instruction *insn, struct insn_ea *ea,
- int modreg, int *typ)
-{
- int sig;
-
-#ifdef DEBUG
- if (insn->is_datasize < 0) {
- panic("decode_ea: called with uninitialized datasize");
- }
-#endif
-
- sig = 0;
-
- /* Set the most common value here. */
- ea->ea_regnum = 8 + (modreg & 7);
-
- if ((modreg & 060) == 0) {
- /* register direct */
- ea->ea_regnum = modreg & 0xf;
- ea->ea_flags = EA_DIRECT;
-#ifdef DEBUG_FPE
- printf("decode_ea: register direct reg=%d\n", ea->ea_regnum);
-#endif
- } else if ((modreg & 077) == 074) {
- /* immediate */
- ea->ea_flags = EA_IMMED;
- sig = fetch_immed(frame, insn, &ea->ea_immed[0]);
-#ifdef DEBUG_FPE
- printf("decode_ea: immediate size=%d\n", insn->is_datasize);
-#endif
- }
- /*
- * rest of the address modes need to be separately
- * handled for the LC040 and the others.
- */
-#if 0 /* XXX */
- else if (frame->f_format == 4 && frame->f_fmt4.f_fa) {
- /* LC040 */
- ea->ea_flags = EA_FRAME_EA;
- ea->ea_fea = frame->f_fmt4.f_fa;
-#ifdef DEBUG_FPE
- printf("decode_ea: 68LC040 - in-frame EA (%p) size %d\n",
- (void *)ea->ea_fea, insn->is_datasize);
-#endif
- if ((modreg & 070) == 030) {
- /* postincrement mode */
- ea->ea_flags |= EA_POSTINCR;
- } else if ((modreg & 070) == 040) {
- /* predecrement mode */
- ea->ea_flags |= EA_PREDECR;
-#ifdef M68060
-#if defined(M68020) || defined(M68030) || defined(M68040)
- if (cputype == CPU_68060)
-#endif
- if (insn->is_datasize == 12)
- ea->ea_fea -= 8;
-#endif
- }
- }
-#endif /* XXX */
- else {
- /* 020/030 */
- switch (modreg & 070) {
-
- case 020: /* (An) */
- ea->ea_flags = 0;
-#ifdef DEBUG_FPE
- printf("decode_ea: register indirect reg=%d\n", ea->ea_regnum);
-#endif
- break;
-
- case 030: /* (An)+ */
- ea->ea_flags = EA_POSTINCR;
-#ifdef DEBUG_FPE
- printf("decode_ea: reg indirect postincrement reg=%d\n",
- ea->ea_regnum);
-#endif
- break;
-
- case 040: /* -(An) */
- ea->ea_flags = EA_PREDECR;
-#ifdef DEBUG_FPE
- printf("decode_ea: reg indirect predecrement reg=%d\n",
- ea->ea_regnum);
-#endif
- break;
-
- case 050: /* (d16,An) */
- ea->ea_flags = EA_OFFSET;
- sig = fetch_disp(frame, insn, 1, &ea->ea_offset);
-#ifdef DEBUG_FPE
- printf("decode_ea: reg indirect with displacement reg=%d\n",
- ea->ea_regnum);
-#endif
- break;
-
- case 060: /* (d8,An,Xn) */
- ea->ea_flags = EA_INDEXED;
- sig = decode_ea6(frame, insn, ea, modreg, typ);
- break;
-
- case 070: /* misc. */
- ea->ea_regnum = (modreg & 7);
- switch (modreg & 7) {
-
- case 0: /* (xxxx).W */
- ea->ea_flags = EA_ABS;
- sig = fetch_disp(frame, insn, 1, &ea->ea_absaddr);
-#ifdef DEBUG_FPE
- printf("decode_ea: absolute address (word)\n");
-#endif
- break;
-
- case 1: /* (xxxxxxxx).L */
- ea->ea_flags = EA_ABS;
- sig = fetch_disp(frame, insn, 2, &ea->ea_absaddr);
-#ifdef DEBUG_FPE
- printf("decode_ea: absolute address (long)\n");
-#endif
- break;
-
- case 2: /* (d16,PC) */
- ea->ea_flags = EA_PC_REL | EA_OFFSET;
- sig = fetch_disp(frame, insn, 1, &ea->ea_absaddr);
-#ifdef DEBUG_FPE
- printf("decode_ea: pc relative word displacement\n");
-#endif
- break;
-
- case 3: /* (d8,PC,Xn) */
- ea->ea_flags = EA_PC_REL | EA_INDEXED;
- sig = decode_ea6(frame, insn, ea, modreg, typ);
- break;
-
- case 4: /* #data */
- /* it should have been taken care of earlier */
- default:
-#ifdef DEBUG_FPE
- printf("decode_ea: invalid addr mode (7,%d)\n", modreg & 7);
-#endif
- *typ = ILL_ILLADR;
- return SIGILL;
- } /* switch for mode 7 */
- break;
- } /* switch mode */
- }
- ea->ea_moffs = 0;
-
- return sig;
-}
-
-/*
- * Decode Mode=6 address modes
- */
-int
-decode_ea6(struct frame *frame, struct instruction *insn, struct insn_ea *ea,
- int modreg, int *typ)
-{
- int idx;
- int basedisp, outerdisp;
- int bd_size, od_size;
- int sig;
- u_int16_t extword;
-
- if (copyin((void *)(insn->is_pc + insn->is_advance), &extword,
- sizeof(extword)) != 0) {
- return SIGSEGV;
- }
- insn->is_advance += 2;
-
- /* get register index */
- ea->ea_idxreg = (extword >> 12) & 0xf;
- idx = frame->f_regs[ea->ea_idxreg];
- if ((extword & 0x0800) == 0) {
- /* if word sized index, sign-extend */
- idx &= 0xffff;
- if (idx & 0x8000) {
- idx |= 0xffff0000;
- }
- }
- /* scale register index */
- idx <<= ((extword >> 9) & 3);
-
- if ((extword & 0x100) == 0) {
- /* brief extension word - sign-extend the displacement */
- basedisp = (extword & 0xff);
- if (basedisp & 0x80) {
- basedisp |= 0xffffff00;
- }
-
- ea->ea_basedisp = idx + basedisp;
- ea->ea_outerdisp = 0;
-#if DEBUG_FPE
- printf("decode_ea6: brief ext word idxreg=%d, basedisp=%08x\n",
- ea->ea_idxreg, ea->ea_basedisp);
-#endif
- } else {
- /* full extension word */
- if (extword & 0x80) {
- ea->ea_flags |= EA_BASE_SUPPRSS;
- }
- bd_size = ((extword >> 4) & 3) - 1;
- od_size = (extword & 3) - 1;
- sig = fetch_disp(frame, insn, bd_size, &basedisp);
- if (sig) {
- return sig;
- }
- if (od_size >= 0) {
- ea->ea_flags |= EA_MEM_INDIR;
- }
- sig = fetch_disp(frame, insn, od_size, &outerdisp);
- if (sig) {
- return sig;
- }
-
- switch (extword & 0x44) {
- case 0: /* preindexed */
- ea->ea_basedisp = basedisp + idx;
- ea->ea_outerdisp = outerdisp;
- break;
- case 4: /* postindexed */
- ea->ea_basedisp = basedisp;
- ea->ea_outerdisp = outerdisp + idx;
- break;
- case 0x40: /* no index */
- ea->ea_basedisp = basedisp;
- ea->ea_outerdisp = outerdisp;
- break;
- default:
-#ifdef DEBUG
- printf("decode_ea6: invalid indirect mode: ext word %02x\n",
- extword);
-#endif
- *typ = ILL_ILLADR;
- return SIGILL;
- break;
- }
-#if DEBUG_FPE
- printf("decode_ea6: full ext idxreg=%d, basedisp=%x, outerdisp=%x\n",
- ea->ea_idxreg, ea->ea_basedisp, ea->ea_outerdisp);
-#endif
- }
-#if DEBUG_FPE
- printf("decode_ea6: regnum=%d, flags=%x\n",
- ea->ea_regnum, ea->ea_flags);
-#endif
- return 0;
-}
-
-/*
- * Load a value from an effective address.
- * Returns zero on success, else signal number.
- */
-int
-fpu_load_ea(struct frame *frame, struct instruction *insn, struct insn_ea *ea,
- char *dst, int *typ)
-{
- int *reg;
- char *src;
- int len, step;
- int sig;
-
-#ifdef DIAGNOSTIC
- if (ea->ea_regnum & ~0xF) {
- panic("load_ea: bad regnum");
- }
-#endif
-
-#ifdef DEBUG_FPE
- printf("load_ea: frame at %p\n", frame);
-#endif
- /* dst is always int or larger. */
- len = insn->is_datasize;
- if (len < 4) {
- dst += (4 - len);
- }
- step = (len == 1 && ea->ea_regnum == 15 /* sp */) ? 2 : len;
-
-#if 0
- if (ea->ea_flags & EA_FRAME_EA) {
- /* Using LC040 frame EA */
-#ifdef DEBUG_FPE
- if (ea->ea_flags & (EA_PREDECR|EA_POSTINCR)) {
- printf("load_ea: frame ea %08x w/r%d\n",
- ea->ea_fea, ea->ea_regnum);
- } else {
- printf("load_ea: frame ea %08x\n", ea->ea_fea);
- }
-#endif
- src = (char *)ea->ea_fea;
- if (copyin(src + ea->ea_moffs, dst, len) != 0)
- return (SIGSEGV);
- if (ea->ea_flags & EA_PREDECR) {
- frame->f_regs[ea->ea_regnum] = ea->ea_fea;
- ea->ea_fea -= step;
- ea->ea_moffs = 0;
- } else if (ea->ea_flags & EA_POSTINCR) {
- ea->ea_fea += step;
- frame->f_regs[ea->ea_regnum] = ea->ea_fea;
- ea->ea_moffs = 0;
- } else {
- ea->ea_moffs += step;
- }
- /* That's it, folks */
- } else if (ea->ea_flags & EA_DIRECT) {
- if (len > 4) {
-#ifdef DEBUG
- printf("load_ea: operand doesn't fit CPU reg\n");
-#endif
- return SIGILL;
- }
- if (ea->ea_moffs > 0) {
-#ifdef DEBUG
- printf("load_ea: more than one move from CPU reg\n");
-#endif
- return SIGILL;
- }
- src = (char *)&frame->f_regs[ea->ea_regnum];
- /* The source is an int. */
- if (len < 4) {
- src += (4 - len);
-#ifdef DEBUG_FPE
- printf("load_ea: short/byte opr - addr adjusted\n");
-#endif
- }
-#ifdef DEBUG_FPE
- printf("load_ea: src %p\n", src);
-#endif
- memcpy(dst, src, len);
- } else
-#endif /* 0 */
- if (ea->ea_flags & EA_IMMED) {
-#ifdef DEBUG_FPE
- printf("load_ea: immed %08x%08x%08x size %d\n",
- ea->ea_immed[0], ea->ea_immed[1], ea->ea_immed[2], len);
-#endif
- src = (char *)&ea->ea_immed[0];
- if (len < 4) {
- src += (4 - len);
-#ifdef DEBUG_FPE
- printf("load_ea: short/byte immed opr - addr adjusted\n");
-#endif
- }
- memcpy(dst, src, len);
- } else if (ea->ea_flags & EA_ABS) {
-#ifdef DEBUG_FPE
- printf("load_ea: abs addr %08x\n", ea->ea_absaddr);
-#endif
- src = (char *)ea->ea_absaddr;
- if (copyin(src, dst, len) != 0)
- return (SIGSEGV);
- } else /* register indirect */ {
- if (ea->ea_flags & EA_PC_REL) {
-#ifdef DEBUG_FPE
- printf("load_ea: using PC\n");
-#endif
- reg = NULL;
- /* Grab the register contents. 4 is offset to the first
- extension word from the opcode */
- src = (char *)insn->is_pc + 4;
-#ifdef DEBUG_FPE
- printf("load_ea: pc relative pc+4 = %p\n", src);
-#endif
- } else /* not PC relative */ {
-#ifdef DEBUG_FPE
- printf("load_ea: using register %c%d\n",
- (ea->ea_regnum >= 8) ? 'a' : 'd', ea->ea_regnum & 7);
-#endif
- /* point to the register */
- reg = &frame->f_regs[ea->ea_regnum];
-
- if (ea->ea_flags & EA_PREDECR) {
-#ifdef DEBUG_FPE
- printf("load_ea: predecr mode - reg decremented\n");
-#endif
- *reg -= step;
- ea->ea_moffs = 0;
- }
-
- /* Grab the register contents. */
- src = (char *)*reg;
-#ifdef DEBUG_FPE
- printf("load_ea: reg indirect reg = %p\n", src);
-#endif
- }
-
- sig = calc_ea(ea, src, &src);
- if (sig)
- return sig;
-
- if (copyin(src + ea->ea_moffs, dst, len) != 0)
- return (SIGSEGV);
-
- /* do post-increment */
- if (ea->ea_flags & EA_POSTINCR) {
- if (ea->ea_flags & EA_PC_REL) {
-#ifdef DEBUG
- printf("load_ea: tried to postincrement PC\n");
-#endif
- *typ = ILL_ILLADR;
- return SIGILL;
- }
- *reg += step;
- ea->ea_moffs = 0;
-#ifdef DEBUG_FPE
- printf("load_ea: postinc mode - reg incremented\n");
-#endif
- } else {
- ea->ea_moffs += len;
- }
- }
-
- return 0;
-}
-
-/*
- * Store a value at the effective address.
- * Returns zero on success, else signal number.
- */
-int
-fpu_store_ea(frame, insn, ea, src)
- struct frame *frame;
- struct instruction *insn;
- struct insn_ea *ea;
- char *src;
-{
- int *reg;
- char *dst;
- int len, step;
- int sig;
-
-#ifdef DIAGNOSTIC
- if (ea->ea_regnum & ~0xf) {
- panic("store_ea: bad regnum");
- }
-#endif
-
- if (ea->ea_flags & (EA_IMMED|EA_PC_REL)) {
- /* not alterable address mode */
-#ifdef DEBUG
- printf("store_ea: not alterable address mode\n");
-#endif
- return SIGILL;
- }
-
- /* src is always int or larger. */
- len = insn->is_datasize;
- if (len < 4) {
- src += (4 - len);
- }
- step = (len == 1 && ea->ea_regnum == 15 /* sp */) ? 2 : len;
-
- if (ea->ea_flags & EA_FRAME_EA) {
- /* Using LC040 frame EA */
-#ifdef DEBUG_FPE
- if (ea->ea_flags & (EA_PREDECR|EA_POSTINCR)) {
- printf("store_ea: frame ea %08x w/r%d\n",
- ea->ea_fea, ea->ea_regnum);
- } else {
- printf("store_ea: frame ea %08x\n", ea->ea_fea);
- }
-#endif
- dst = (char *)ea->ea_fea;
- copyout(src, dst + ea->ea_moffs, len);
- if (ea->ea_flags & EA_PREDECR) {
- frame->f_regs[ea->ea_regnum] = ea->ea_fea;
- ea->ea_fea -= step;
- ea->ea_moffs = 0;
- } else if (ea->ea_flags & EA_POSTINCR) {
- ea->ea_fea += step;
- frame->f_regs[ea->ea_regnum] = ea->ea_fea;
- ea->ea_moffs = 0;
- } else {
- ea->ea_moffs += step;
- }
- /* That's it, folks */
- } else if (ea->ea_flags & EA_ABS) {
-#ifdef DEBUG_FPE
- printf("store_ea: abs addr %08x\n", ea->ea_absaddr);
-#endif
- dst = (char *)ea->ea_absaddr;
- copyout(src, dst + ea->ea_moffs, len);
- ea->ea_moffs += len;
- } else if (ea->ea_flags & EA_DIRECT) {
- if (len > 4) {
-#ifdef DEBUG
- printf("store_ea: operand doesn't fit CPU reg\n");
-#endif
- return SIGILL;
- }
- if (ea->ea_moffs > 0) {
-#ifdef DEBUG
- printf("store_ea: more than one move to CPU reg\n");
-#endif
- return SIGILL;
- }
- dst = (char *)&frame->f_regs[ea->ea_regnum];
- /* The destination is an int. */
- if (len < 4) {
- dst += (4 - len);
-#ifdef DEBUG_FPE
- printf("store_ea: short/byte opr - dst addr adjusted\n");
-#endif
- }
-#ifdef DEBUG_FPE
- printf("store_ea: dst %p\n", dst);
-#endif
- memcpy(dst, src, len);
- } else /* One of MANY indirect forms... */ {
-#ifdef DEBUG_FPE
- printf("store_ea: using register %c%d\n",
- (ea->ea_regnum >= 8) ? 'a' : 'd', ea->ea_regnum & 7);
-#endif
- /* point to the register */
- reg = &(frame->f_regs[ea->ea_regnum]);
-
- /* do pre-decrement */
- if (ea->ea_flags & EA_PREDECR) {
-#ifdef DEBUG_FPE
- printf("store_ea: predecr mode - reg decremented\n");
-#endif
- *reg -= step;
- ea->ea_moffs = 0;
- }
-
- /* calculate the effective address */
- sig = calc_ea(ea, (char *)*reg, &dst);
- if (sig)
- return sig;
-
-#ifdef DEBUG_FPE
- printf("store_ea: dst addr=%p+%d\n", dst, ea->ea_moffs);
-#endif
- copyout(src, dst + ea->ea_moffs, len);
-
- /* do post-increment */
- if (ea->ea_flags & EA_POSTINCR) {
- *reg += step;
- ea->ea_moffs = 0;
-#ifdef DEBUG_FPE
- printf("store_ea: postinc mode - reg incremented\n");
-#endif
- } else {
- ea->ea_moffs += len;
- }
- }
-
- return 0;
-}
-
-/*
- * fetch_immed: fetch immediate operand
- */
-int
-fetch_immed(frame, insn, dst)
- struct frame *frame;
- struct instruction *insn;
- int *dst;
-{
- int data, ext_bytes;
- u_int16_t tmp;
-
- ext_bytes = insn->is_datasize;
- if (ext_bytes < 0)
- return (0);
-
- if (ext_bytes <= 2) {
- if (copyin((void *)(insn->is_pc + insn->is_advance), &tmp,
- sizeof(tmp)) != 0) {
- return SIGSEGV;
- }
- if (ext_bytes == 1) {
- /* sign-extend byte to long */
- data = (char)tmp;
- } else {
- /* sign-extend word to long */
- data = (int)tmp;
- }
- insn->is_advance += 2;
- dst[0] = data;
- return (0);
- }
-
- /* if (ext_bytes > 2) { */
- if (copyin((void *)(insn->is_pc + insn->is_advance), &dst[0],
- sizeof(dst[0])) != 0) {
- return SIGSEGV;
- }
- insn->is_advance += 4;
- /* } */
-
- if (ext_bytes > 4) {
- if (copyin((void *)(insn->is_pc + insn->is_advance), &dst[1],
- sizeof(dst[1])) != 0) {
- return SIGSEGV;
- }
- insn->is_advance += 4;
- }
-
- if (ext_bytes > 8) {
- if (copyin((void *)(insn->is_pc + insn->is_advance), &dst[2],
- sizeof(dst[2])) != 0) {
- return SIGSEGV;
- }
- insn->is_advance += 4;
- }
-
- return 0;
-}
-
-/*
- * fetch_disp: fetch displacement in full extension words
- */
-int
-fetch_disp(frame, insn, size, res)
- struct frame *frame;
- struct instruction *insn;
- int size, *res;
-{
- int disp;
- u_int16_t word;
-
- switch (size) {
- case 1:
- if (copyin((void *)(insn->is_pc + insn->is_advance), &word,
- sizeof(word)) != 0) {
- return SIGSEGV;
- }
- /* sign-extend */
- disp = (int)word;
- insn->is_advance += 2;
- break;
- case 2:
- if (copyin((void *)(insn->is_pc + insn->is_advance), &disp,
- sizeof(disp)) != 0) {
- return SIGSEGV;
- }
- insn->is_advance += 4;
- break;
- default:
- disp = 0;
- break;
- }
-
- *res = disp;
-
- return 0;
-}
-
-/*
- * Calculates an effective address for all address modes except for
- * register direct, absolute, and immediate modes. However, it does
- * not take care of predecrement/postincrement of register content.
- * Returns a signal value (0 == no error).
- */
-int
-calc_ea(ea, ptr, eaddr)
- struct insn_ea *ea;
- char *ptr; /* base address (usually a register content) */
- char **eaddr; /* pointer to result pointer */
-{
- int word;
-
-#if DEBUG_FPE
- printf("calc_ea: reg indirect (reg) = %p\n", ptr);
-#endif
-
- if (ea->ea_flags & EA_OFFSET) {
- /* apply the signed offset */
-#if DEBUG_FPE
- printf("calc_ea: offset %d\n", ea->ea_offset);
-#endif
- ptr += ea->ea_offset;
- } else if (ea->ea_flags & EA_INDEXED) {
-#if DEBUG_FPE
- printf("calc_ea: indexed mode\n");
-#endif
-
- if (ea->ea_flags & EA_BASE_SUPPRSS) {
- /* base register is suppressed */
- ptr = (char *)ea->ea_basedisp;
- } else {
- ptr += ea->ea_basedisp;
- }
-
- if (ea->ea_flags & EA_MEM_INDIR) {
-#if DEBUG_FPE
- printf("calc_ea: mem indir mode: basedisp=%08x, outerdisp=%08x\n",
- ea->ea_basedisp, ea->ea_outerdisp);
- printf("calc_ea: addr fetched from %p\n", ptr);
-#endif
- /* memory indirect modes */
- if (copyin(ptr, &word, sizeof(word)) != 0) {
- return SIGSEGV;
- }
-#if DEBUG_FPE
- printf("calc_ea: fetched ptr 0x%08x\n", word);
-#endif
- ptr = (char *)word + ea->ea_outerdisp;
- }
- }
-
- *eaddr = ptr;
-
- return 0;
-}
diff --git a/sys/arch/m68k/fpe/fpu_div.c b/sys/arch/m68k/fpe/fpu_div.c
deleted file mode 100644
index f01ff07ed6d..00000000000
--- a/sys/arch/m68k/fpe/fpu_div.c
+++ /dev/null
@@ -1,263 +0,0 @@
-/* $OpenBSD: fpu_div.c,v 1.5 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_div.c,v 1.4 2003/08/07 16:28:11 agc Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- * @(#)fpu_div.c 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Perform an FPU divide (return x / y).
- */
-
-#include <sys/types.h>
-
-#include <machine/reg.h>
-
-#include <m68k/fpe/fpu_arith.h>
-#include <m68k/fpe/fpu_emulate.h>
-
-/*
- * Division of normal numbers is done as follows:
- *
- * x and y are floating point numbers, i.e., in the form 1.bbbb * 2^e.
- * If X and Y are the mantissas (1.bbbb's), the quotient is then:
- *
- * q = (X / Y) * 2^((x exponent) - (y exponent))
- *
- * Since X and Y are both in [1.0,2.0), the quotient's mantissa (X / Y)
- * will be in [0.5,2.0). Moreover, it will be less than 1.0 if and only
- * if X < Y. In that case, it will have to be shifted left one bit to
- * become a normal number, and the exponent decremented. Thus, the
- * desired exponent is:
- *
- * left_shift = x->fp_mant < y->fp_mant;
- * result_exp = x->fp_exp - y->fp_exp - left_shift;
- *
- * The quotient mantissa X/Y can then be computed one bit at a time
- * using the following algorithm:
- *
- * Q = 0; -- Initial quotient.
- * R = X; -- Initial remainder,
- * if (left_shift) -- but fixed up in advance.
- * R *= 2;
- * for (bit = FP_NMANT; --bit >= 0; R *= 2) {
- * if (R >= Y) {
- * Q |= 1 << bit;
- * R -= Y;
- * }
- * }
- *
- * The subtraction R -= Y always removes the uppermost bit from R (and
- * can sometimes remove additional lower-order 1 bits); this proof is
- * left to the reader.
- *
- * This loop correctly calculates the guard and round bits since they are
- * included in the expanded internal representation. The sticky bit
- * is to be set if and only if any other bits beyond guard and round
- * would be set. From the above it is obvious that this is true if and
- * only if the remainder R is nonzero when the loop terminates.
- *
- * Examining the loop above, we can see that the quotient Q is built
- * one bit at a time ``from the top down''. This means that we can
- * dispense with the multi-word arithmetic and just build it one word
- * at a time, writing each result word when it is done.
- *
- * Furthermore, since X and Y are both in [1.0,2.0), we know that,
- * initially, R >= Y. (Recall that, if X < Y, R is set to X * 2 and
- * is therefore at in [2.0,4.0).) Thus Q is sure to have bit FP_NMANT-1
- * set, and R can be set initially to either X - Y (when X >= Y) or
- * 2X - Y (when X < Y). In addition, comparing R and Y is difficult,
- * so we will simply calculate R - Y and see if that underflows.
- * This leads to the following revised version of the algorithm:
- *
- * R = X;
- * bit = FP_1;
- * D = R - Y;
- * if (D >= 0) {
- * result_exp = x->fp_exp - y->fp_exp;
- * R = D;
- * q = bit;
- * bit >>= 1;
- * } else {
- * result_exp = x->fp_exp - y->fp_exp - 1;
- * q = 0;
- * }
- * R <<= 1;
- * do {
- * D = R - Y;
- * if (D >= 0) {
- * q |= bit;
- * R = D;
- * }
- * R <<= 1;
- * } while ((bit >>= 1) != 0);
- * Q[0] = q;
- * for (i = 1; i < 4; i++) {
- * q = 0, bit = 1 << 31;
- * do {
- * D = R - Y;
- * if (D >= 0) {
- * q |= bit;
- * R = D;
- * }
- * R <<= 1;
- * } while ((bit >>= 1) != 0);
- * Q[i] = q;
- * }
- *
- * This can be refined just a bit further by moving the `R <<= 1'
- * calculations to the front of the do-loops and eliding the first one.
- * The process can be terminated immediately whenever R becomes 0, but
- * this is relatively rare, and we do not bother.
- */
-
-struct fpn *
-fpu_div(fe)
- struct fpemu *fe;
-{
- struct fpn *x = &fe->fe_f1, *y = &fe->fe_f2;
- u_int q, bit;
- u_int r0, r1, r2, d0, d1, d2, y0, y1, y2;
- FPU_DECL_CARRY
-
- fe->fe_fpsr &= ~FPSR_EXCP; /* clear all exceptions */
-
- /*
- * Since divide is not commutative, we cannot just use ORDER.
- * Check either operand for NaN first; if there is at least one,
- * order the signalling one (if only one) onto the right, then
- * return it. Otherwise we have the following cases:
- *
- * Inf / Inf = NaN, plus NV exception
- * Inf / num = Inf [i.e., return x]
- * Inf / 0 = Inf [i.e., return x]
- * 0 / Inf = 0 [i.e., return x]
- * 0 / num = 0 [i.e., return x]
- * 0 / 0 = NaN, plus NV exception
- * num / Inf = 0
- * num / num = num (do the divide)
- * num / 0 = Inf, plus DZ exception
- */
- if (ISNAN(x) || ISNAN(y)) {
- ORDER(x, y);
- return (y);
- }
- if (ISINF(x) || ISZERO(x)) {
- if (x->fp_class == y->fp_class)
- return (fpu_newnan(fe));
- return (x);
- }
-
- /* all results at this point use XOR of operand signs */
- x->fp_sign ^= y->fp_sign;
- if (ISINF(y)) {
- x->fp_class = FPC_ZERO;
- return (x);
- }
- if (ISZERO(y)) {
- fe->fe_fpsr |= FPSR_DZ;
- x->fp_class = FPC_INF;
- return (x);
- }
-
- /*
- * Macros for the divide. See comments at top for algorithm.
- * Note that we expand R, D, and Y here.
- */
-
-#define SUBTRACT /* D = R - Y */ \
- FPU_SUBS(d2, r2, y2); \
- FPU_SUBCS(d1, r1, y1); FPU_SUBC(d0, r0, y0)
-
-#define NONNEGATIVE /* D >= 0 */ \
- ((int)d0 >= 0)
-
-#ifdef FPU_SHL1_BY_ADD
-#define SHL1 /* R <<= 1 */ \
- FPU_ADDS(r2, r2, r2); \
- FPU_ADDCS(r1, r1, r1); FPU_ADDC(r0, r0, r0)
-#else
-#define SHL1 \
- r0 = (r0 << 1) | (r1 >> 31), r1 = (r1 << 1) | (r2 >> 31), \
- r2 <<= 1
-#endif
-
-#define LOOP /* do ... while (bit >>= 1) */ \
- do { \
- SHL1; \
- SUBTRACT; \
- if (NONNEGATIVE) { \
- q |= bit; \
- r0 = d0, r1 = d1, r2 = d2; \
- } \
- } while ((bit >>= 1) != 0)
-
-#define WORD(r, i) /* calculate r->fp_mant[i] */ \
- q = 0; \
- bit = 1 << 31; \
- LOOP; \
- (x)->fp_mant[i] = q
-
- /* Setup. Note that we put our result in x. */
- r0 = x->fp_mant[0];
- r1 = x->fp_mant[1];
- r2 = x->fp_mant[2];
- y0 = y->fp_mant[0];
- y1 = y->fp_mant[1];
- y2 = y->fp_mant[2];
-
- bit = FP_1;
- SUBTRACT;
- if (NONNEGATIVE) {
- x->fp_exp -= y->fp_exp;
- r0 = d0, r1 = d1, r2 = d2;
- q = bit;
- bit >>= 1;
- } else {
- x->fp_exp -= y->fp_exp + 1;
- q = 0;
- }
- LOOP;
- x->fp_mant[0] = q;
- WORD(x, 1);
- WORD(x, 2);
- x->fp_sticky = r0 | r1 | r2;
-
- return (x);
-}
diff --git a/sys/arch/m68k/fpe/fpu_emulate.c b/sys/arch/m68k/fpe/fpu_emulate.c
deleted file mode 100644
index daa89da2539..00000000000
--- a/sys/arch/m68k/fpe/fpu_emulate.c
+++ /dev/null
@@ -1,1166 +0,0 @@
-/* $OpenBSD: fpu_emulate.c,v 1.16 2010/07/20 20:47:17 miod Exp $ */
-/* $NetBSD: fpu_emulate.c,v 1.25 2003/09/22 14:18:34 cl Exp $ */
-
-/*
- * Copyright (c) 1995 Gordon W. Ross
- * some portion Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- * 4. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Gordon Ross
- *
- * 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.
- */
-
-/*
- * mc68881 emulator
- * XXX - Just a start at it for now...
- */
-
-#include <sys/types.h>
-#include <sys/signal.h>
-#include <sys/systm.h>
-#include <machine/frame.h>
-
-#if defined(DDB) && defined(DEBUG_FPE)
-#include <machine/db_machdep.h>
-#endif
-
-#include <m68k/fpe/fpu_emulate.h>
-
-int fpu_emul_fmovmcr(struct fpemu *fe, struct instruction *insn, int *);
-int fpu_emul_fmovm(struct fpemu *fe, struct instruction *insn, int *);
-int fpu_emul_arith(struct fpemu *fe, struct instruction *insn, int *);
-int fpu_emul_type1(struct fpemu *fe, struct instruction *insn, int *);
-int fpu_emul_brcc(struct fpemu *fe, struct instruction *insn);
-int test_cc(struct fpemu *fe, int pred);
-struct fpn *fpu_cmp(struct fpemu *fe);
-
-#if DEBUG_FPE
-# define DUMP_INSN(insn) \
- printf("fpu_emulate: insn={adv=%d,siz=%d,op=%04x,w1=%04x}\n", \
- (insn)->is_advance, (insn)->is_datasize, \
- (insn)->is_opcode, (insn)->is_word1)
-#else
-# define DUMP_INSN(insn)
-#endif
-
-/*
- * Emulate a floating-point instruction.
- * Return zero for success, else signal number.
- * (Typically: zero, SIGFPE, SIGILL, SIGSEGV)
- */
-int
-fpu_emulate(struct frame *frame, struct fpframe *fpf, int *typ)
-{
- static struct instruction insn;
- static struct fpemu fe;
- int optype, sig;
- u_int16_t word;
-
-
- /* initialize insn.is_datasize to tell it is *not* initialized */
- insn.is_datasize = -1;
-
- fe.fe_frame = frame;
- fe.fe_fpframe = fpf;
- fe.fe_fpsr = fpf->fpf_fpsr;
- fe.fe_fpcr = fpf->fpf_fpcr;
-
-#if DEBUG_FPE
- printf("ENTERING fpu_emulate: FPSR=%08x, FPCR=%08x\n",
- fe.fe_fpsr, fe.fe_fpcr);
-#endif
-
- /* always set this (to avoid a warning) */
- insn.is_pc = frame->f_pc;
- insn.is_nextpc = 0;
- 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.
- * XXX TODO: This may not be true, so we might want to save the PC
- * in order to restore it later.
- */
- /* insn.is_nextpc = frame->f_pc; */
- insn.is_pc = frame->f_fmt4.f_fslw;
- frame->f_pc = insn.is_pc;
- }
-
- if (copyin((void *)insn.is_pc, &word, sizeof(word)) != 0) {
-#ifdef DEBUG
- printf("fpu_emulate: fault reading opcode\n");
-#endif
- return (SIGSEGV);
- }
-
- if ((word & 0xf000) != 0xf000) {
-#ifdef DEBUG
- printf("fpu_emulate: not coproc. insn.: opcode=0x%x\n", word);
-#endif
- return (SIGILL);
- }
-
- if ((word & 0x0E00) != 0x0200) {
-#ifdef DEBUG
- printf("fpu_emulate: bad coproc. id: opcode=0x%x\n", word);
-#endif
- *typ = ILL_COPROC;
- return (SIGILL);
- }
-
- insn.is_opcode = word;
- optype = (word & 0x01C0);
-
- if (copyin((void *)(insn.is_pc + 2), &word, sizeof(word)) != 0) {
-#ifdef DEBUG
- printf("fpu_emulate: fault reading word1\n");
-#endif
- return (SIGSEGV);
- }
- insn.is_word1 = word;
- /* all FPU instructions are at least 4-byte long */
- insn.is_advance = 4;
-
- DUMP_INSN(&insn);
-
- /*
- * Which family (or type) of opcode is it?
- * Tests ordered by likelihood (hopefully).
- * Certainly, type 0 is the most common.
- */
- if (optype == 0x0000) {
- /* type=0: generic */
- if ((word & 0xc000) == 0xc000) {
-#if DEBUG_FPE
- printf("fpu_emulate: fmovm FPr\n");
-#endif
- sig = fpu_emul_fmovm(&fe, &insn, typ);
- } else if ((word & 0xc000) == 0x8000) {
-#if DEBUG_FPE
- printf("fpu_emulate: fmovm FPcr\n");
-#endif
- sig = fpu_emul_fmovmcr(&fe, &insn, typ);
- } else if ((word & 0xe000) == 0x6000) {
- /* fstore = fmove FPn,mem */
-#if DEBUG_FPE
- printf("fpu_emulate: fmove to mem\n");
-#endif
- sig = fpu_emul_fstore(&fe, &insn, typ);
- } else if ((word & 0xfc00) == 0x5c00) {
- /* fmovecr */
-#if DEBUG_FPE
- printf("fpu_emulate: fmovecr\n");
-#endif
- sig = fpu_emul_fmovecr(&fe, &insn, typ);
- } else if ((word & 0xa07f) == 0x26) {
- /* fscale */
-#if DEBUG_FPE
- printf("fpu_emulate: fscale\n");
-#endif
- sig = fpu_emul_fscale(&fe, &insn, typ);
- } else {
-#if DEBUG_FPE
- printf("fpu_emulate: other type0\n");
-#endif
- /* all other type0 insns are arithmetic */
- sig = fpu_emul_arith(&fe, &insn, typ);
- }
- if (sig == 0) {
-#if DEBUG_FPE
- printf("fpu_emulate: type 0 returned 0\n");
-#endif
- sig = fpu_upd_excp(&fe);
- }
- } else if (optype == 0x0080 || optype == 0x00C0) {
- /* type=2 or 3: fbcc, short or long disp. */
-#if DEBUG_FPE
- printf("fpu_emulate: fbcc %s\n",
- (optype & 0x40) ? "long" : "short");
-#endif
- sig = fpu_emul_brcc(&fe, &insn);
- } else if (optype == 0x0040) {
- /* type=1: fdbcc, fscc, ftrapcc */
-#if DEBUG_FPE
- printf("fpu_emulate: type1\n");
-#endif
- sig = fpu_emul_type1(&fe, &insn, typ);
- } else {
- /* type=4: fsave (privileged) */
- /* type=5: frestore (privileged) */
- /* type=6: reserved */
- /* type=7: reserved */
-#ifdef DEBUG
- printf("fpu_emulate: bad opcode type: opcode=0x%x\n", insn.is_opcode);
-#endif
- *typ = ILL_PRVOPC;
- sig = SIGILL;
- }
-
- DUMP_INSN(&insn);
-
- /*
- * XXX it is not clear to me, if we should progress the PC always,
- * for SIGFPE || 0, or only for 0; however, without SIGFPE, we
- * don't pass the signalling regression tests. -is
- */
- if ((sig == 0) || (sig == SIGFPE))
- frame->f_pc += insn.is_advance;
-#if defined(DDB) && defined(DEBUG_FPE)
- else {
- printf("fpu_emulate: sig=%d, opcode=%x, word1=%x\n",
- sig, insn.is_opcode, insn.is_word1);
- kdb_trap(-1, (db_regs_t *)frame);
- }
-#endif
-#if 0 /* XXX something is wrong */
- if (frame->f_format == 4) {
- /* XXX Restore PC -- 68{EC,LC}040 only */
- if (insn.is_nextpc)
- frame->f_pc = insn.is_nextpc;
- }
-#endif
-
-#if DEBUG_FPE
- printf("EXITING fpu_emulate: w/FPSR=%08x, FPCR=%08x\n",
- fe.fe_fpsr, fe.fe_fpcr);
-#endif
-
- if (*typ == 0)
- switch (sig) {
- case SIGSEGV:
- *typ = SEGV_MAPERR;
- break;
- case SIGILL:
- *typ = ILL_ILLOPC;
- break;
- case SIGFPE:
- *typ = FPE_FLTINV;
- break;
- }
- return (sig);
-}
-
-/* update accrued exception bits and see if there's an FP exception */
-int
-fpu_upd_excp(fe)
- struct fpemu *fe;
-{
- u_int fpsr;
- u_int fpcr;
-
- fpsr = fe->fe_fpsr;
- fpcr = fe->fe_fpcr;
- /* update fpsr accrued exception bits; each insn doesn't have to
- update this */
- if (fpsr & (FPSR_BSUN | FPSR_SNAN | FPSR_OPERR)) {
- fpsr |= FPSR_AIOP;
- }
- if (fpsr & FPSR_OVFL) {
- fpsr |= FPSR_AOVFL;
- }
- if ((fpsr & FPSR_UNFL) && (fpsr & FPSR_INEX2)) {
- fpsr |= FPSR_AUNFL;
- }
- if (fpsr & FPSR_DZ) {
- fpsr |= FPSR_ADZ;
- }
- if (fpsr & (FPSR_INEX1 | FPSR_INEX2 | FPSR_OVFL)) {
- fpsr |= FPSR_AINEX;
- }
-
- fe->fe_fpframe->fpf_fpsr = fe->fe_fpsr = fpsr;
-
- return (fpsr & fpcr & FPSR_EXCP) ? SIGFPE : 0;
-}
-
-/* update fpsr according to fp (= result of an fp op) */
-u_int
-fpu_upd_fpsr(fe, fp)
- struct fpemu *fe;
- struct fpn *fp;
-{
- u_int fpsr;
-
-#if DEBUG_FPE
- printf("fpu_upd_fpsr: previous fpsr=%08x\n", fe->fe_fpsr);
-#endif
- /* clear all condition code */
- fpsr = fe->fe_fpsr & ~FPSR_CCB;
-
-#if DEBUG_FPE
- printf("fpu_upd_fpsr: result is a ");
-#endif
- if (fp->fp_sign) {
-#if DEBUG_FPE
- printf("negative ");
-#endif
- fpsr |= FPSR_NEG;
-#if DEBUG_FPE
- } else {
- printf("positive ");
-#endif
- }
-
- switch (fp->fp_class) {
- case FPC_SNAN:
-#if DEBUG_FPE
- printf("signaling NAN\n");
-#endif
- fpsr |= (FPSR_NAN | FPSR_SNAN);
- break;
- case FPC_QNAN:
-#if DEBUG_FPE
- printf("quiet NAN\n");
-#endif
- fpsr |= FPSR_NAN;
- break;
- case FPC_ZERO:
-#if DEBUG_FPE
- printf("Zero\n");
-#endif
- fpsr |= FPSR_ZERO;
- break;
- case FPC_INF:
-#if DEBUG_FPE
- printf("Inf\n");
-#endif
- fpsr |= FPSR_INF;
- break;
- default:
-#if DEBUG_FPE
- printf("Number\n");
-#endif
- /* anything else is treated as if it is a number */
- break;
- }
-
- fe->fe_fpsr = fe->fe_fpframe->fpf_fpsr = fpsr;
-
-#if DEBUG_FPE
- printf("fpu_upd_fpsr: new fpsr=%08x\n", fe->fe_fpframe->fpf_fpsr);
-#endif
-
- return fpsr;
-}
-
-int
-fpu_emul_fmovmcr(struct fpemu *fe, struct instruction *insn, int *typ)
-{
- struct frame *frame = fe->fe_frame;
- struct fpframe *fpf = fe->fe_fpframe;
- int sig;
- int reglist;
- int fpu_to_mem;
-
- /* move to/from control registers */
- reglist = (insn->is_word1 & 0x1c00) >> 10;
- /* Bit 13 selects direction (FPU to/from Mem) */
- fpu_to_mem = insn->is_word1 & 0x2000;
-
- insn->is_datasize = 4;
- insn->is_advance = 4;
- sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ);
- if (sig) { return sig; }
-
- if (reglist != 1 && reglist != 2 && reglist != 4 &&
- (insn->is_ea.ea_flags & EA_DIRECT)) {
- /* attempted to copy more than one FPcr to CPU regs */
-#ifdef DEBUG
- printf("fpu_emul_fmovmcr: tried to copy too many FPcr\n");
-#endif
- return SIGILL;
- }
-
- if (reglist & 4) {
- /* fpcr */
- if ((insn->is_ea.ea_flags & EA_DIRECT) &&
- insn->is_ea.ea_regnum >= 8 /* address reg */) {
- /* attempted to copy FPCR to An */
-#ifdef DEBUG
- printf("fpu_emul_fmovmcr: tried to copy FPCR from/to A%d\n",
- insn->is_ea.ea_regnum & 7);
-#endif
- return SIGILL;
- }
- if (fpu_to_mem) {
- sig = fpu_store_ea(frame, insn, &insn->is_ea,
- (char *)&fpf->fpf_fpcr);
- } else {
- sig = fpu_load_ea(frame, insn, &insn->is_ea,
- (char *)&fpf->fpf_fpcr, typ);
- }
- }
- if (sig) { return sig; }
-
- if (reglist & 2) {
- /* fpsr */
- if ((insn->is_ea.ea_flags & EA_DIRECT) &&
- insn->is_ea.ea_regnum >= 8 /* address reg */) {
- /* attempted to copy FPSR to An */
-#ifdef DEBUG
- printf("fpu_emul_fmovmcr: tried to copy FPSR from/to A%d\n",
- insn->is_ea.ea_regnum & 7);
-#endif
- return SIGILL;
- }
- if (fpu_to_mem) {
- sig = fpu_store_ea(frame, insn, &insn->is_ea,
- (char *)&fpf->fpf_fpsr);
- } else {
- sig = fpu_load_ea(frame, insn, &insn->is_ea,
- (char *)&fpf->fpf_fpsr, typ);
- }
- }
- if (sig) { return sig; }
-
- if (reglist & 1) {
- /* fpiar - can be moved to/from An */
- if (fpu_to_mem) {
- sig = fpu_store_ea(frame, insn, &insn->is_ea,
- (char *)&fpf->fpf_fpiar);
- } else {
- sig = fpu_load_ea(frame, insn, &insn->is_ea,
- (char *)&fpf->fpf_fpiar, typ);
- }
- }
- return sig;
-}
-
-/*
- * type 0: fmovem
- * Separated out of fpu_emul_type0 for efficiency.
- * In this function, we know:
- * (opcode & 0x01C0) == 0
- * (word1 & 0x8000) == 0x8000
- *
- * No conversion or rounding is done by this instruction,
- * and the FPSR is not affected.
- */
-int
-fpu_emul_fmovm(struct fpemu *fe, struct instruction *insn, int *typ)
-{
- struct frame *frame = fe->fe_frame;
- struct fpframe *fpf = fe->fe_fpframe;
- int word1, sig;
- int reglist, regmask, regnum;
- int fpu_to_mem, order;
- int w1_post_incr;
- int *fpregs;
-
- insn->is_advance = 4;
- insn->is_datasize = 12;
- word1 = insn->is_word1;
-
- /* Bit 13 selects direction (FPU to/from Mem) */
- fpu_to_mem = word1 & 0x2000;
-
- /*
- * Bits 12,11 select register list mode:
- * 0,0: Static reg list, pre-decr.
- * 0,1: Dynamic reg list, pre-decr.
- * 1,0: Static reg list, post-incr.
- * 1,1: Dynamic reg list, post-incr
- */
- w1_post_incr = word1 & 0x1000;
- if (word1 & 0x0800) {
- /* dynamic reg list */
- reglist = frame->f_regs[(word1 & 0x70) >> 4];
- } else {
- reglist = word1;
- }
- reglist &= 0xFF;
-
- /* Get effective address. (modreg=opcode&077) */
- sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ);
- if (sig) { return sig; }
-
- /* Get address of soft coprocessor regs. */
- fpregs = &fpf->fpf_regs[0];
-
- if (insn->is_ea.ea_flags & EA_PREDECR) {
- regnum = 7;
- order = -1;
- } else {
- regnum = 0;
- order = 1;
- }
-
- regmask = 0x80;
- while ((0 <= regnum) && (regnum < 8)) {
- if (regmask & reglist) {
- if (fpu_to_mem) {
- sig = fpu_store_ea(frame, insn, &insn->is_ea,
- (char *)&fpregs[regnum * 3]);
-#if DEBUG_FPE
- printf("fpu_emul_fmovm: FP%d (%08x,%08x,%08x) saved\n",
- regnum, fpregs[regnum * 3], fpregs[regnum * 3 + 1],
- fpregs[regnum * 3 + 2]);
-#endif
- } else { /* mem to fpu */
- sig = fpu_load_ea(frame, insn, &insn->is_ea,
- (char *)&fpregs[regnum * 3], typ);
-#if DEBUG_FPE
- printf("fpu_emul_fmovm: FP%d (%08x,%08x,%08x) loaded\n",
- regnum, fpregs[regnum * 3], fpregs[regnum * 3 + 1],
- fpregs[regnum * 3 + 2]);
-#endif
- }
- if (sig) { break; }
- }
- regnum += order;
- regmask >>= 1;
- }
-
- return sig;
-}
-
-struct fpn *
-fpu_cmp(fe)
- struct fpemu *fe;
-{
- struct fpn *x = &fe->fe_f1, *y = &fe->fe_f2;
-
- /* take care of special cases */
- if (x->fp_class < 0 || y->fp_class < 0) {
- /* if either of two is a SNAN, result is SNAN */
- x->fp_class = (y->fp_class < x->fp_class) ? y->fp_class : x->fp_class;
- } else if (x->fp_class == FPC_INF) {
- if (y->fp_class == FPC_INF) {
- /* both infinities */
- if (x->fp_sign == y->fp_sign) {
- x->fp_class = FPC_ZERO; /* return a signed zero */
- } else {
- x->fp_class = FPC_NUM; /* return a faked number w/x's sign */
- x->fp_exp = 16383;
- x->fp_mant[0] = FP_1;
- }
- } else {
- /* y is a number */
- x->fp_class = FPC_NUM; /* return a forged number w/x's sign */
- x->fp_exp = 16383;
- x->fp_mant[0] = FP_1;
- }
- } else if (y->fp_class == FPC_INF) {
- /* x is a Num but y is an Inf */
- /* return a forged number w/y's sign inverted */
- x->fp_class = FPC_NUM;
- x->fp_sign = !y->fp_sign;
- x->fp_exp = 16383;
- x->fp_mant[0] = FP_1;
- } else {
- /* x and y are both numbers or zeros, or pair of a number and a zero */
- y->fp_sign = !y->fp_sign;
- x = fpu_add(fe); /* (x - y) */
- /*
- * FCMP does not set Inf bit in CC, so return a forged number
- * (value doesn't matter) if Inf is the result of fsub.
- */
- if (x->fp_class == FPC_INF) {
- x->fp_class = FPC_NUM;
- x->fp_exp = 16383;
- x->fp_mant[0] = FP_1;
- }
- }
- return x;
-}
-
-/*
- * arithmetic operations
- */
-int
-fpu_emul_arith(struct fpemu *fe, struct instruction *insn, int *typ)
-{
- struct frame *frame = fe->fe_frame;
- u_int *fpregs = &(fe->fe_fpframe->fpf_regs[0]);
- struct fpn *res;
- int word1, sig = 0;
- int regnum, format;
- int discard_result = 0;
- u_int buf[3];
-#if DEBUG_FPE
- int flags;
- char regname;
-#endif
-
- fe->fe_fpsr &= ~FPSR_EXCP;
-
- DUMP_INSN(insn);
-
-#if DEBUG_FPE
- printf("fpu_emul_arith: FPSR = %08x, FPCR = %08x\n",
- fe->fe_fpsr, fe->fe_fpcr);
-#endif
-
- word1 = insn->is_word1;
- format = (word1 >> 10) & 7;
- regnum = (word1 >> 7) & 7;
-
- /* fetch a source operand : may not be used */
-#if DEBUG_FPE
- printf("fpu_emul_arith: dst/src FP%d=%08x,%08x,%08x\n",
- regnum, fpregs[regnum*3], fpregs[regnum*3+1],
- fpregs[regnum*3+2]);
-#endif
-
- fpu_explode(fe, &fe->fe_f1, FTYPE_EXT, &fpregs[regnum * 3]);
-
- DUMP_INSN(insn);
-
- /* get the other operand which is always the source */
- if ((word1 & 0x4000) == 0) {
-#if DEBUG_FPE
- printf("fpu_emul_arith: FP%d op FP%d => FP%d\n",
- format, regnum, regnum);
- printf("fpu_emul_arith: src opr FP%d=%08x,%08x,%08x\n",
- format, fpregs[format*3], fpregs[format*3+1],
- fpregs[format*3+2]);
-#endif
- fpu_explode(fe, &fe->fe_f2, FTYPE_EXT, &fpregs[format * 3]);
- } else {
- /* the operand is in memory */
- if (format == FTYPE_DBL) {
- insn->is_datasize = 8;
- } else if (format == FTYPE_SNG || format == FTYPE_LNG) {
- insn->is_datasize = 4;
- } else if (format == FTYPE_WRD) {
- insn->is_datasize = 2;
- } else if (format == FTYPE_BYT) {
- insn->is_datasize = 1;
- } else if (format == FTYPE_EXT) {
- insn->is_datasize = 12;
- } else {
- /* invalid or unsupported operand format */
- *typ = ILL_ILLOPN;
- sig = SIGILL;
- return sig;
- }
-
- /* Get effective address. (modreg=opcode&077) */
- sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ);
- if (sig) {
-#if DEBUG_FPE
- printf("fpu_emul_arith: error in fpu_decode_ea\n");
-#endif
- return sig;
- }
-
- DUMP_INSN(insn);
-
-#if DEBUG_FPE
- printf("fpu_emul_arith: addr mode = ");
- flags = insn->is_ea.ea_flags;
- regname = (insn->is_ea.ea_regnum & 8) ? 'a' : 'd';
-
- if (flags & EA_DIRECT) {
- printf("%c%d\n",
- regname, insn->is_ea.ea_regnum & 7);
- } else if (flags & EA_PC_REL) {
- if (flags & EA_OFFSET) {
- printf("pc@(%d)\n", insn->is_ea.ea_offset);
- } else if (flags & EA_INDEXED) {
- printf("pc@(...)\n");
- }
- } else if (flags & EA_PREDECR) {
- printf("%c%d@-\n",
- regname, insn->is_ea.ea_regnum & 7);
- } else if (flags & EA_POSTINCR) {
- printf("%c%d@+\n", regname, insn->is_ea.ea_regnum & 7);
- } else if (flags & EA_OFFSET) {
- printf("%c%d@(%d)\n", regname, insn->is_ea.ea_regnum & 7,
- insn->is_ea.ea_offset);
- } else if (flags & EA_INDEXED) {
- printf("%c%d@(...)\n", regname, insn->is_ea.ea_regnum & 7);
- } else if (flags & EA_ABS) {
- printf("0x%08x\n", insn->is_ea.ea_absaddr);
- } else if (flags & EA_IMMED) {
-
- printf("#0x%08x,%08x,%08x\n", insn->is_ea.ea_immed[0],
- insn->is_ea.ea_immed[1], insn->is_ea.ea_immed[2]);
- } else {
- printf("%c%d@\n", regname, insn->is_ea.ea_regnum & 7);
- }
-#endif /* DEBUG_FPE */
-
- fpu_load_ea(frame, insn, &insn->is_ea, (char *)buf, typ);
- if (format == FTYPE_WRD) {
- /* sign-extend */
- buf[0] &= 0xffff;
- if (buf[0] & 0x8000) {
- buf[0] |= 0xffff0000;
- }
- format = FTYPE_LNG;
- } else if (format == FTYPE_BYT) {
- /* sign-extend */
- buf[0] &= 0xff;
- if (buf[0] & 0x80) {
- buf[0] |= 0xffffff00;
- }
- format = FTYPE_LNG;
- }
-#if DEBUG_FPE
- printf("fpu_emul_arith: src = %08x %08x %08x, siz = %d\n",
- buf[0], buf[1], buf[2], insn->is_datasize);
-#endif
- fpu_explode(fe, &fe->fe_f2, format, buf);
- }
-
- DUMP_INSN(insn);
-
- /* An arithmetic instruction emulate function has a prototype of
- * struct fpn *fpu_op(struct fpemu *);
-
- * 1) If the instruction is monadic, then fpu_op() must use
- * fe->fe_f2 as its operand, and return a pointer to the
- * result.
-
- * 2) If the instruction is diadic, then fpu_op() must use
- * fe->fe_f1 and fe->fe_f2 as its two operands, and return a
- * pointer to the result.
-
- */
- res = 0;
- switch (word1 & 0x3f) {
- case 0x00: /* fmove */
- res = &fe->fe_f2;
- break;
-
- case 0x01: /* fint */
- res = fpu_int(fe);
- break;
-
- case 0x03: /* fintrz */
- res = fpu_intrz(fe);
- break;
-
- case 0x04: /* fsqrt */
- res = fpu_sqrt(fe);
- break;
-
- case 0x06: /* flognp1 */
- res = fpu_lognp1(fe);
- break;
-
- case 0x14: /* flogn */
- res = fpu_logn(fe);
- break;
-
- case 0x15: /* flog10 */
- res = fpu_log10(fe);
- break;
-
- case 0x16: /* flog2 */
- res = fpu_log2(fe);
- break;
-
- case 0x18: /* fabs */
- fe->fe_f2.fp_sign = 0;
- res = &fe->fe_f2;
- break;
-
- case 0x1A: /* fneg */
- fe->fe_f2.fp_sign = !fe->fe_f2.fp_sign;
- res = &fe->fe_f2;
- break;
-
- case 0x1E: /* fgetexp */
- res = fpu_getexp(fe);
- break;
-
- case 0x1F: /* fgetman */
- res = fpu_getman(fe);
- break;
-
- case 0x20: /* fdiv */
- case 0x24: /* fsgldiv: cheating - better than nothing */
- res = fpu_div(fe);
- break;
-
- case 0x21: /* fmod */
- res = fpu_mod(fe);
- break;
-
- case 0x28: /* fsub */
- fe->fe_f2.fp_sign = !fe->fe_f2.fp_sign; /* f2 = -f2 */
- case 0x22: /* fadd */
- res = fpu_add(fe);
- break;
-
- case 0x23: /* fmul */
- case 0x27: /* fsglmul: cheating - better than nothing */
- res = fpu_mul(fe);
- break;
-
- case 0x25: /* frem */
- res = fpu_rem(fe);
- break;
-
- case 0x26:
- /* fscale is handled by a separate function */
- break;
-
- case 0x38: /* fcmp */
- res = fpu_cmp(fe);
- discard_result = 1;
- break;
-
- case 0x3A: /* ftst */
- res = &fe->fe_f2;
- discard_result = 1;
- break;
-
- case 0x02: /* fsinh */
- case 0x08: /* fetoxm1 */
- case 0x09: /* ftanh */
- case 0x0A: /* fatan */
- case 0x0C: /* fasin */
- case 0x0D: /* fatanh */
- case 0x0E: /* fsin */
- case 0x0F: /* ftan */
- case 0x10: /* fetox */
- case 0x11: /* ftwotox */
- case 0x12: /* ftentox */
- case 0x19: /* fcosh */
- case 0x1C: /* facos */
- case 0x1D: /* fcos */
- case 0x30: /* fsincos */
- case 0x31: /* fsincos */
- case 0x32: /* fsincos */
- case 0x33: /* fsincos */
- case 0x34: /* fsincos */
- case 0x35: /* fsincos */
- case 0x36: /* fsincos */
- case 0x37: /* fsincos */
- default:
-#ifdef DEBUG
- printf("fpu_emul_arith: bad opcode=0x%x, word1=0x%x\n",
- insn->is_opcode, insn->is_word1);
-#endif
- sig = SIGILL;
- } /* switch (word1 & 0x3f) */
-
- if (!discard_result && sig == 0) {
- fpu_implode(fe, res, FTYPE_EXT, &fpregs[regnum * 3]);
-#if DEBUG_FPE
- printf("fpu_emul_arith: %08x,%08x,%08x stored in FP%d\n",
- fpregs[regnum*3], fpregs[regnum*3+1],
- fpregs[regnum*3+2], regnum);
- } else if (sig == 0) {
- static char *class_name[] = { "SNAN", "QNAN", "ZERO", "NUM", "INF" };
- printf("fpu_emul_arith: result(%s,%c,%d,%08x,%08x,%08x) discarded\n",
- class_name[res->fp_class + 2],
- res->fp_sign ? '-' : '+', res->fp_exp,
- res->fp_mant[0], res->fp_mant[1],
- res->fp_mant[2]);
- } else {
- printf("fpu_emul_arith: received signal %d\n", sig);
-#endif
- }
-
- /* update fpsr according to the result of operation */
- fpu_upd_fpsr(fe, res);
-
-#if DEBUG_FPE
- printf("fpu_emul_arith: FPSR = %08x, FPCR = %08x\n",
- fe->fe_fpsr, fe->fe_fpcr);
-#endif
-
- DUMP_INSN(insn);
-
- return sig;
-}
-
-/* test condition code according to the predicate in the opcode.
- * returns -1 when the predicate evaluates to true, 0 when false.
- * signal numbers are returned when an error is detected.
- */
-int
-test_cc(fe, pred)
- struct fpemu *fe;
- int pred;
-{
- int result, sig_bsun, invert;
- int fpsr;
-
- fpsr = fe->fe_fpsr;
- invert = 0;
- fpsr &= ~FPSR_EXCP; /* clear all exceptions */
-#if DEBUG_FPE
- printf("test_cc: fpsr=0x%08x\n", fpsr);
-#endif
- pred &= 0x3f; /* lowest 6 bits */
-
-#if DEBUG_FPE
- printf("test_cc: ");
-#endif
-
- if (pred >= 0x20) {
- return SIGILL;
- } else if (pred & 0x10) {
- /* IEEE nonaware tests */
- sig_bsun = 1;
- pred &= 0x0f; /* lower 4 bits */
- } else {
- /* IEEE aware tests */
-#if DEBUG_FPE
- printf("IEEE ");
-#endif
- sig_bsun = 0;
- }
-
- if (pred & 0x08) {
-#if DEBUG_FPE
- printf("Not ");
-#endif
- /* predicate is "NOT ..." */
- pred ^= 0xf; /* invert */
- invert = -1;
- }
- switch (pred) {
- case 0: /* (Signaling) False */
-#if DEBUG_FPE
- printf("False");
-#endif
- result = 0;
- break;
- case 1: /* (Signaling) Equal */
-#if DEBUG_FPE
- printf("Equal");
-#endif
- result = -((fpsr & FPSR_ZERO) == FPSR_ZERO);
- break;
- case 2: /* Greater Than */
-#if DEBUG_FPE
- printf("GT");
-#endif
- result = -((fpsr & (FPSR_NAN|FPSR_ZERO|FPSR_NEG)) == 0);
- break;
- case 3: /* Greater or Equal */
-#if DEBUG_FPE
- printf("GE");
-#endif
- result = -((fpsr & FPSR_ZERO) ||
- (fpsr & (FPSR_NAN|FPSR_NEG)) == 0);
- break;
- case 4: /* Less Than */
-#if DEBUG_FPE
- printf("LT");
-#endif
- result = -((fpsr & (FPSR_NAN|FPSR_ZERO|FPSR_NEG)) == FPSR_NEG);
- break;
- case 5: /* Less or Equal */
-#if DEBUG_FPE
- printf("LE");
-#endif
- result = -((fpsr & FPSR_ZERO) ||
- ((fpsr & (FPSR_NAN|FPSR_NEG)) == FPSR_NEG));
- break;
- case 6: /* Greater or Less than */
-#if DEBUG_FPE
- printf("GLT");
-#endif
- result = -((fpsr & (FPSR_NAN|FPSR_ZERO)) == 0);
- break;
- case 7: /* Greater, Less or Equal */
-#if DEBUG_FPE
- printf("GLE");
-#endif
- result = -((fpsr & FPSR_NAN) == 0);
- break;
- default:
- /* invalid predicate */
- return SIGILL;
- }
- result ^= invert; /* if the predicate is "NOT ...", then
- invert the result */
-#if DEBUG_FPE
- printf("=> %s (%d)\n", result ? "true" : "false", result);
-#endif
- /* if it's an IEEE unaware test and NAN is set, BSUN is set */
- if (sig_bsun && (fpsr & FPSR_NAN)) {
- fpsr |= FPSR_BSUN;
- }
-
- /* put fpsr back */
- fe->fe_fpframe->fpf_fpsr = fe->fe_fpsr = fpsr;
-
- return result;
-}
-
-/*
- * type 1: fdbcc, fscc, ftrapcc
- * In this function, we know:
- * (opcode & 0x01C0) == 0x0040
- */
-int
-fpu_emul_type1(struct fpemu *fe, struct instruction *insn, int *typ)
-{
- struct frame *frame = fe->fe_frame;
- int advance, sig, branch;
- int16_t displ;
-
- branch = test_cc(fe, insn->is_word1);
- fe->fe_fpframe->fpf_fpsr = fe->fe_fpsr;
-
- insn->is_advance = 4;
- sig = 0;
-
- switch (insn->is_opcode & 070) {
- case 010: /* fdbcc */
- if (branch == -1) {
- /* advance */
- insn->is_advance = 6;
- } else if (!branch) {
- /* decrement Dn and if (Dn != -1) branch */
- u_int16_t count = frame->f_regs[insn->is_opcode & 7];
-
- if (count-- != 0) {
- if (copyin((void *)(insn->is_pc + insn->is_advance), &displ,
- sizeof(displ)) != 0) {
-#ifdef DEBUG
- printf("fpu_emul_type1: fault reading displacement\n");
-#endif
- return SIGSEGV;
- }
- insn->is_advance += (int)displ;
- /* XXX insn->is_nextpc = insn->is_pc + insn->is_advance; */
- } else {
- insn->is_advance = 6;
- }
- /* write it back */
- frame->f_regs[insn->is_opcode & 7] &= 0xffff0000;
- frame->f_regs[insn->is_opcode & 7] |= (u_int32_t)count;
- } else { /* got a signal */
- sig = SIGFPE;
- }
- break;
-
- case 070: /* ftrapcc or fscc */
- advance = 4;
- if ((insn->is_opcode & 07) >= 2) {
- switch (insn->is_opcode & 07) {
- case 3: /* long opr */
- advance += 2;
- case 2: /* word opr */
- advance += 2;
- case 4: /* no opr */
- break;
- default:
- return SIGILL;
- break;
- }
-
- if (branch == 0) {
- /* no trap */
- insn->is_advance = advance;
- sig = 0;
- } else {
- /* trap */
- sig = SIGILL;
- *typ = ILL_ILLTRP;
- }
- break;
- } /* if ((insn->is_opcode & 7) < 2), fall through to FScc */
-
- default: /* fscc */
- insn->is_advance = 4;
- insn->is_datasize = 1; /* always byte */
- sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ);
- if (sig) {
- break;
- }
- if (branch == -1 || branch == 0) {
- /* set result */
- sig = fpu_store_ea(frame, insn, &insn->is_ea, (char *)&branch);
- } else {
- /* got an exception */
- sig = branch;
- }
- break;
- }
- return sig;
-}
-
-/*
- * Type 2 or 3: fbcc (also fnop)
- * In this function, we know:
- * (opcode & 0x0180) == 0x0080
- */
-int
-fpu_emul_brcc(fe, insn)
- struct fpemu *fe;
- struct instruction *insn;
-{
- int displ;
- int sig;
- u_int16_t word2;
-
- /*
- * Get branch displacement.
- */
- insn->is_advance = 4;
- displ = insn->is_word1;
-
- if (insn->is_opcode & 0x40) {
- if (copyin((void *)(insn->is_pc + insn->is_advance), &word2,
- sizeof(word2)) != 0) {
-#ifdef DEBUG
- printf("fpu_emul_brcc: fault reading word2\n");
-#endif
- return SIGSEGV;
- }
- displ <<= 16;
- displ |= word2;
- insn->is_advance += 2;
- } else /* displacement is word sized */
- if (displ & 0x8000)
- displ |= 0xFFFF0000;
-
- /* XXX: If CC, insn->is_pc += displ */
- sig = test_cc(fe, insn->is_opcode);
- fe->fe_fpframe->fpf_fpsr = fe->fe_fpsr;
-
- if (fe->fe_fpsr & fe->fe_fpcr & FPSR_EXCP) {
- return SIGFPE; /* caught an exception */
- }
- if (sig == -1) {
- /* branch does take place; 2 is the offset to the 1st disp word */
- insn->is_advance = displ + 2;
- /* XXX insn->is_nextpc = insn->is_pc + insn->is_advance; */
- } else if (sig) {
- return SIGILL; /* got a signal */
- }
-#if DEBUG_FPE
- printf("fpu_emul_brcc: %s insn @ %x (%x+%x) (disp=%x)\n",
- (sig == -1) ? "BRANCH to" : "NEXT",
- insn->is_pc + insn->is_advance, insn->is_pc, insn->is_advance,
- displ);
-#endif
- return 0;
-}
diff --git a/sys/arch/m68k/fpe/fpu_emulate.h b/sys/arch/m68k/fpe/fpu_emulate.h
deleted file mode 100644
index 6b99db93304..00000000000
--- a/sys/arch/m68k/fpe/fpu_emulate.h
+++ /dev/null
@@ -1,319 +0,0 @@
-/* $OpenBSD: fpu_emulate.h,v 1.7 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_emulate.h,v 1.11 2005/08/13 05:38:45 he Exp $ */
-
-/*
- * Copyright (c) 1995 Gordon Ross
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- * 4. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Gordon Ross
- *
- * 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.
- */
-
-#ifndef _FPU_EMULATE_H_
-#define _FPU_EMULATE_H_
-
-#include <sys/types.h>
-
-/*
- * Floating point emulator (tailored for SPARC/modified for m68k, but
- * structurally machine-independent).
- *
- * Floating point numbers are carried around internally in an `expanded'
- * or `unpacked' form consisting of:
- * - sign
- * - unbiased exponent
- * - mantissa (`1.' + 80-bit fraction + guard + round)
- * - sticky bit
- * Any implied `1' bit is inserted, giving a 81-bit mantissa that is
- * always nonzero. Additional low-order `guard' and `round' bits are
- * scrunched in, making the entire mantissa 83 bits long. This is divided
- * into three 32-bit words, with `spare' bits left over in the upper part
- * of the top word (the high bits of fp_mant[0]). An internal `exploded'
- * number is thus kept within the half-open interval [1.0,2.0) (but see
- * the `number classes' below). This holds even for denormalized numbers:
- * when we explode an external denorm, we normalize it, introducing low-order
- * zero bits, so that the rest of the code always sees normalized values.
- *
- * Note that a number of our algorithms use the `spare' bits at the top.
- * The most demanding algorithm---the one for sqrt---depends on two such
- * bits, so that it can represent values up to (but not including) 8.0,
- * and then it needs a carry on top of that, so that we need three `spares'.
- *
- * The sticky-word is 32 bits so that we can use `OR' operators to goosh
- * whole words from the mantissa into it.
- *
- * All operations are done in this internal extended precision. According
- * to Hennesey & Patterson, Appendix A, rounding can be repeated---that is,
- * it is OK to do a+b in extended precision and then round the result to
- * single precision---provided single, double, and extended precisions are
- * `far enough apart' (they always are), but we will try to avoid any such
- * extra work where possible.
- */
-struct fpn {
- int fp_class; /* see below */
- int fp_sign; /* 0 => positive, 1 => negative */
- int fp_exp; /* exponent (unbiased) */
- int fp_sticky; /* nonzero bits lost at right end */
- u_int fp_mant[3]; /* 83-bit mantissa */
-};
-
-#define FP_NMANT 83 /* total bits in mantissa (incl g,r) */
-#define FP_NG 2 /* number of low-order guard bits */
-#define FP_LG ((FP_NMANT - 1) & 31) /* log2(1.0) for fp_mant[0] */
-#define FP_QUIETBIT (1 << (FP_LG - 1)) /* Quiet bit in NaNs (0.5) */
-#define FP_1 (1 << FP_LG) /* 1.0 in fp_mant[0] */
-#define FP_2 (1 << (FP_LG + 1)) /* 2.0 in fp_mant[0] */
-
-#define CPYFPN(dst, src) \
-if ((dst) != (src)) { \
- (dst)->fp_class = (src)->fp_class; \
- (dst)->fp_sign = (src)->fp_sign; \
- (dst)->fp_exp = (src)->fp_exp; \
- (dst)->fp_sticky = (src)->fp_sticky; \
- (dst)->fp_mant[0] = (src)->fp_mant[0]; \
- (dst)->fp_mant[1] = (src)->fp_mant[1]; \
- (dst)->fp_mant[2] = (src)->fp_mant[2]; \
-}
-
-/*
- * Number classes. Since zero, Inf, and NaN cannot be represented using
- * the above layout, we distinguish these from other numbers via a class.
- */
-#define FPC_SNAN -2 /* signalling NaN (sign irrelevant) */
-#define FPC_QNAN -1 /* quiet NaN (sign irrelevant) */
-#define FPC_ZERO 0 /* zero (sign matters) */
-#define FPC_NUM 1 /* number (sign matters) */
-#define FPC_INF 2 /* infinity (sign matters) */
-
-#define ISNAN(fp) ((fp)->fp_class < 0)
-#define ISZERO(fp) ((fp)->fp_class == 0)
-#define ISINF(fp) ((fp)->fp_class == FPC_INF)
-
-/*
- * ORDER(x,y) `sorts' a pair of `fpn *'s so that the right operand (y) points
- * to the `more significant' operand for our purposes. Appendix N says that
- * the result of a computation involving two numbers are:
- *
- * If both are SNaN: operand 2, converted to Quiet
- * If only one is SNaN: the SNaN operand, converted to Quiet
- * If both are QNaN: operand 2
- * If only one is QNaN: the QNaN operand
- *
- * In addition, in operations with an Inf operand, the result is usually
- * Inf. The class numbers are carefully arranged so that if
- * (unsigned)class(op1) > (unsigned)class(op2)
- * then op1 is the one we want; otherwise op2 is the one we want.
- */
-#define ORDER(x, y) { \
- if ((u_int)(x)->fp_class > (u_int)(y)->fp_class) \
- SWAP(x, y); \
-}
-#define SWAP(x, y) { \
- struct fpn *swap; \
- swap = (x), (x) = (y), (y) = swap; \
-}
-
-/*
- * Emulator state.
- */
-struct fpemu {
- struct frame *fe_frame; /* integer regs, etc */
- struct fpframe *fe_fpframe; /* FP registers, etc */
- u_int fe_fpsr; /* fpsr copy (modified during op) */
- u_int fe_fpcr; /* fpcr copy */
- struct fpn fe_f1; /* operand 1 */
- struct fpn fe_f2; /* operand 2, if required */
- struct fpn fe_f3; /* available storage for result */
-};
-
-/*****************************************************************************
- * End of definitions derived from Sparc FPE
- *****************************************************************************/
-
-/*
- * Internal info about a decoded effective address.
- */
-struct insn_ea {
- int ea_regnum;
- int ea_ext[3]; /* extension words if any */
- int ea_flags; /* flags == 0 means mode 2: An@ */
-#define EA_DIRECT 0x001 /* mode [01]: Dn or An */
-#define EA_PREDECR 0x002 /* mode 4: An@- */
-#define EA_POSTINCR 0x004 /* mode 3: An@+ */
-#define EA_OFFSET 0x008 /* mode 5 or (7,2): APC@(d16) */
-#define EA_INDEXED 0x010 /* mode 6 or (7,3): APC@(Xn:*:*,d8) etc */
-#define EA_ABS 0x020 /* mode (7,[01]): abs */
-#define EA_PC_REL 0x040 /* mode (7,[23]): PC@(d16) etc */
-#define EA_IMMED 0x080 /* mode (7,4): #immed */
-#define EA_MEM_INDIR 0x100 /* mode 6 or (7,3): APC@(Xn:*:*,*)@(*) etc */
-#define EA_BASE_SUPPRSS 0x200 /* mode 6 or (7,3): base register suppressed */
-#define EA_FRAME_EA 0x400 /* MC68LC040 only: precalculated EA from
- format 4 stack frame */
- int ea_moffs; /* offset used for fmoveMulti */
-};
-
-#define ea_offset ea_ext[0] /* mode 5: offset word */
-#define ea_absaddr ea_ext[0] /* mode (7,[01]): absolute address */
-#define ea_immed ea_ext /* mode (7,4): immediate value */
-#define ea_basedisp ea_ext[0] /* mode 6: base displacement */
-#define ea_outerdisp ea_ext[1] /* mode 6: outer displacement */
-#define ea_idxreg ea_ext[2] /* mode 6: index register number */
-#define ea_fea ea_ext[0] /* MC68LC040 only: frame EA */
-
-struct instruction {
- u_int is_pc; /* insn's address */
- u_int is_nextpc; /* next PC */
- int is_advance; /* length of instruction */
- int is_datasize; /* size of memory operand */
- int is_opcode; /* opcode word */
- int is_word1; /* second word */
- struct insn_ea is_ea; /* decoded effective address mode */
-};
-
-/*
- * FP data types
- */
-#define FTYPE_LNG 0 /* Long Word Integer */
-#define FTYPE_SNG 1 /* Single Prec */
-#define FTYPE_EXT 2 /* Extended Prec */
-#define FTYPE_BCD 3 /* Packed BCD */
-#define FTYPE_WRD 4 /* Word Integer */
-#define FTYPE_DBL 5 /* Double Prec */
-#define FTYPE_BYT 6 /* Byte Integer */
-
-/*
- * MC68881/68882 FPcr bit definitions (should these go to <m68k/reg.h>
- * or <m68k/fpu.h> or something?)
- */
-
-/* fpsr */
-#define FPSR_CCB 0xff000000
-# define FPSR_NEG 0x08000000
-# define FPSR_ZERO 0x04000000
-# define FPSR_INF 0x02000000
-# define FPSR_NAN 0x01000000
-#define FPSR_QTT 0x00ff0000
-# define FPSR_QSG 0x00800000
-# define FPSR_QUO 0x007f0000
-#define FPSR_EXCP 0x0000ff00
-# define FPSR_BSUN 0x00008000
-# define FPSR_SNAN 0x00004000
-# define FPSR_OPERR 0x00002000
-# define FPSR_OVFL 0x00001000
-# define FPSR_UNFL 0x00000800
-# define FPSR_DZ 0x00000400
-# define FPSR_INEX2 0x00000200
-# define FPSR_INEX1 0x00000100
-#define FPSR_AEX 0x000000ff
-# define FPSR_AIOP 0x00000080
-# define FPSR_AOVFL 0x00000040
-# define FPSR_AUNFL 0x00000020
-# define FPSR_ADZ 0x00000010
-# define FPSR_AINEX 0x00000008
-
-/* fpcr */
-#define FPCR_EXCP FPSR_EXCP
-# define FPCR_BSUN FPSR_BSUN
-# define FPCR_SNAN FPSR_SNAN
-# define FPCR_OPERR FPSR_OPERR
-# define FPCR_OVFL FPSR_OVFL
-# define FPCR_UNFL FPSR_UNFL
-# define FPCR_DZ FPSR_DZ
-# define FPCR_INEX2 FPSR_INEX2
-# define FPCR_INEX1 FPSR_INEX1
-#define FPCR_MODE 0x000000ff
-# define FPCR_PREC 0x000000c0
-# define FPCR_EXTD 0x00000000
-# define FPCR_SNGL 0x00000040
-# define FPCR_DBL 0x00000080
-# define FPCR_ROUND 0x00000030
-# define FPCR_NEAR 0x00000000
-# define FPCR_ZERO 0x00000010
-# define FPCR_MINF 0x00000020
-# define FPCR_PINF 0x00000030
-
-/*
- * Other functions.
- */
-
-/* Build a new Quiet NaN (sign=0, frac=all 1's). */
-struct fpn *fpu_newnan(struct fpemu *fe);
-
-/*
- * Shift a number right some number of bits, taking care of round/sticky.
- * Note that the result is probably not a well-formed number (it will lack
- * the normal 1-bit mant[0]&FP_1).
- */
-int fpu_shr(struct fpn *fp, int shr);
-/*
- * Round a number according to the round mode in FPCR
- */
-int fpu_round(struct fpemu *fe, struct fpn *fp);
-
-/* type conversion */
-void fpu_explode(struct fpemu *fe, struct fpn *fp, int t, u_int *src);
-void fpu_implode(struct fpemu *fe, struct fpn *fp, int t, u_int *dst);
-
-/*
- * non-static emulation functions
- */
-/* type 0 */
-int fpu_emul_fmovecr(struct fpemu *fe, struct instruction *insn, int *typ);
-int fpu_emul_fstore(struct fpemu *fe, struct instruction *insn, int *typ);
-int fpu_emul_fscale(struct fpemu *fe, struct instruction *insn, int *typ);
-
-/*
- * include function declarations of those which are called by fpu_emul_arith()
- */
-#include <m68k/fpe/fpu_arith_proto.h>
-
-int fpu_emulate(struct frame *frame, struct fpframe *fpf, int *typ);
-
-/*
- * "helper" functions
- */
-/* return values from constant rom */
-struct fpn *fpu_const(struct fpn *fp, u_int offset);
-/* update exceptions and FPSR */
-int fpu_upd_excp(struct fpemu *fe);
-u_int fpu_upd_fpsr(struct fpemu *fe, struct fpn *fp) ;
-
-/* address mode decoder, and load/store */
-int fpu_decode_ea(struct frame *frame, struct instruction *insn,
- struct insn_ea *ea, int modreg, int *typ);
-int fpu_load_ea(struct frame *frame, struct instruction *insn,
- struct insn_ea *ea, char *dst, int *typ);
-int fpu_store_ea(struct frame *frame, struct instruction *insn,
- struct insn_ea *ea, char *src);
-
-/* fpu_subr.c */
-void fpu_norm(struct fpn *fp);
-
-#if !defined(FPE_DEBUG)
-# define FPE_DEBUG 0
-#endif
-
-#endif /* _FPU_EMULATE_H_ */
diff --git a/sys/arch/m68k/fpe/fpu_explode.c b/sys/arch/m68k/fpe/fpu_explode.c
deleted file mode 100644
index e372d1c7255..00000000000
--- a/sys/arch/m68k/fpe/fpu_explode.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* $OpenBSD: fpu_explode.c,v 1.6 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_explode.c,v 1.6 2003/10/23 15:07:30 kleink Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- * @(#)fpu_explode.c 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * FPU subroutines: `explode' the machine's `packed binary' format numbers
- * into our internal format.
- */
-
-#include <sys/types.h>
-#include <sys/systm.h>
-
-#include <machine/ieee.h>
-#include <machine/reg.h>
-
-#include <m68k/fpe/fpu_arith.h>
-#include <m68k/fpe/fpu_emulate.h>
-
-
-/* Conversion to internal format -- note asymmetry. */
-int fpu_itof(struct fpn *fp, u_int i);
-int fpu_stof(struct fpn *fp, u_int i);
-int fpu_dtof(struct fpn *fp, u_int i, u_int j);
-int fpu_xtof(struct fpn *fp, u_int i, u_int j, u_int k);
-
-/*
- * N.B.: in all of the following, we assume the FP format is
- *
- * ---------------------------
- * | s | exponent | fraction |
- * ---------------------------
- *
- * (which represents -1**s * 1.fraction * 2**exponent), so that the
- * sign bit is way at the top (bit 31), the exponent is next, and
- * then the remaining bits mark the fraction. A zero exponent means
- * zero or denormalized (0.fraction rather than 1.fraction), and the
- * maximum possible exponent, 2bias+1, signals inf (fraction==0) or NaN.
- *
- * Since the sign bit is always the topmost bit---this holds even for
- * integers---we set that outside all the *tof functions. Each function
- * returns the class code for the new number (but note that we use
- * FPC_QNAN for all NaNs; fpu_explode will fix this if appropriate).
- */
-
-/*
- * int -> fpn.
- */
-int
-fpu_itof(fp, i)
- struct fpn *fp;
- u_int i;
-{
-
- if (i == 0)
- return (FPC_ZERO);
- /*
- * The value FP_1 represents 2^FP_LG, so set the exponent
- * there and let normalization fix it up. Convert negative
- * numbers to sign-and-magnitude. Note that this relies on
- * fpu_norm()'s handling of `supernormals'; see fpu_subr.c.
- */
- fp->fp_exp = FP_LG;
- fp->fp_mant[0] = (int)i < 0 ? -i : i;
- fp->fp_mant[1] = 0;
- fp->fp_mant[2] = 0;
- fpu_norm(fp);
- return (FPC_NUM);
-}
-
-#define mask(nbits) ((1 << (nbits)) - 1)
-
-/*
- * All external floating formats convert to internal in the same manner,
- * as defined here. Note that only normals get an implied 1.0 inserted.
- */
-#define FP_TOF(exp, expbias, allfrac, f0, f1, f2, f3) \
- if (exp == 0) { \
- if (allfrac == 0) \
- return (FPC_ZERO); \
- fp->fp_exp = 1 - expbias; \
- fp->fp_mant[0] = f0; \
- fp->fp_mant[1] = f1; \
- fp->fp_mant[2] = f2; \
- fpu_norm(fp); \
- return (FPC_NUM); \
- } \
- if (exp == (2 * expbias + 1)) { \
- if (allfrac == 0) \
- return (FPC_INF); \
- fp->fp_mant[0] = f0; \
- fp->fp_mant[1] = f1; \
- fp->fp_mant[2] = f2; \
- return (FPC_QNAN); \
- } \
- fp->fp_exp = exp - expbias; \
- fp->fp_mant[0] = FP_1 | f0; \
- fp->fp_mant[1] = f1; \
- fp->fp_mant[2] = f2; \
- return (FPC_NUM)
-
-/*
- * 32-bit single precision -> fpn.
- * We assume a single occupies at most (64-FP_LG) bits in the internal
- * format: i.e., needs at most fp_mant[0] and fp_mant[1].
- */
-int
-fpu_stof(fp, i)
- struct fpn *fp;
- u_int i;
-{
- int exp;
- u_int frac, f0, f1;
-#define SNG_SHIFT (SNG_FRACBITS - FP_LG)
-
- exp = (i >> (32 - 1 - SNG_EXPBITS)) & mask(SNG_EXPBITS);
- frac = i & mask(SNG_FRACBITS);
- f0 = frac >> SNG_SHIFT;
- f1 = frac << (32 - SNG_SHIFT);
- FP_TOF(exp, SNG_EXP_BIAS, frac, f0, f1, 0, 0);
-}
-
-/*
- * 64-bit double -> fpn.
- * We assume this uses at most (96-FP_LG) bits.
- */
-int
-fpu_dtof(fp, i, j)
- struct fpn *fp;
- u_int i, j;
-{
- int exp;
- u_int frac, f0, f1, f2;
-#define DBL_SHIFT (DBL_FRACBITS - 32 - FP_LG)
-
- exp = (i >> (32 - 1 - DBL_EXPBITS)) & mask(DBL_EXPBITS);
- frac = i & mask(DBL_FRACBITS - 32);
- f0 = frac >> DBL_SHIFT;
- f1 = (frac << (32 - DBL_SHIFT)) | (j >> DBL_SHIFT);
- f2 = j << (32 - DBL_SHIFT);
- frac |= j;
- FP_TOF(exp, DBL_EXP_BIAS, frac, f0, f1, f2, 0);
-}
-
-/*
- * 96-bit extended -> fpn.
- */
-int
-fpu_xtof(fp, i, j, k)
- struct fpn *fp;
- u_int i, j, k;
-{
- int exp;
- u_int frac, f0, f1, f2;
-#define EXT_SHIFT (EXT_FRACBITS - 1 - 32 - FP_LG)
-
- exp = (i >> (32 - 1 - EXT_EXPBITS)) & mask(EXT_EXPBITS);
- f0 = j >> EXT_SHIFT;
- f1 = (j << (32 - EXT_SHIFT)) | (k >> EXT_SHIFT);
- f2 = k << (32 - EXT_SHIFT);
- frac = j | k;
-
- /* m68k extended does not imply denormal by exp==0 */
- if (exp == 0) {
- if (frac == 0)
- return (FPC_ZERO);
- fp->fp_exp = - EXT_EXP_BIAS;
- fp->fp_mant[0] = f0;
- fp->fp_mant[1] = f1;
- fp->fp_mant[2] = f2;
- fpu_norm(fp);
- return (FPC_NUM);
- }
- if (exp == (2 * EXT_EXP_BIAS + 1)) {
- if (frac == 0)
- return (FPC_INF);
- fp->fp_mant[0] = f0;
- fp->fp_mant[1] = f1;
- fp->fp_mant[2] = f2;
- return (FPC_QNAN);
- }
- fp->fp_exp = exp - EXT_EXP_BIAS;
- fp->fp_mant[0] = FP_1 | f0;
- fp->fp_mant[1] = f1;
- fp->fp_mant[2] = f2;
- return (FPC_NUM);
-}
-
-/*
- * Explode the contents of a memory operand.
- */
-void
-fpu_explode(fe, fp, type, space)
- struct fpemu *fe;
- struct fpn *fp;
- int type;
- u_int *space;
-{
- u_int s;
-
- s = space[0];
- fp->fp_sign = s >> 31;
- fp->fp_sticky = 0;
- switch (type) {
-
- case FTYPE_BYT:
- s >>= 8;
- case FTYPE_WRD:
- s >>= 16;
- case FTYPE_LNG:
- s = fpu_itof(fp, s);
- break;
-
- case FTYPE_SNG:
- s = fpu_stof(fp, s);
- break;
-
- case FTYPE_DBL:
- s = fpu_dtof(fp, s, space[1]);
- break;
-
- case FTYPE_EXT:
- s = fpu_xtof(fp, s, space[1], space[2]);
- break;
-
- default:
- panic("fpu_explode");
- }
- if (s == FPC_QNAN && (fp->fp_mant[0] & FP_QUIETBIT) == 0) {
- /*
- * Input is a signalling NaN. All operations that return
- * an input NaN operand put it through a ``NaN conversion'',
- * which basically just means ``turn on the quiet bit''.
- * We do this here so that all NaNs internally look quiet
- * (we can tell signalling ones by their class).
- */
- fp->fp_mant[0] |= FP_QUIETBIT;
- fe->fe_fpsr |= FPSR_SNAN; /* assert SNAN exception */
- s = FPC_SNAN;
- }
- fp->fp_class = s;
-}
diff --git a/sys/arch/m68k/fpe/fpu_fmovecr.c b/sys/arch/m68k/fpe/fpu_fmovecr.c
deleted file mode 100644
index a8392202709..00000000000
--- a/sys/arch/m68k/fpe/fpu_fmovecr.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* $OpenBSD: fpu_fmovecr.c,v 1.8 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_fmovecr.c,v 1.10 2003/07/15 02:43:09 lukem Exp $ */
-
-/*
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * @(#)fpu_fmovecr.c 10/8/95
- */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <machine/frame.h>
-
-#include <m68k/fpe/fpu_emulate.h>
-
-/* XXX: quick consistency check */
-#if (FP_1 != 0x40000)
-Error you have to change this table when changing the mantissa size
-#endif
-
-static struct fpn constrom[] = {
- /* fp_class, fp_sign, fp_exp, fp_sticky, fp_mant[0] ... [2] */
- { FPC_NUM, 0, 1, 0, { 0x6487e, 0xd5110b46, 0x11a80000 } },
- { FPC_NUM, 0, -2, 0, { 0x4d104, 0xd427de7f, 0xbcc00000 } },
- { FPC_NUM, 0, 1, 0, { 0x56fc2, 0xa2c515da, 0x54d00000 } },
- { FPC_NUM, 0, 0, 0, { 0x5c551, 0xd94ae0bf, 0x85e00000 } },
- { FPC_NUM, 0, -2, 0, { 0x6f2de, 0xc549b943, 0x8ca80000 } },
- { FPC_ZERO, 0, 0, 0, { 0x0, 0x0, 0x0 } },
- { FPC_NUM, 0, -1, 0, { 0x58b90, 0xbfbe8e7b, 0xcd600000 } },
- { FPC_NUM, 0, 1, 0, { 0x49aec, 0x6eed5545, 0x60b80000 } },
- { FPC_NUM, 0, 0, 0, { 0x40000, 0x0, 0x0 } },
- { FPC_NUM, 0, 3, 0, { 0x50000, 0x0, 0x0 } },
- { FPC_NUM, 0, 6, 0, { 0x64000, 0x0, 0x0 } },
- { FPC_NUM, 0, 13, 0, { 0x4e200, 0x0, 0x0 } },
- { FPC_NUM, 0, 26, 0, { 0x5f5e1, 0x0, 0x0 } },
- { FPC_NUM, 0, 53, 0, { 0x470de, 0x4df82000, 0x0 } },
- { FPC_NUM, 0, 106, 0, { 0x4ee2d, 0x6d415b85, 0xacf00000 } },
- { FPC_NUM, 0, 212, 0, { 0x613c0, 0xfa4ffe7d, 0x36a80000 } },
- { FPC_NUM, 0, 425, 0, { 0x49dd2, 0x3e4c074c, 0x67000000 } },
- { FPC_NUM, 0, 850, 0, { 0x553f7, 0x5fdcefce, 0xf4700000 } },
- { FPC_NUM, 0, 1700, 0, { 0x718cd, 0x5753074, 0x8e380000 } },
- { FPC_NUM, 0, 3401, 0, { 0x64bb3, 0xac340ba8, 0x60b80000 } },
- { FPC_NUM, 0, 6803, 0, { 0x4f459, 0xdaee29ea, 0xef280000 } },
- { FPC_NUM, 0, 13606, 0, { 0x62302, 0x90145104, 0xbcd80000 } },
-};
-
-struct fpn *
-fpu_const(fp, offset)
- struct fpn *fp;
- u_int offset;
-{
- struct fpn *r;
-
-#ifdef DEBUG
- if (fp == NULL) {
- panic("fpu_const: NULL pointer passed");
- }
-#endif
- if (offset == 0) {
- r = &constrom[0];
- } else if (0xb <= offset && offset <= 0xe) {
- r = &constrom[offset - 0xb + 1];
- } else if (0x30 <= offset && offset <= 0x3f) {
- r = &constrom[offset - 0x30 + 6];
- } else {
- /* return 0.0 for anything else (incl. valid offset 0xf) */
- r = &constrom[5];
- }
-
- CPYFPN(fp, r);
-
- return fp;
-}
-
-int
-fpu_emul_fmovecr(struct fpemu *fe, struct instruction *insn, int *typ)
-{
- int dstreg, offset;
- u_int *fpreg;
-
- dstreg = (insn->is_word1 >> 7) & 0x7;
- offset = insn->is_word1 & 0x7F;
- fpreg = &(fe->fe_fpframe->fpf_regs[0]);
-
- (void)fpu_const(&fe->fe_f3, offset);
- (void)fpu_upd_fpsr(fe, &fe->fe_f3);
- fpu_implode(fe, &fe->fe_f3, FTYPE_EXT, &fpreg[dstreg * 3]);
-#if DEBUG_FPE
- printf(" fpu_emul_fmovecr: result %08x,%08x,%08x to FP%d\n",
- fpreg[dstreg * 3], fpreg[dstreg * 3 + 1], fpreg[dstreg * 3 + 2],
- dstreg);
-#endif
- return 0;
-}
diff --git a/sys/arch/m68k/fpe/fpu_fscale.c b/sys/arch/m68k/fpe/fpu_fscale.c
deleted file mode 100644
index db536ba78ec..00000000000
--- a/sys/arch/m68k/fpe/fpu_fscale.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* $OpenBSD: fpu_fscale.c,v 1.8 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_fscale.c,v 1.11 2003/07/15 02:43:10 lukem Exp $ */
-
-/*
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- * 4. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by Gordon Ross
- *
- * 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.
- */
-
-/*
- * FSCALE - separated from the other type0 arithmetic instructions
- * for performance reason; maybe unnecessary, but FSCALE assumes
- * the source operand be an integer. It performs type conversion
- * only if the source operand is *not* an integer.
- */
-
-#include <sys/types.h>
-#include <sys/signal.h>
-#include <sys/systm.h>
-#include <machine/frame.h>
-
-#include <m68k/fpe/fpu_emulate.h>
-
-int
-fpu_emul_fscale(struct fpemu *fe, struct instruction *insn, int *typ)
-{
- struct frame *frame;
- u_int *fpregs;
- int word1, sig;
- int regnum, format;
- int scale, sign, exp;
- u_int m0, m1;
- u_int buf[3], fpsr;
-#if DEBUG_FPE
- int flags;
- char regname;
-#endif
-
- scale = sig = 0;
- frame = fe->fe_frame;
- fpregs = &(fe->fe_fpframe->fpf_regs[0]);
- /* clear all exceptions and conditions */
- fpsr = fe->fe_fpsr & ~FPSR_EXCP & ~FPSR_CCB;
-#if DEBUG_FPE
- printf("fpu_emul_fscale: FPSR = %08x, FPCR = %08x\n", fpsr, fe->fe_fpcr);
-#endif
-
- word1 = insn->is_word1;
- format = (word1 >> 10) & 7;
- regnum = (word1 >> 7) & 7;
-
- fe->fe_fpcr &= FPCR_ROUND;
- fe->fe_fpcr |= FPCR_ZERO;
-
- /* get the source operand */
- if ((word1 & 0x4000) == 0) {
-#if DEBUG_FPE
- printf("fpu_emul_fscale: FP%d op FP%d => FP%d\n",
- format, regnum, regnum);
- /* the operand is an FP reg */
- printf("fpu_emul_scale: src opr FP%d=%08x%08x%08x\n",
- format, fpregs[format*3], fpregs[format*3+1],
- fpregs[format*3+2]);
-#endif
- fpu_explode(fe, &fe->fe_f2, FTYPE_EXT, &fpregs[format * 3]);
- fpu_implode(fe, &fe->fe_f2, FTYPE_LNG, buf);
- scale = buf[0];
- } else {
- /* the operand is in memory */
- if (format == FTYPE_DBL) {
- insn->is_datasize = 8;
- } else if (format == FTYPE_SNG || format == FTYPE_LNG) {
- insn->is_datasize = 4;
- } else if (format == FTYPE_WRD) {
- insn->is_datasize = 2;
- } else if (format == FTYPE_BYT) {
- insn->is_datasize = 1;
- } else if (format == FTYPE_EXT) {
- insn->is_datasize = 12;
- } else {
- /* invalid or unsupported operand format */
- *typ = ILL_ILLOPN;
- sig = SIGILL;
- return sig;
- }
-
- /* Get effective address. (modreg=opcode&077) */
- sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ);
- if (sig) {
-#if DEBUG_FPE
- printf("fpu_emul_fscale: error in decode_ea\n");
-#endif
- return sig;
- }
-
-#if DEBUG_FPE
- printf("fpu_emul_fscale: addr mode = ");
- flags = insn->is_ea.ea_flags;
- regname = (insn->is_ea.ea_regnum & 8) ? 'a' : 'd';
-
- if (flags & EA_DIRECT) {
- printf("%c%d\n", regname, insn->is_ea.ea_regnum & 7);
- } else if (flags & EA_PREDECR) {
- printf("%c%d@-\n", regname, insn->is_ea.ea_regnum & 7);
- } else if (flags & EA_POSTINCR) {
- printf("%c%d@+\n", regname, insn->is_ea.ea_regnum & 7);
- } else if (flags & EA_OFFSET) {
- printf("%c%d@(%d)\n", regname, insn->is_ea.ea_regnum & 7,
- insn->is_ea.ea_offset);
- } else if (flags & EA_INDEXED) {
- printf("%c%d@(...)\n", regname, insn->is_ea.ea_regnum & 7);
- } else if (flags & EA_ABS) {
- printf("0x%08x\n", insn->is_ea.ea_absaddr);
- } else if (flags & EA_PC_REL) {
- printf("pc@(%d)\n", insn->is_ea.ea_offset);
- } else if (flags & EA_IMMED) {
- printf("#0x%08x%08x%08x\n",
- insn->is_ea.ea_immed[0], insn->is_ea.ea_immed[1],
- insn->is_ea.ea_immed[2]);
- } else {
- printf("%c%d@\n", regname, insn->is_ea.ea_regnum & 7);
- }
-#endif
- fpu_load_ea(frame, insn, &insn->is_ea, (char *)buf, typ);
-
-#if DEBUG_FPE
- printf("fpu_emul_fscale: src = %08x%08x%08x, siz = %d\n",
- buf[0], buf[1], buf[2], insn->is_datasize);
-#endif
- if (format == FTYPE_LNG) {
- /* nothing */
- scale = buf[0];
- } else if (format == FTYPE_WRD) {
- /* sign-extend */
- scale = buf[0] & 0xffff;
- if (scale & 0x8000) {
- scale |= 0xffff0000;
- }
- } else if (format == FTYPE_BYT) {
- /* sign-extend */
- scale = buf[0] & 0xff;
- if (scale & 0x80) {
- scale |= 0xffffff00;
- }
- } else if (format == FTYPE_DBL || format == FTYPE_SNG ||
- format == FTYPE_EXT) {
- fpu_explode(fe, &fe->fe_f2, format, buf);
- fpu_implode(fe, &fe->fe_f2, FTYPE_LNG, buf);
- scale = buf[0];
- }
- /* make it look like we've got an FP oprand */
- fe->fe_f2.fp_class = (buf[0] == 0) ? FPC_ZERO : FPC_NUM;
- }
-
- /* assume there's no exception */
- sig = 0;
-
- /* it's barbaric but we're going to operate directly on
- * the dst operand's bit pattern */
- sign = fpregs[regnum * 3] & 0x80000000;
- exp = (fpregs[regnum * 3] & 0x7fff0000) >> 16;
- m0 = fpregs[regnum * 3 + 1];
- m1 = fpregs[regnum * 3 + 2];
-
- switch (fe->fe_f2.fp_class) {
- case FPC_SNAN:
- fpsr |= FPSR_SNAN;
- case FPC_QNAN:
- /* dst = NaN */
- exp = 0x7fff;
- m0 = m1 = 0xffffffff;
- break;
- case FPC_ZERO:
- case FPC_NUM:
- if ((0 < exp && exp < 0x7fff) ||
- (exp == 0 && (m0 | m1) != 0)) {
- /* normal or denormal */
- exp += scale;
- if (exp < 0) {
- /* underflow */
- u_int grs; /* guard, round and sticky */
-
- exp = 0;
- grs = m1 << (32 + exp);
- m1 = m0 << (32 + exp) | m1 >> -exp;
- m0 >>= -exp;
- if (grs != 0) {
- fpsr |= FPSR_INEX2;
-
- switch (fe->fe_fpcr & 0x30) {
- case FPCR_MINF:
- if (sign != 0) {
- if (++m1 == 0 &&
- ++m0 == 0) {
- m0 = 0x80000000;
- exp++;
- }
- }
- break;
- case FPCR_NEAR:
- if (grs == 0x80000000) {
- /* tie */
- if ((m1 & 1) &&
- ++m1 == 0 &&
- ++m0 == 0) {
- m0 = 0x80000000;
- exp++;
- }
- } else if (grs & 0x80000000) {
- if (++m1 == 0 &&
- ++m0 == 0) {
- m0 = 0x80000000;
- exp++;
- }
- }
- break;
- case FPCR_PINF:
- if (sign == 0) {
- if (++m1 == 0 &&
- ++m0 == 0) {
- m0 = 0x80000000;
- exp++;
- }
- }
- break;
- case FPCR_ZERO:
- break;
- }
- }
- if (exp == 0 && (m0 & 0x80000000) == 0) {
- fpsr |= FPSR_UNFL;
- if ((m0 | m1) == 0) {
- fpsr |= FPSR_ZERO;
- }
- }
- } else if (exp >= 0x7fff) {
- /* overflow --> result = Inf */
- /* but first, try to normalize in case it's an unnormalized */
- while ((m0 & 0x80000000) == 0) {
- exp--;
- m0 = (m0 << 1) | (m1 >> 31);
- m1 = m1 << 1;
- }
- /* if it's still too large, then return Inf */
- if (exp >= 0x7fff) {
- exp = 0x7fff;
- m0 = m1 = 0;
- fpsr |= FPSR_OVFL | FPSR_INF;
- }
- } else if ((m0 & 0x80000000) == 0) {
- /*
- * it's a denormal; we try to normalize but
- * result may and may not be a normal.
- */
- while (exp > 0 && (m0 & 0x80000000) == 0) {
- exp--;
- m0 = (m0 << 1) | (m1 >> 31);
- m1 = m1 << 1;
- }
- if ((m0 & 0x80000000) == 0) {
- fpsr |= FPSR_UNFL;
- }
- } /* exp in range and mantissa normalized */
- } else if (exp == 0 && m0 == 0 && m1 == 0) {
- /* dst is Zero */
- fpsr |= FPSR_ZERO;
- } /* else we know exp == 0x7fff */
- else if ((m0 | m1) == 0) {
- fpsr |= FPSR_INF;
- } else if ((m0 & 0x40000000) == 0) {
- /* a signaling NaN */
- fpsr |= FPSR_NAN | FPSR_SNAN;
- } else {
- /* a quiet NaN */
- fpsr |= FPSR_NAN;
- }
- break;
- case FPC_INF:
- /* dst = NaN */
- exp = 0x7fff;
- m0 = m1 = 0xffffffff;
- fpsr |= FPSR_OPERR | FPSR_NAN;
- break;
- default:
-#ifdef DEBUG
- panic("fpu_emul_fscale: invalid fp class");
-#endif
- break;
- }
-
- /* store the result */
- fpregs[regnum * 3] = sign | (exp << 16);
- fpregs[regnum * 3 + 1] = m0;
- fpregs[regnum * 3 + 2] = m1;
-
- if (sign) {
- fpsr |= FPSR_NEG;
- }
-
- /* update fpsr according to the result of operation */
- fe->fe_fpframe->fpf_fpsr = fe->fe_fpsr = fpsr;
-
-#if DEBUG_FPE
- printf("fpu_emul_fscale: FPSR = %08x, FPCR = %08x\n",
- fe->fe_fpsr, fe->fe_fpcr);
-#endif
-
- return (fpsr & fe->fe_fpcr & FPSR_EXCP) ? SIGFPE : sig;
-}
diff --git a/sys/arch/m68k/fpe/fpu_fstore.c b/sys/arch/m68k/fpe/fpu_fstore.c
deleted file mode 100644
index 097d4e57fb1..00000000000
--- a/sys/arch/m68k/fpe/fpu_fstore.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* $OpenBSD: fpu_fstore.c,v 1.6 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_fstore.c,v 1.8 2003/07/15 02:43:10 lukem Exp $ */
-
-/*
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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.
- *
- * 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.
- */
-
-#include <sys/types.h>
-#include <sys/signal.h>
-#include <sys/systm.h>
-#include <machine/frame.h>
-
-#include <m68k/fpe/fpu_emulate.h>
-
-/*
- * type 0: fmove mem/fpr->fpr
- * In this function, we know
- * (opcode & 0x01c0) == 0
- * (word1 & 0xe000) == 0x6000
- */
-int
-fpu_emul_fstore(struct fpemu *fe, struct instruction *insn, int *typ)
-{
- struct frame *frame = fe->fe_frame;
- u_int *fpregs = fe->fe_fpframe->fpf_regs;
- int word1, sig;
- int regnum;
- int format;
- u_int buf[3];
-
-#if DEBUG_FPE
- printf(" fpu_emul_fstore: frame at %p fpframe at %p\n",
- frame, fe->fe_fpframe);
-#endif
-
- word1 = insn->is_word1;
- format = (word1 >> 10) & 7;
- regnum = (word1 >> 7) & 7;
-
- insn->is_advance = 4;
-
- if (format == FTYPE_DBL) {
- insn->is_datasize = 8;
- } else if (format == FTYPE_SNG || format == FTYPE_LNG) {
- insn->is_datasize = 4;
- } else if (format == FTYPE_WRD) {
- insn->is_datasize = 2;
- format = FTYPE_LNG;
- } else if (format == FTYPE_BYT) {
- insn->is_datasize = 1;
- format = FTYPE_LNG;
- } else if (format == FTYPE_EXT) {
- insn->is_datasize = 12;
- } else {
- /* invalid or unsupported operand format */
-#if DEBUG_FPE
- printf(" fpu_emul_fstore: invalid format %d\n", format);
-#endif
- *typ = ILL_ILLOPN;
- sig = SIGILL;
- }
-#if DEBUG_FPE
- printf(" fpu_emul_fstore: format %d, size %d\n",
- format, insn->is_datasize);
-#endif
-
- fe->fe_fpsr &= ~FPSR_EXCP;
-
- /* Get effective address. (modreg=opcode&077) */
- sig = fpu_decode_ea(frame, insn, &insn->is_ea, insn->is_opcode, typ);
- if (sig) {
-#if DEBUG_FPE
- printf(" fpu_emul_fstore: failed in decode_ea sig=%d\n", sig);
-#endif
- return sig;
- }
-
- if (insn->is_datasize > 4 && insn->is_ea.ea_flags == EA_DIRECT) {
- /* trying to store dbl or ext into a data register */
-#ifdef DEBUG
- printf(" fpu_fstore: attempted to store dbl/ext to reg\n");
-#endif
- return SIGILL;
- }
-
-#if DEBUG_FPE
- printf(" fpu_emul_fstore: saving FP%d (%08x,%08x,%08x)\n",
- regnum, fpregs[regnum * 3], fpregs[regnum * 3 + 1],
- fpregs[regnum * 3 + 2]);
-#endif
- fpu_explode(fe, &fe->fe_f3, FTYPE_EXT, &fpregs[regnum * 3]);
-#if DEBUG_FPE
- {
- static char *class_name[] = { "SNAN", "QNAN", "ZERO", "NUM", "INF" };
- printf(" fpu_emul_fstore: fpn (%s,%c,%d,%08x,%08x,%08x)\n",
- class_name[fe->fe_f3.fp_class + 2],
- fe->fe_f3.fp_sign ? '-' : '+', fe->fe_f3.fp_exp,
- fe->fe_f3.fp_mant[0], fe->fe_f3.fp_mant[1],
- fe->fe_f3.fp_mant[2]);
- }
-#endif
- fpu_implode(fe, &fe->fe_f3, format, buf);
-
- fpu_store_ea(frame, insn, &insn->is_ea, (char *)buf);
-#if DEBUG_FPE
- printf(" fpu_emul_fstore: %08x,%08x,%08x size %d\n",
- buf[0], buf[1], buf[2], insn->is_datasize);
-#endif
-
- return 0;
-}
diff --git a/sys/arch/m68k/fpe/fpu_getexp.c b/sys/arch/m68k/fpe/fpu_getexp.c
deleted file mode 100644
index 771de64f826..00000000000
--- a/sys/arch/m68k/fpe/fpu_getexp.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/* $OpenBSD: fpu_getexp.c,v 1.3 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_getexp.c,v 1.1 1995/11/03 04:47:11 briggs Exp $ */
-
-/*
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * @(#)fpu_getexp.c 10/8/95
- */
-
-#include <sys/types.h>
-
-#include <m68k/fpe/fpu_emulate.h>
-
-struct fpn *
-fpu_getexp(fe)
- struct fpemu *fe;
-{
- struct fpn *fp = &fe->fe_f2;
-
- fe->fe_fpsr &= ~FPSR_EXCP; /* clear all exceptions */
-
- if (fp->fp_class == FPC_INF) {
- fp = fpu_newnan(fe);
- fe->fe_fpsr |= FPSR_OPERR;
- } else if (fp->fp_class == FPC_NUM) { /* a number */
- fpu_explode(fe, &fe->fe_f3, FTYPE_LNG, &fp->fp_exp);
- fp = &fe->fe_f3;
- } else if (fp->fp_class == FPC_SNAN) { /* signaling NaN */
- fe->fe_fpsr |= FPSR_SNAN;
- } /* else if fp == zero or fp == quiet NaN, return itself */
- return fp;
-}
-
-struct fpn *
-fpu_getman(fe)
- struct fpemu *fe;
-{
- struct fpn *fp = &fe->fe_f2;
-
- fe->fe_fpsr &= ~FPSR_EXCP; /* clear all exceptions */
-
- if (fp->fp_class == FPC_INF) {
- fp = fpu_newnan(fe);
- fe->fe_fpsr |= FPSR_OPERR;
- } else if (fp->fp_class == FPC_NUM) { /* a number */
- fp->fp_exp = 0;
- } else if (fp->fp_class == FPC_SNAN) { /* signaling NaN */
- fe->fe_fpsr |= FPSR_SNAN;
- } /* else if fp == zero or fp == quiet NaN, return itself */
- return fp;
-}
-
diff --git a/sys/arch/m68k/fpe/fpu_implode.c b/sys/arch/m68k/fpe/fpu_implode.c
deleted file mode 100644
index ddfa8582fa9..00000000000
--- a/sys/arch/m68k/fpe/fpu_implode.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/* $OpenBSD: fpu_implode.c,v 1.6 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_implode.c,v 1.8 2003/10/23 15:07:30 kleink Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- * @(#)fpu_implode.c 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * FPU subroutines: `implode' internal format numbers into the machine's
- * `packed binary' format.
- */
-
-#include <sys/types.h>
-#include <sys/systm.h>
-
-#include <machine/ieee.h>
-#include <machine/reg.h>
-
-#include <m68k/fpe/fpu_emulate.h>
-#include <m68k/fpe/fpu_arith.h>
-
-/* Conversion from internal format -- note asymmetry. */
-u_int fpu_ftoi(struct fpemu *fe, struct fpn *fp);
-u_int fpu_ftos(struct fpemu *fe, struct fpn *fp);
-u_int fpu_ftod(struct fpemu *fe, struct fpn *fp, u_int *);
-u_int fpu_ftox(struct fpemu *fe, struct fpn *fp, u_int *);
-
-int toinf(struct fpemu *fe, int sign);
-
-/*
- * Round a number (algorithm from Motorola MC68882 manual, modified for
- * our internal format). Set inexact exception if rounding is required.
- * Return true iff we rounded up.
- *
- * After rounding, we discard the guard and round bits by shifting right
- * 2 bits (a la fpu_shr(), but we do not bother with fp->fp_sticky).
- * This saves effort later.
- *
- * Note that we may leave the value 2.0 in fp->fp_mant; it is the caller's
- * responsibility to fix this if necessary.
- */
-int
-fpu_round(struct fpemu *fe, struct fpn *fp)
-{
- u_int m0, m1, m2;
- int gr, s;
-
- m0 = fp->fp_mant[0];
- m1 = fp->fp_mant[1];
- m2 = fp->fp_mant[2];
- gr = m2 & 3;
- s = fp->fp_sticky;
-
- /* mant >>= FP_NG */
- m2 = (m2 >> FP_NG) | (m1 << (32 - FP_NG));
- m1 = (m1 >> FP_NG) | (m0 << (32 - FP_NG));
- m0 >>= FP_NG;
-
- if ((gr | s) == 0) /* result is exact: no rounding needed */
- goto rounddown;
-
- fe->fe_fpsr |= FPSR_INEX2; /* inexact */
-
- /* Go to rounddown to round down; break to round up. */
- switch (fe->fe_fpcr & FPCR_ROUND) {
-
- case FPCR_NEAR:
- default:
- /*
- * Round only if guard is set (gr & 2). If guard is set,
- * but round & sticky both clear, then we want to round
- * but have a tie, so round to even, i.e., add 1 iff odd.
- */
- if ((gr & 2) == 0)
- goto rounddown;
- if ((gr & 1) || fp->fp_sticky || (m2 & 1))
- break;
- goto rounddown;
-
- case FPCR_ZERO:
- /* Round towards zero, i.e., down. */
- goto rounddown;
-
- case FPCR_MINF:
- /* Round towards -Inf: up if negative, down if positive. */
- if (fp->fp_sign)
- break;
- goto rounddown;
-
- case FPCR_PINF:
- /* Round towards +Inf: up if positive, down otherwise. */
- if (!fp->fp_sign)
- break;
- goto rounddown;
- }
-
- /* Bump low bit of mantissa, with carry. */
- if (++m2 == 0 && ++m1 == 0)
- m0++;
- fp->fp_sticky = 0;
- fp->fp_mant[0] = m0;
- fp->fp_mant[1] = m1;
- fp->fp_mant[2] = m2;
- return (1);
-
-rounddown:
- fp->fp_sticky = 0;
- fp->fp_mant[0] = m0;
- fp->fp_mant[1] = m1;
- fp->fp_mant[2] = m2;
- return (0);
-}
-
-/*
- * For overflow: return true if overflow is to go to +/-Inf, according
- * to the sign of the overflowing result. If false, overflow is to go
- * to the largest magnitude value instead.
- */
-int
-toinf(struct fpemu *fe, int sign)
-{
- int inf;
-
- /* look at rounding direction */
- switch (fe->fe_fpcr & FPCR_ROUND) {
-
- default:
- case FPCR_NEAR: /* the nearest value is always Inf */
- inf = 1;
- break;
-
- case FPCR_ZERO: /* toward 0 => never towards Inf */
- inf = 0;
- break;
-
- case FPCR_PINF: /* toward +Inf iff positive */
- inf = (sign == 0);
- break;
-
- case FPCR_MINF: /* toward -Inf iff negative */
- inf = sign;
- break;
- }
- return (inf);
-}
-
-/*
- * fpn -> int (int value returned as return value).
- *
- * N.B.: this conversion always rounds towards zero (this is a peculiarity
- * of the SPARC instruction set).
- */
-u_int
-fpu_ftoi(fe, fp)
- struct fpemu *fe;
- struct fpn *fp;
-{
- u_int i;
- int sign, exp;
-
- sign = fp->fp_sign;
- switch (fp->fp_class) {
-
- case FPC_ZERO:
- return (0);
-
- case FPC_NUM:
- /*
- * If exp >= 2^32, overflow. Otherwise shift value right
- * into last mantissa word (this will not exceed 0xffffffff),
- * shifting any guard and round bits out into the sticky
- * bit. Then ``round'' towards zero, i.e., just set an
- * inexact exception if sticky is set (see fpu_round()).
- * If the result is > 0x80000000, or is positive and equals
- * 0x80000000, overflow; otherwise the last fraction word
- * is the result.
- */
- if ((exp = fp->fp_exp) >= 32)
- break;
- /* NB: the following includes exp < 0 cases */
- if (fpu_shr(fp, FP_NMANT - 1 - FP_NG - exp) != 0)
- /* m68881/2 do not underflow when
- converting to integer */;
- fpu_round(fe, fp);
- i = fp->fp_mant[2];
- if (i >= ((u_int)0x80000000 + sign))
- break;
- return (sign ? -i : i);
-
- default: /* Inf, qNaN, sNaN */
- break;
- }
- /* overflow: replace any inexact exception with invalid */
- fe->fe_fpsr = (fe->fe_fpsr & ~FPSR_INEX2) | FPSR_OPERR;
- return (0x7fffffff + sign);
-}
-
-/*
- * fpn -> single (32 bit single returned as return value).
- * We assume <= 29 bits in a single-precision fraction (1.f part).
- */
-u_int
-fpu_ftos(fe, fp)
- struct fpemu *fe;
- struct fpn *fp;
-{
- u_int sign = fp->fp_sign << 31;
- int exp;
-
-#define SNG_EXP(e) ((e) << SNG_FRACBITS) /* makes e an exponent */
-#define SNG_MASK (SNG_EXP(1) - 1) /* mask for fraction */
-
- /* Take care of non-numbers first. */
- if (ISNAN(fp)) {
- /*
- * Preserve upper bits of NaN, per SPARC V8 appendix N.
- * Note that fp->fp_mant[0] has the quiet bit set,
- * even if it is classified as a signalling NaN.
- */
- (void) fpu_shr(fp, FP_NMANT - 1 - SNG_FRACBITS);
- exp = SNG_EXP_INFNAN;
- goto done;
- }
- if (ISINF(fp))
- return (sign | SNG_EXP(SNG_EXP_INFNAN));
- if (ISZERO(fp))
- return (sign);
-
- /*
- * Normals (including subnormals). Drop all the fraction bits
- * (including the explicit ``implied'' 1 bit) down into the
- * single-precision range. If the number is subnormal, move
- * the ``implied'' 1 into the explicit range as well, and shift
- * right to introduce leading zeroes. Rounding then acts
- * differently for normals and subnormals: the largest subnormal
- * may round to the smallest normal (1.0 x 2^minexp), or may
- * remain subnormal. In the latter case, signal an underflow
- * if the result was inexact or if underflow traps are enabled.
- *
- * Rounding a normal, on the other hand, always produces another
- * normal (although either way the result might be too big for
- * single precision, and cause an overflow). If rounding a
- * normal produces 2.0 in the fraction, we need not adjust that
- * fraction at all, since both 1.0 and 2.0 are zero under the
- * fraction mask.
- *
- * Note that the guard and round bits vanish from the number after
- * rounding.
- */
- if ((exp = fp->fp_exp + SNG_EXP_BIAS) <= 0) { /* subnormal */
- fe->fe_fpsr |= FPSR_UNFL;
- /* -NG for g,r; -SNG_FRACBITS-exp for fraction */
- (void) fpu_shr(fp, FP_NMANT - FP_NG - SNG_FRACBITS - exp);
- if (fpu_round(fe, fp) && fp->fp_mant[2] == SNG_EXP(1))
- return (sign | SNG_EXP(1) | 0);
- if (fe->fe_fpsr & FPSR_INEX2)
- fe->fe_fpsr |= FPSR_UNFL
- /* mc68881/2 don't underflow when converting */;
- return (sign | SNG_EXP(0) | fp->fp_mant[2]);
- }
- /* -FP_NG for g,r; -1 for implied 1; -SNG_FRACBITS for fraction */
- (void) fpu_shr(fp, FP_NMANT - FP_NG - 1 - SNG_FRACBITS);
-#ifdef DIAGNOSTIC
- if ((fp->fp_mant[2] & SNG_EXP(1 << FP_NG)) == 0)
- panic("fpu_ftos");
-#endif
- if (fpu_round(fe, fp) && fp->fp_mant[2] == SNG_EXP(2))
- exp++;
- if (exp >= SNG_EXP_INFNAN) {
- /* overflow to inf or to max single */
- fe->fe_fpsr |= FPSR_OPERR | FPSR_INEX2 | FPSR_OVFL;
- if (toinf(fe, sign))
- return (sign | SNG_EXP(SNG_EXP_INFNAN));
- return (sign | SNG_EXP(SNG_EXP_INFNAN - 1) | SNG_MASK);
- }
-done:
- /* phew, made it */
- return (sign | SNG_EXP(exp) | (fp->fp_mant[2] & SNG_MASK));
-}
-
-/*
- * fpn -> double (32 bit high-order result returned; 32-bit low order result
- * left in res[1]). Assumes <= 61 bits in double precision fraction.
- *
- * This code mimics fpu_ftos; see it for comments.
- */
-u_int
-fpu_ftod(fe, fp, res)
- struct fpemu *fe;
- struct fpn *fp;
- u_int *res;
-{
- u_int sign = fp->fp_sign << 31;
- int exp;
-
-#define DBL_EXP(e) ((e) << (DBL_FRACBITS & 31))
-#define DBL_MASK (DBL_EXP(1) - 1)
-
- if (ISNAN(fp)) {
- (void) fpu_shr(fp, FP_NMANT - 1 - DBL_FRACBITS);
- exp = DBL_EXP_INFNAN;
- goto done;
- }
- if (ISINF(fp)) {
- sign |= DBL_EXP(DBL_EXP_INFNAN);
- res[1] = 0;
- return (sign);
- }
- if (ISZERO(fp)) {
- res[1] = 0;
- return (sign);
- }
-
- if ((exp = fp->fp_exp + DBL_EXP_BIAS) <= 0) {
- fe->fe_fpsr |= FPSR_UNFL;
- (void) fpu_shr(fp, FP_NMANT - FP_NG - DBL_FRACBITS - exp);
- if (fpu_round(fe, fp) && fp->fp_mant[1] == DBL_EXP(1)) {
- res[1] = 0;
- return (sign | DBL_EXP(1) | 0);
- }
- if (fe->fe_fpsr & FPSR_INEX2)
- fe->fe_fpsr |= FPSR_UNFL
- /* mc68881/2 don't underflow when converting */;
- exp = 0;
- goto done;
- }
- (void) fpu_shr(fp, FP_NMANT - FP_NG - 1 - DBL_FRACBITS);
- if (fpu_round(fe, fp) && fp->fp_mant[1] == DBL_EXP(2))
- exp++;
- if (exp >= DBL_EXP_INFNAN) {
- fe->fe_fpsr |= FPSR_OPERR | FPSR_INEX2 | FPSR_OVFL;
- if (toinf(fe, sign)) {
- res[1] = 0;
- return (sign | DBL_EXP(DBL_EXP_INFNAN) | 0);
- }
- res[1] = ~0;
- return (sign | DBL_EXP(DBL_EXP_INFNAN) | DBL_MASK);
- }
-done:
- res[1] = fp->fp_mant[2];
- return (sign | DBL_EXP(exp) | (fp->fp_mant[1] & DBL_MASK));
-}
-
-/*
- * fpn -> 68k extended (32 bit high-order result returned; two 32-bit low
- * order result left in res[1] & res[2]). Assumes == 64 bits in extended
- * precision fraction.
- *
- * This code mimics fpu_ftos; see it for comments.
- */
-u_int
-fpu_ftox(fe, fp, res)
- struct fpemu *fe;
- struct fpn *fp;
- u_int *res;
-{
- u_int sign = fp->fp_sign << 31;
- int exp;
-
-#define EXT_EXP(e) ((e) << 16)
-/*
- * on m68k extended prec, significand does not share the same long
- * word with exponent
- */
-#define EXT_MASK 0
-#define EXT_EXPLICIT1 (1UL << (63 & 31))
-#define EXT_EXPLICIT2 (1UL << (64 & 31))
-
- if (ISNAN(fp)) {
- (void) fpu_shr(fp, FP_NMANT - EXT_FRACBITS);
- exp = EXT_EXP_INFNAN;
- goto done;
- }
- if (ISINF(fp)) {
- sign |= EXT_EXP(EXT_EXP_INFNAN);
- res[1] = res[2] = 0;
- return (sign);
- }
- if (ISZERO(fp)) {
- res[1] = res[2] = 0;
- return (sign);
- }
-
- if ((exp = fp->fp_exp + EXT_EXP_BIAS) < 0) {
- fe->fe_fpsr |= FPSR_UNFL;
- /* I'm not sure about this <=... exp==0 doesn't mean
- it's a denormal in extended format */
- (void) fpu_shr(fp, FP_NMANT - FP_NG - EXT_FRACBITS - exp);
- if (fpu_round(fe, fp) && fp->fp_mant[1] == EXT_EXPLICIT1) {
- res[1] = res[2] = 0;
- return (sign | EXT_EXP(1) | 0);
- }
- if (fe->fe_fpsr & FPSR_INEX2)
- fe->fe_fpsr |= FPSR_UNFL
- /* mc68881/2 don't underflow */;
- exp = 0;
- goto done;
- }
-#if (FP_NMANT - FP_NG - EXT_FRACBITS) > 0
- (void) fpu_shr(fp, FP_NMANT - FP_NG - EXT_FRACBITS);
-#endif
- if (fpu_round(fe, fp) && fp->fp_mant[0] == EXT_EXPLICIT2)
- exp++;
- if (exp >= EXT_EXP_INFNAN) {
- fe->fe_fpsr |= FPSR_OPERR | FPSR_INEX2 | FPSR_OVFL;
- if (toinf(fe, sign)) {
- res[1] = res[2] = 0;
- return (sign | EXT_EXP(EXT_EXP_INFNAN) | 0);
- }
- res[1] = res[2] = ~0;
- return (sign | EXT_EXP(EXT_EXP_INFNAN) | EXT_MASK);
- }
-done:
- res[1] = fp->fp_mant[1];
- res[2] = fp->fp_mant[2];
- return (sign | EXT_EXP(exp));
-}
-
-/*
- * Implode an fpn, writing the result into the given space.
- */
-void
-fpu_implode(fe, fp, type, space)
- struct fpemu *fe;
- struct fpn *fp;
- int type;
- u_int *space;
-{
- /* XXX Dont delete exceptions set here: fe->fe_fpsr &= ~FPSR_EXCP; */
-
- switch (type) {
- case FTYPE_LNG:
- space[0] = fpu_ftoi(fe, fp);
- break;
-
- case FTYPE_SNG:
- space[0] = fpu_ftos(fe, fp);
- break;
-
- case FTYPE_DBL:
- space[0] = fpu_ftod(fe, fp, space);
- break;
-
- case FTYPE_EXT:
- /* funky rounding precision options ?? */
- space[0] = fpu_ftox(fe, fp, space);
- break;
-
- default:
- panic("fpu_implode");
- }
-}
diff --git a/sys/arch/m68k/fpe/fpu_int.c b/sys/arch/m68k/fpe/fpu_int.c
deleted file mode 100644
index 42fe85c05cf..00000000000
--- a/sys/arch/m68k/fpe/fpu_int.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/* $OpenBSD: fpu_int.c,v 1.5 2010/05/10 02:00:50 krw Exp $ */
-/* $NetBSD: fpu_int.c,v 1.6 2003/07/15 02:43:10 lukem Exp $ */
-
-/*
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * @(#)fpu_int.c
- */
-
-#include <sys/types.h>
-
-#include <machine/reg.h>
-
-#include <m68k/fpe/fpu_arith.h>
-#include <m68k/fpe/fpu_emulate.h>
-
-/* FINTRZ - always round to zero */
-struct fpn *
-fpu_intrz(fe)
- struct fpemu *fe;
-{
- struct fpn *x = &fe->fe_f2;
- int sh, clr, mask, i;
-
- /* special cases first */
- if (x->fp_class != FPC_NUM) {
- return x;
- }
- /* when |x| < 1.0 */
- if (x->fp_exp < 0) {
- x->fp_class = FPC_ZERO;
- x->fp_mant[0] = x->fp_mant[1] = x->fp_mant[2] = 0;
- return x;
- }
-
- /* real work */
- sh = FP_NMANT - 1 - x->fp_exp;
- if (sh <= 0) {
- return x;
- }
-
- clr = 2 - sh / 32;
- mask = (0xffffffff << (sh % 32));
-
- for (i = 2; i > clr; i--) {
- x->fp_mant[i] = 0;
- }
- x->fp_mant[i] &= mask;
-
- return x;
-}
-
-/* FINT */
-struct fpn *
-fpu_int(fe)
- struct fpemu *fe;
-{
- struct fpn *x = &fe->fe_f2;
- int rsh, lsh, wsh, i;
-
- /* special cases first */
- if (x->fp_class != FPC_NUM) {
- return x;
- }
- /* even if we have exponent == -1, we still have possibility
- that the result >= 1.0 when mantissa ~= 1.0 and rounded up */
- if (x->fp_exp < -1) {
- x->fp_class = FPC_ZERO;
- x->fp_mant[0] = x->fp_mant[1] = x->fp_mant[2] = 0;
- return x;
- }
-
- /* real work */
- rsh = FP_NMANT - 1 - x->fp_exp;
- if (rsh - FP_NG <= 0) {
- return x;
- }
-
- fpu_shr(x, rsh - FP_NG); /* shift to the right */
-
- if (fpu_round(fe, x) == 1 /* rounded up */ &&
- x->fp_mant[2 - (FP_NMANT-rsh)/32] & (1 << ((FP_NMANT-rsh)%32))
- /* x >= 2.0 */) {
- rsh--; /* reduce shift count by 1 */
- x->fp_exp++; /* adjust exponent */
- }
-
- /* shift it back to the left */
- wsh = rsh / 32;
- lsh = rsh % 32;
- rsh = 32 - lsh;
- for (i = 0; i + wsh < 2; i++) {
- x->fp_mant[i] = (x->fp_mant[i+wsh] << lsh) | (x->fp_mant[i+wsh+1] >> rsh);
- }
- x->fp_mant[i] = (x->fp_mant[i+wsh] << lsh);
- i++;
- for (; i < 3; i++) {
- x->fp_mant[i] = 0;
- }
-
- return x;
-}
diff --git a/sys/arch/m68k/fpe/fpu_log.c b/sys/arch/m68k/fpe/fpu_log.c
deleted file mode 100644
index fb31d7d2b5a..00000000000
--- a/sys/arch/m68k/fpe/fpu_log.c
+++ /dev/null
@@ -1,602 +0,0 @@
-/* $OpenBSD: fpu_log.c,v 1.6 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_log.c,v 1.8 2003/07/15 02:43:10 lukem Exp $ */
-
-/*
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * @(#)fpu_log.c 10/8/95
- */
-
-#include <sys/types.h>
-#include <sys/systm.h>
-
-#include <m68k/fpe/fpu_emulate.h>
-
-static u_int logA6[] = { 0x3FC2499A, 0xB5E4040B };
-static u_int logA5[] = { 0xBFC555B5, 0x848CB7DB };
-static u_int logA4[] = { 0x3FC99999, 0x987D8730 };
-static u_int logA3[] = { 0xBFCFFFFF, 0xFF6F7E97 };
-static u_int logA2[] = { 0x3FD55555, 0x555555A4 };
-static u_int logA1[] = { 0xBFE00000, 0x00000008 };
-
-static u_int logB5[] = { 0x3F175496, 0xADD7DAD6 };
-static u_int logB4[] = { 0x3F3C71C2, 0xFE80C7E0 };
-static u_int logB3[] = { 0x3F624924, 0x928BCCFF };
-static u_int logB2[] = { 0x3F899999, 0x999995EC };
-static u_int logB1[] = { 0x3FB55555, 0x55555555 };
-
-/* sfpn = shortened fp number; can represent only positive numbers */
-static struct sfpn {
- int sp_exp;
- u_int sp_m0, sp_m1;
-} logtbl[] = {
- { 0x3FFE - 0x3fff, 0xFE03F80FU, 0xE03F80FEU },
- { 0x3FF7 - 0x3fff, 0xFF015358U, 0x833C47E2U },
- { 0x3FFE - 0x3fff, 0xFA232CF2U, 0x52138AC0U },
- { 0x3FF9 - 0x3fff, 0xBDC8D83EU, 0xAD88D549U },
- { 0x3FFE - 0x3fff, 0xF6603D98U, 0x0F6603DAU },
- { 0x3FFA - 0x3fff, 0x9CF43DCFU, 0xF5EAFD48U },
- { 0x3FFE - 0x3fff, 0xF2B9D648U, 0x0F2B9D65U },
- { 0x3FFA - 0x3fff, 0xDA16EB88U, 0xCB8DF614U },
- { 0x3FFE - 0x3fff, 0xEF2EB71FU, 0xC4345238U },
- { 0x3FFB - 0x3fff, 0x8B29B775U, 0x1BD70743U },
- { 0x3FFE - 0x3fff, 0xEBBDB2A5U, 0xC1619C8CU },
- { 0x3FFB - 0x3fff, 0xA8D839F8U, 0x30C1FB49U },
- { 0x3FFE - 0x3fff, 0xE865AC7BU, 0x7603A197U },
- { 0x3FFB - 0x3fff, 0xC61A2EB1U, 0x8CD907ADU },
- { 0x3FFE - 0x3fff, 0xE525982AU, 0xF70C880EU },
- { 0x3FFB - 0x3fff, 0xE2F2A47AU, 0xDE3A18AFU },
- { 0x3FFE - 0x3fff, 0xE1FC780EU, 0x1FC780E2U },
- { 0x3FFB - 0x3fff, 0xFF64898EU, 0xDF55D551U },
- { 0x3FFE - 0x3fff, 0xDEE95C4CU, 0xA037BA57U },
- { 0x3FFC - 0x3fff, 0x8DB956A9U, 0x7B3D0148U },
- { 0x3FFE - 0x3fff, 0xDBEB61EEU, 0xD19C5958U },
- { 0x3FFC - 0x3fff, 0x9B8FE100U, 0xF47BA1DEU },
- { 0x3FFE - 0x3fff, 0xD901B203U, 0x6406C80EU },
- { 0x3FFC - 0x3fff, 0xA9372F1DU, 0x0DA1BD17U },
- { 0x3FFE - 0x3fff, 0xD62B80D6U, 0x2B80D62CU },
- { 0x3FFC - 0x3fff, 0xB6B07F38U, 0xCE90E46BU },
- { 0x3FFE - 0x3fff, 0xD3680D36U, 0x80D3680DU },
- { 0x3FFC - 0x3fff, 0xC3FD0329U, 0x06488481U },
- { 0x3FFE - 0x3fff, 0xD0B69FCBU, 0xD2580D0BU },
- { 0x3FFC - 0x3fff, 0xD11DE0FFU, 0x15AB18CAU },
- { 0x3FFE - 0x3fff, 0xCE168A77U, 0x25080CE1U },
- { 0x3FFC - 0x3fff, 0xDE1433A1U, 0x6C66B150U },
- { 0x3FFE - 0x3fff, 0xCB8727C0U, 0x65C393E0U },
- { 0x3FFC - 0x3fff, 0xEAE10B5AU, 0x7DDC8ADDU },
- { 0x3FFE - 0x3fff, 0xC907DA4EU, 0x871146ADU },
- { 0x3FFC - 0x3fff, 0xF7856E5EU, 0xE2C9B291U },
- { 0x3FFE - 0x3fff, 0xC6980C69U, 0x80C6980CU },
- { 0x3FFD - 0x3fff, 0x82012CA5U, 0xA68206D7U },
- { 0x3FFE - 0x3fff, 0xC4372F85U, 0x5D824CA6U },
- { 0x3FFD - 0x3fff, 0x882C5FCDU, 0x7256A8C5U },
- { 0x3FFE - 0x3fff, 0xC1E4BBD5U, 0x95F6E947U },
- { 0x3FFD - 0x3fff, 0x8E44C60BU, 0x4CCFD7DEU },
- { 0x3FFE - 0x3fff, 0xBFA02FE8U, 0x0BFA02FFU },
- { 0x3FFD - 0x3fff, 0x944AD09EU, 0xF4351AF6U },
- { 0x3FFE - 0x3fff, 0xBD691047U, 0x07661AA3U },
- { 0x3FFD - 0x3fff, 0x9A3EECD4U, 0xC3EAA6B2U },
- { 0x3FFE - 0x3fff, 0xBB3EE721U, 0xA54D880CU },
- { 0x3FFD - 0x3fff, 0xA0218434U, 0x353F1DE8U },
- { 0x3FFE - 0x3fff, 0xB92143FAU, 0x36F5E02EU },
- { 0x3FFD - 0x3fff, 0xA5F2FCABU, 0xBBC506DAU },
- { 0x3FFE - 0x3fff, 0xB70FBB5AU, 0x19BE3659U },
- { 0x3FFD - 0x3fff, 0xABB3B8BAU, 0x2AD362A5U },
- { 0x3FFE - 0x3fff, 0xB509E68AU, 0x9B94821FU },
- { 0x3FFD - 0x3fff, 0xB1641795U, 0xCE3CA97BU },
- { 0x3FFE - 0x3fff, 0xB30F6352U, 0x8917C80BU },
- { 0x3FFD - 0x3fff, 0xB7047551U, 0x5D0F1C61U },
- { 0x3FFE - 0x3fff, 0xB11FD3B8U, 0x0B11FD3CU },
- { 0x3FFD - 0x3fff, 0xBC952AFEU, 0xEA3D13E1U },
- { 0x3FFE - 0x3fff, 0xAF3ADDC6U, 0x80AF3ADEU },
- { 0x3FFD - 0x3fff, 0xC2168ED0U, 0xF458BA4AU },
- { 0x3FFE - 0x3fff, 0xAD602B58U, 0x0AD602B6U },
- { 0x3FFD - 0x3fff, 0xC788F439U, 0xB3163BF1U },
- { 0x3FFE - 0x3fff, 0xAB8F69E2U, 0x8359CD11U },
- { 0x3FFD - 0x3fff, 0xCCECAC08U, 0xBF04565DU },
- { 0x3FFE - 0x3fff, 0xA9C84A47U, 0xA07F5638U },
- { 0x3FFD - 0x3fff, 0xD2420487U, 0x2DD85160U },
- { 0x3FFE - 0x3fff, 0xA80A80A8U, 0x0A80A80BU },
- { 0x3FFD - 0x3fff, 0xD7894992U, 0x3BC3588AU },
- { 0x3FFE - 0x3fff, 0xA655C439U, 0x2D7B73A8U },
- { 0x3FFD - 0x3fff, 0xDCC2C4B4U, 0x9887DACCU },
- { 0x3FFE - 0x3fff, 0xA4A9CF1DU, 0x96833751U },
- { 0x3FFD - 0x3fff, 0xE1EEBD3EU, 0x6D6A6B9EU },
- { 0x3FFE - 0x3fff, 0xA3065E3FU, 0xAE7CD0E0U },
- { 0x3FFD - 0x3fff, 0xE70D785CU, 0x2F9F5BDCU },
- { 0x3FFE - 0x3fff, 0xA16B312EU, 0xA8FC377DU },
- { 0x3FFD - 0x3fff, 0xEC1F392CU, 0x5179F283U },
- { 0x3FFE - 0x3fff, 0x9FD809FDU, 0x809FD80AU },
- { 0x3FFD - 0x3fff, 0xF12440D3U, 0xE36130E6U },
- { 0x3FFE - 0x3fff, 0x9E4CAD23U, 0xDD5F3A20U },
- { 0x3FFD - 0x3fff, 0xF61CCE92U, 0x346600BBU },
- { 0x3FFE - 0x3fff, 0x9CC8E160U, 0xC3FB19B9U },
- { 0x3FFD - 0x3fff, 0xFB091FD3U, 0x8145630AU },
- { 0x3FFE - 0x3fff, 0x9B4C6F9EU, 0xF03A3CAAU },
- { 0x3FFD - 0x3fff, 0xFFE97042U, 0xBFA4C2ADU },
- { 0x3FFE - 0x3fff, 0x99D722DAU, 0xBDE58F06U },
- { 0x3FFE - 0x3fff, 0x825EFCEDU, 0x49369330U },
- { 0x3FFE - 0x3fff, 0x9868C809U, 0x868C8098U },
- { 0x3FFE - 0x3fff, 0x84C37A7AU, 0xB9A905C9U },
- { 0x3FFE - 0x3fff, 0x97012E02U, 0x5C04B809U },
- { 0x3FFE - 0x3fff, 0x87224C2EU, 0x8E645FB7U },
- { 0x3FFE - 0x3fff, 0x95A02568U, 0x095A0257U },
- { 0x3FFE - 0x3fff, 0x897B8CACU, 0x9F7DE298U },
- { 0x3FFE - 0x3fff, 0x94458094U, 0x45809446U },
- { 0x3FFE - 0x3fff, 0x8BCF55DEU, 0xC4CD05FEU },
- { 0x3FFE - 0x3fff, 0x92F11384U, 0x0497889CU },
- { 0x3FFE - 0x3fff, 0x8E1DC0FBU, 0x89E125E5U },
- { 0x3FFE - 0x3fff, 0x91A2B3C4U, 0xD5E6F809U },
- { 0x3FFE - 0x3fff, 0x9066E68CU, 0x955B6C9BU },
- { 0x3FFE - 0x3fff, 0x905A3863U, 0x3E06C43BU },
- { 0x3FFE - 0x3fff, 0x92AADE74U, 0xC7BE59E0U },
- { 0x3FFE - 0x3fff, 0x8F1779D9U, 0xFDC3A219U },
- { 0x3FFE - 0x3fff, 0x94E9BFF6U, 0x15845643U },
- { 0x3FFE - 0x3fff, 0x8DDA5202U, 0x37694809U },
- { 0x3FFE - 0x3fff, 0x9723A1B7U, 0x20134203U },
- { 0x3FFE - 0x3fff, 0x8CA29C04U, 0x6514E023U },
- { 0x3FFE - 0x3fff, 0x995899C8U, 0x90EB8990U },
- { 0x3FFE - 0x3fff, 0x8B70344AU, 0x139BC75AU },
- { 0x3FFE - 0x3fff, 0x9B88BDAAU, 0x3A3DAE2FU },
- { 0x3FFE - 0x3fff, 0x8A42F870U, 0x5669DB46U },
- { 0x3FFE - 0x3fff, 0x9DB4224FU, 0xFFE1157CU },
- { 0x3FFE - 0x3fff, 0x891AC73AU, 0xE9819B50U },
- { 0x3FFE - 0x3fff, 0x9FDADC26U, 0x8B7A12DAU },
- { 0x3FFE - 0x3fff, 0x87F78087U, 0xF78087F8U },
- { 0x3FFE - 0x3fff, 0xA1FCFF17U, 0xCE733BD4U },
- { 0x3FFE - 0x3fff, 0x86D90544U, 0x7A34ACC6U },
- { 0x3FFE - 0x3fff, 0xA41A9E8FU, 0x5446FB9FU },
- { 0x3FFE - 0x3fff, 0x85BF3761U, 0x2CEE3C9BU },
- { 0x3FFE - 0x3fff, 0xA633CD7EU, 0x6771CD8BU },
- { 0x3FFE - 0x3fff, 0x84A9F9C8U, 0x084A9F9DU },
- { 0x3FFE - 0x3fff, 0xA8489E60U, 0x0B435A5EU },
- { 0x3FFE - 0x3fff, 0x83993052U, 0x3FBE3368U },
- { 0x3FFE - 0x3fff, 0xAA59233CU, 0xCCA4BD49U },
- { 0x3FFE - 0x3fff, 0x828CBFBEU, 0xB9A020A3U },
- { 0x3FFE - 0x3fff, 0xAC656DAEU, 0x6BCC4985U },
- { 0x3FFE - 0x3fff, 0x81848DA8U, 0xFAF0D277U },
- { 0x3FFE - 0x3fff, 0xAE6D8EE3U, 0x60BB2468U },
- { 0x3FFE - 0x3fff, 0x80808080U, 0x80808081U },
- { 0x3FFE - 0x3fff, 0xB07197A2U, 0x3C46C654U },
-};
-
-struct fpn *__fpu_logn(struct fpemu *fe);
-
-/*
- * natural log - algorithm taken from Motorola FPSP,
- * except this doesn't bother to check for invalid input.
- */
-struct fpn *
-__fpu_logn(fe)
- struct fpemu *fe;
-{
- static struct fpn X, F, U, V, W, KLOG2;
- struct fpn *d;
- int i, k;
-
- CPYFPN(&X, &fe->fe_f2);
-
- /* see if |X-1| < 1/16 approx. */
- if ((-1 == X.fp_exp && (0xf07d0000U >> (31 - FP_LG)) <= X.fp_mant[0]) ||
- (0 == X.fp_exp && X.fp_mant[0] <= (0x88410000U >> (31 - FP_LG)))) {
- /* log near 1 */
-#if FPE_DEBUG
- printf("__fpu_logn: log near 1\n");
-#endif
-
- fpu_const(&fe->fe_f1, 0x32);
- /* X+1 */
- d = fpu_add(fe);
- CPYFPN(&V, d);
-
- CPYFPN(&fe->fe_f1, &X);
- fpu_const(&fe->fe_f2, 0x32); /* 1.0 */
- fe->fe_f2.fp_sign = 1; /* -1.0 */
- /* X-1 */
- d = fpu_add(fe);
- CPYFPN(&fe->fe_f1, d);
- /* 2(X-1) */
- fe->fe_f1.fp_exp++; /* *= 2 */
- CPYFPN(&fe->fe_f2, &V);
- /* U=2(X-1)/(X+1) */
- d = fpu_div(fe);
- CPYFPN(&U, d);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, d);
- /* V=U*U */
- d = fpu_mul(fe);
- CPYFPN(&V, d);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, d);
- /* W=V*V */
- d = fpu_mul(fe);
- CPYFPN(&W, d);
-
- /* calculate U+U*V*([B1+W*(B3+W*B5)]+[V*(B2+W*B4)]) */
-
- /* B1+W*(B3+W*B5) part */
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB5);
- /* W*B5 */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB3);
- /* B3+W*B5 */
- d = fpu_add(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &W);
- /* W*(B3+W*B5) */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB1);
- /* B1+W*(B3+W*B5) */
- d = fpu_add(fe);
- CPYFPN(&X, d);
-
- /* [V*(B2+W*B4)] part */
- CPYFPN(&fe->fe_f1, &W);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB4);
- /* W*B4 */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logB2);
- /* B2+W*B4 */
- d = fpu_add(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &V);
- /* V*(B2+W*B4) */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &X);
- /* B1+W*(B3+W*B5)+V*(B2+W*B4) */
- d = fpu_add(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &V);
- /* V*(B1+W*(B3+W*B5)+V*(B2+W*B4)) */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &U);
- /* U*V*(B1+W*(B3+W*B5)+V*(B2+W*B4)) */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &U);
- /* U+U*V*(B1+W*(B3+W*B5)+V*(B2+W*B4)) */
- d = fpu_add(fe);
- } else /* the usual case */ {
-#if FPE_DEBUG
- printf("__fpu_logn: the usual case. X=(%d,%08x,%08x...)\n",
- X.fp_exp, X.fp_mant[0], X.fp_mant[1]);
-#endif
-
- k = X.fp_exp;
- /* X <- Y */
- X.fp_exp = fe->fe_f2.fp_exp = 0;
-
- /* get the most significant 7 bits of X */
- F.fp_class = FPC_NUM;
- F.fp_sign = 0;
- F.fp_exp = X.fp_exp;
- F.fp_mant[0] = X.fp_mant[0] & (0xfe000000U >> (31 - FP_LG));
- F.fp_mant[0] |= (0x01000000U >> (31 - FP_LG));
- F.fp_mant[1] = F.fp_mant[2] = 0;
- F.fp_sticky = 0;
-
-#if FPE_DEBUG
- printf("__fpu_logn: X=Y*2^k=(%d,%08x,%08x...)*2^%d\n",
- fe->fe_f2.fp_exp, fe->fe_f2.fp_mant[0],
- fe->fe_f2.fp_mant[1], k);
- printf("__fpu_logn: F=(%d,%08x,%08x...)\n",
- F.fp_exp, F.fp_mant[0], F.fp_mant[1]);
-#endif
-
- /* index to the table */
- i = (F.fp_mant[0] >> (FP_LG - 7)) & 0x7e;
-
-#if FPE_DEBUG
- printf("__fpu_logn: index to logtbl i=%d(%x)\n", i, i);
-#endif
-
- CPYFPN(&fe->fe_f1, &F);
- /* -F */
- fe->fe_f1.fp_sign = 1;
- /* Y-F */
- d = fpu_add(fe);
- CPYFPN(&fe->fe_f1, d);
-
- /* fe_f2 = 1/F */
- fe->fe_f2.fp_class = FPC_NUM;
- fe->fe_f2.fp_sign = fe->fe_f2.fp_sticky = fe->fe_f2.fp_mant[2] = 0;
- fe->fe_f2.fp_exp = logtbl[i].sp_exp;
- fe->fe_f2.fp_mant[0] = (logtbl[i].sp_m0 >> (31 - FP_LG));
- fe->fe_f2.fp_mant[1] = (logtbl[i].sp_m0 << (FP_LG + 1)) |
- (logtbl[i].sp_m1 >> (31 - FP_LG));
- fe->fe_f2.fp_mant[2] = (u_int)(logtbl[i].sp_m1 << (FP_LG + 1));
-
-#if FPE_DEBUG
- printf("__fpu_logn: 1/F=(%d,%08x,%08x...)\n", fe->fe_f2.fp_exp,
- fe->fe_f2.fp_mant[0], fe->fe_f2.fp_mant[1]);
-#endif
-
- /* U = (Y-F) * (1/F) */
- d = fpu_mul(fe);
- CPYFPN(&U, d);
-
- /* KLOG2 = K * ln(2) */
- /* fe_f1 == (fpn)k */
- fpu_explode(fe, &fe->fe_f1, FTYPE_LNG, &k);
- (void)fpu_const(&fe->fe_f2, 0x30 /* ln(2) */);
-#if FPE_DEBUG
- printf("__fpu_logn: fp(k)=(%d,%08x,%08x...)\n", fe->fe_f1.fp_exp,
- fe->fe_f1.fp_mant[0], fe->fe_f1.fp_mant[1]);
- printf("__fpu_logn: ln(2)=(%d,%08x,%08x...)\n", fe->fe_f2.fp_exp,
- fe->fe_f2.fp_mant[0], fe->fe_f2.fp_mant[1]);
-#endif
- /* K * LOGOF2 */
- d = fpu_mul(fe);
- CPYFPN(&KLOG2, d);
-
- /* V=U*U */
- CPYFPN(&fe->fe_f1, &U);
- CPYFPN(&fe->fe_f2, &U);
- d = fpu_mul(fe);
- CPYFPN(&V, d);
-
- /*
- * approximation of LOG(1+U) by
- * (U+V*(A1+V*(A3+V*A5)))+(U*V*(A2+V*(A4+V*A6)))
- */
-
- /* (U+V*(A1+V*(A3+V*A5))) part */
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA5);
- /* V*A5 */
- d = fpu_mul(fe);
-
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA3);
- /* A3+V*A5 */
- d = fpu_add(fe);
-
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &V);
- /* V*(A3+V*A5) */
- d = fpu_mul(fe);
-
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA1);
- /* A1+V*(A3+V*A5) */
- d = fpu_add(fe);
-
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &V);
- /* V*(A1+V*(A3+V*A5)) */
- d = fpu_mul(fe);
-
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &U);
- /* U+V*(A1+V*(A3+V*A5)) */
- d = fpu_add(fe);
-
- CPYFPN(&X, d);
-
- /* (U*V*(A2+V*(A4+V*A6))) part */
- CPYFPN(&fe->fe_f1, &V);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA6);
- /* V*A6 */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA4);
- /* A4+V*A6 */
- d = fpu_add(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &V);
- /* V*(A4+V*A6) */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- fpu_explode(fe, &fe->fe_f2, FTYPE_DBL, logA2);
- /* A2+V*(A4+V*A6) */
- d = fpu_add(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &V);
- /* V*(A2+V*(A4+V*A6)) */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &U);
- /* U*V*(A2+V*(A4+V*A6)) */
- d = fpu_mul(fe);
- CPYFPN(&fe->fe_f1, d);
- i++;
- /* fe_f2 = logtbl[i+1] (== LOG(F)) */
- fe->fe_f2.fp_class = FPC_NUM;
- fe->fe_f2.fp_sign = fe->fe_f2.fp_sticky = fe->fe_f2.fp_mant[2] = 0;
- fe->fe_f2.fp_exp = logtbl[i].sp_exp;
- fe->fe_f2.fp_mant[0] = (logtbl[i].sp_m0 >> (31 - FP_LG));
- fe->fe_f2.fp_mant[1] = (logtbl[i].sp_m0 << (FP_LG + 1)) |
- (logtbl[i].sp_m1 >> (31 - FP_LG));
- fe->fe_f2.fp_mant[2] = (logtbl[i].sp_m1 << (FP_LG + 1));
-
-#if FPE_DEBUG
- printf("__fpu_logn: ln(F)=(%d,%08x,%08x,...)\n", fe->fe_f2.fp_exp,
- fe->fe_f2.fp_mant[0], fe->fe_f2.fp_mant[1]);
-#endif
-
- /* LOG(F)+U*V*(A2+V*(A4+V*A6)) */
- d = fpu_add(fe);
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &X);
- /* LOG(F)+U+V*(A1+V*(A3+V*A5))+U*V*(A2+V*(A4+V*A6)) */
- d = fpu_add(fe);
-
-#if FPE_DEBUG
- printf("__fpu_logn: ln(Y)=(%c,%d,%08x,%08x,%08x)\n",
- d->fp_sign ? '-' : '+', d->fp_exp,
- d->fp_mant[0], d->fp_mant[1], d->fp_mant[2]);
-#endif
-
- CPYFPN(&fe->fe_f1, d);
- CPYFPN(&fe->fe_f2, &KLOG2);
- /* K*LOGOF2+LOG(F)+U+V*(A1+V*(A3+V*A5))+U*V*(A2+V*(A4+V*A6)) */
- d = fpu_add(fe);
- }
-
- return d;
-}
-
-struct fpn *
-fpu_log10(fe)
- struct fpemu *fe;
-{
- struct fpn *fp = &fe->fe_f2;
- u_int fpsr;
-
- fpsr = fe->fe_fpsr & ~FPSR_EXCP; /* clear all exceptions */
-
- if (fp->fp_class >= FPC_NUM) {
- if (fp->fp_sign) { /* negative number or Inf */
- fp = fpu_newnan(fe);
- fpsr |= FPSR_OPERR;
- } else if (fp->fp_class == FPC_NUM) {
- /* the real work here */
- fp = __fpu_logn(fe);
- if (fp != &fe->fe_f1)
- CPYFPN(&fe->fe_f1, fp);
- (void)fpu_const(&fe->fe_f2, 0x31 /* ln(10) */);
- fp = fpu_div(fe);
- } /* else if fp == +Inf, return +Inf */
- } else if (fp->fp_class == FPC_ZERO) {
- /* return -Inf */
- fp->fp_class = FPC_INF;
- fp->fp_sign = 1;
- fpsr |= FPSR_DZ;
- } else if (fp->fp_class == FPC_SNAN) {
- fpsr |= FPSR_SNAN;
- fp = fpu_newnan(fe);
- } else {
- fp = fpu_newnan(fe);
- }
-
- fe->fe_fpsr = fpsr;
-
- return fp;
-}
-
-struct fpn *
-fpu_log2(fe)
- struct fpemu *fe;
-{
- struct fpn *fp = &fe->fe_f2;
- u_int fpsr;
-
- fpsr = fe->fe_fpsr & ~FPSR_EXCP; /* clear all exceptions */
-
- if (fp->fp_class >= FPC_NUM) {
- if (fp->fp_sign) { /* negative number or Inf */
- fp = fpu_newnan(fe);
- fpsr |= FPSR_OPERR;
- } else if (fp->fp_class == FPC_NUM) {
- /* the real work here */
- if (fp->fp_mant[0] == FP_1 && fp->fp_mant[1] == 0 &&
- fp->fp_mant[2] == 0) {
- /* fp == 2.0 ^ exp <--> log2(fp) == exp */
- fpu_explode(fe, &fe->fe_f3, FTYPE_LNG, &fp->fp_exp);
- fp = &fe->fe_f3;
- } else {
- fp = __fpu_logn(fe);
- if (fp != &fe->fe_f1)
- CPYFPN(&fe->fe_f1, fp);
- (void)fpu_const(&fe->fe_f2, 0x30 /* ln(2) */);
- fp = fpu_div(fe);
- }
- } /* else if fp == +Inf, return +Inf */
- } else if (fp->fp_class == FPC_ZERO) {
- /* return -Inf */
- fp->fp_class = FPC_INF;
- fp->fp_sign = 1;
- fpsr |= FPSR_DZ;
- } else if (fp->fp_class == FPC_SNAN) {
- fpsr |= FPSR_SNAN;
- fp = fpu_newnan(fe);
- } else {
- fp = fpu_newnan(fe);
- }
-
- fe->fe_fpsr = fpsr;
- return fp;
-}
-
-struct fpn *
-fpu_logn(fe)
- struct fpemu *fe;
-{
- struct fpn *fp = &fe->fe_f2;
- u_int fpsr;
-
- fpsr = fe->fe_fpsr & ~FPSR_EXCP; /* clear all exceptions */
-
- if (fp->fp_class >= FPC_NUM) {
- if (fp->fp_sign) { /* negative number or Inf */
- fp = fpu_newnan(fe);
- fpsr |= FPSR_OPERR;
- } else if (fp->fp_class == FPC_NUM) {
- /* the real work here */
- fp = __fpu_logn(fe);
- } /* else if fp == +Inf, return +Inf */
- } else if (fp->fp_class == FPC_ZERO) {
- /* return -Inf */
- fp->fp_class = FPC_INF;
- fp->fp_sign = 1;
- fpsr |= FPSR_DZ;
- } else if (fp->fp_class == FPC_SNAN) {
- fpsr |= FPSR_SNAN;
- fp = fpu_newnan(fe);
- } else {
- fp = fpu_newnan(fe);
- }
-
- fe->fe_fpsr = fpsr;
-
- return fp;
-}
-
-struct fpn *
-fpu_lognp1(fe)
- struct fpemu *fe;
-{
- struct fpn *fp;
-
- /* build a 1.0 */
- fp = fpu_const(&fe->fe_f1, 0x32); /* get 1.0 */
- /* fp = 1.0 + f2 */
- fp = fpu_add(fe);
-
- /* copy the result to the src opr */
- if (&fe->fe_f2 != fp)
- CPYFPN(&fe->fe_f2, fp);
-
- return fpu_logn(fe);
-}
diff --git a/sys/arch/m68k/fpe/fpu_mul.c b/sys/arch/m68k/fpe/fpu_mul.c
deleted file mode 100644
index e1027ad4f4c..00000000000
--- a/sys/arch/m68k/fpe/fpu_mul.c
+++ /dev/null
@@ -1,212 +0,0 @@
-/* $OpenBSD: fpu_mul.c,v 1.5 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_mul.c,v 1.4 2003/08/07 16:28:11 agc Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- * @(#)fpu_mul.c 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Perform an FPU multiply (return x * y).
- */
-
-#include <sys/types.h>
-
-#include <machine/reg.h>
-
-#include <m68k/fpe/fpu_arith.h>
-#include <m68k/fpe/fpu_emulate.h>
-
-/*
- * The multiplication algorithm for normal numbers is as follows:
- *
- * The fraction of the product is built in the usual stepwise fashion.
- * Each step consists of shifting the accumulator right one bit
- * (maintaining any guard bits) and, if the next bit in y is set,
- * adding the multiplicand (x) to the accumulator. Then, in any case,
- * we advance one bit leftward in y. Algorithmically:
- *
- * A = 0;
- * for (bit = 0; bit < FP_NMANT; bit++) {
- * sticky |= A & 1, A >>= 1;
- * if (Y & (1 << bit))
- * A += X;
- * }
- *
- * (X and Y here represent the mantissas of x and y respectively.)
- * The resultant accumulator (A) is the product's mantissa. It may
- * be as large as 11.11111... in binary and hence may need to be
- * shifted right, but at most one bit.
- *
- * Since we do not have efficient multiword arithmetic, we code the
- * accumulator as four separate words, just like any other mantissa.
- * We use local variables in the hope that this may be faster
- * than memory. We keep x->fp_mant in locals for the same reason.
- *
- * In the algorithm above, the bits in y are inspected one at a time.
- * We will pick them up 32 at a time and then deal with those 32, one
- * at a time. Note, however, that we know several things about y:
- *
- * - the guard and round bits at the bottom are sure to be zero;
- *
- * - often many low bits are zero (y is often from a single or double
- * precision source);
- *
- * - bit FP_NMANT-1 is set, and FP_1*2 fits in a word.
- *
- * We can also test for 32-zero-bits swiftly. In this case, the center
- * part of the loop---setting sticky, shifting A, and not adding---will
- * run 32 times without adding X to A. We can do a 32-bit shift faster
- * by simply moving words. Since zeros are common, we optimize this case.
- * Furthermore, since A is initially zero, we can omit the shift as well
- * until we reach a nonzero word.
- */
-struct fpn *
-fpu_mul(fe)
- struct fpemu *fe;
-{
- struct fpn *x = &fe->fe_f1, *y = &fe->fe_f2;
- u_int a2, a1, a0, x2, x1, x0, bit, m;
- int sticky;
- FPU_DECL_CARRY
-
- /*
- * Put the `heavier' operand on the right (see fpu_emu.h).
- * Then we will have one of the following cases, taken in the
- * following order:
- *
- * - y = NaN. Implied: if only one is a signalling NaN, y is.
- * The result is y.
- * - y = Inf. Implied: x != NaN (is 0, number, or Inf: the NaN
- * case was taken care of earlier).
- * If x = 0, the result is NaN. Otherwise the result
- * is y, with its sign reversed if x is negative.
- * - x = 0. Implied: y is 0 or number.
- * The result is 0 (with XORed sign as usual).
- * - other. Implied: both x and y are numbers.
- * The result is x * y (XOR sign, multiply bits, add exponents).
- */
- ORDER(x, y);
- if (ISNAN(y)) {
- y->fp_sign ^= x->fp_sign;
- return (y);
- }
- if (ISINF(y)) {
- if (ISZERO(x))
- return (fpu_newnan(fe));
- y->fp_sign ^= x->fp_sign;
- return (y);
- }
- if (ISZERO(x)) {
- x->fp_sign ^= y->fp_sign;
- return (x);
- }
-
- /*
- * Setup. In the code below, the mask `m' will hold the current
- * mantissa byte from y. The variable `bit' denotes the bit
- * within m. We also define some macros to deal with everything.
- */
- x2 = x->fp_mant[2];
- x1 = x->fp_mant[1];
- x0 = x->fp_mant[0];
- sticky = a2 = a1 = a0 = 0;
-
-#define ADD /* A += X */ \
- FPU_ADDS(a2, a2, x2); \
- FPU_ADDCS(a1, a1, x1); \
- FPU_ADDC(a0, a0, x0)
-
-#define SHR1 /* A >>= 1, with sticky */ \
- sticky |= a2 & 1, \
- a2 = (a2 >> 1) | (a1 << 31), a1 = (a1 >> 1) | (a0 << 31), a0 >>= 1
-
-#define SHR32 /* A >>= 32, with sticky */ \
- sticky |= a2, a2 = a1, a1 = a0, a0 = 0
-
-#define STEP /* each 1-bit step of the multiplication */ \
- SHR1; if (bit & m) { ADD; }; bit <<= 1
-
- /*
- * We are ready to begin. The multiply loop runs once for each
- * of the four 32-bit words. Some words, however, are special.
- * As noted above, the low order bits of Y are often zero. Even
- * if not, the first loop can certainly skip the guard bits.
- * The last word of y has its highest 1-bit in position FP_NMANT-1,
- * so we stop the loop when we move past that bit.
- */
- if ((m = y->fp_mant[2]) == 0) {
- /* SHR32; */ /* unneeded since A==0 */
- } else {
- bit = 1 << FP_NG;
- do {
- STEP;
- } while (bit != 0);
- }
- if ((m = y->fp_mant[1]) == 0) {
- SHR32;
- } else {
- bit = 1;
- do {
- STEP;
- } while (bit != 0);
- }
- m = y->fp_mant[0]; /* definitely != 0 */
- bit = 1;
- do {
- STEP;
- } while (bit <= m);
-
- /*
- * Done with mantissa calculation. Get exponent and handle
- * 11.111...1 case, then put result in place. We reuse x since
- * it already has the right class (FP_NUM).
- */
- m = x->fp_exp + y->fp_exp;
- if (a0 >= FP_2) {
- SHR1;
- m++;
- }
- x->fp_sign ^= y->fp_sign;
- x->fp_exp = m;
- x->fp_sticky = sticky;
- x->fp_mant[2] = a2;
- x->fp_mant[1] = a1;
- x->fp_mant[0] = a0;
- return (x);
-}
diff --git a/sys/arch/m68k/fpe/fpu_rem.c b/sys/arch/m68k/fpe/fpu_rem.c
deleted file mode 100644
index 5e8d76b4c39..00000000000
--- a/sys/arch/m68k/fpe/fpu_rem.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/* $OpenBSD: fpu_rem.c,v 1.5 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_rem.c,v 1.5 2003/07/15 02:43:10 lukem Exp $ */
-
-/*
- * Copyright (c) 1995 Ken Nakata
- * All rights reserved.
- *
- * 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. Neither the name of the author nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- *
- * @(#)fpu_rem.c 10/24/95
- */
-
-#include <sys/types.h>
-#include <sys/signal.h>
-#include <machine/frame.h>
-
-#include <m68k/fpe/fpu_emulate.h>
-
-/*
- * ALGORITHM
- *
- * Step 1. Save and strip signs of X and Y: signX := sign(X),
- * signY := sign(Y), X := *X*, Y := *Y*,
- * signQ := signX EOR signY. Record whether MOD or REM
- * is requested.
- *
- * Step 2. Set L := expo(X)-expo(Y), k := 0, Q := 0.
- * If (L < 0) then
- * R := X, go to Step 4.
- * else
- * R := 2^(-L)X, j := L.
- * endif
- *
- * Step 3. Perform MOD(X,Y)
- * 3.1 If R = Y, go to Step 9.
- * 3.2 If R > Y, then { R := R - Y, Q := Q + 1}
- * 3.3 If j = 0, go to Step 4.
- * 3.4 k := k + 1, j := j - 1, Q := 2Q, R := 2R. Go to
- * Step 3.1.
- *
- * Step 4. At this point, R = X - QY = MOD(X,Y). Set
- * Last_Subtract := false (used in Step 7 below). If
- * MOD is requested, go to Step 6.
- *
- * Step 5. R = MOD(X,Y), but REM(X,Y) is requested.
- * 5.1 If R < Y/2, then R = MOD(X,Y) = REM(X,Y). Go to
- * Step 6.
- * 5.2 If R > Y/2, then { set Last_Subtract := true,
- * Q := Q + 1, Y := signY*Y }. Go to Step 6.
- * 5.3 This is the tricky case of R = Y/2. If Q is odd,
- * then { Q := Q + 1, signX := -signX }.
- *
- * Step 6. R := signX*R.
- *
- * Step 7. If Last_Subtract = true, R := R - Y.
- *
- * Step 8. Return signQ, last 7 bits of Q, and R as required.
- *
- * Step 9. At this point, R = 2^(-j)*X - Q Y = Y. Thus,
- * X = 2^(j)*(Q+1)Y. set Q := 2^(j)*(Q+1),
- * R := 0. Return signQ, last 7 bits of Q, and R.
- */
-
-struct fpn *__fpu_modrem(struct fpemu *fe, int modrem);
-
-struct fpn *
-__fpu_modrem(fe, modrem)
- struct fpemu *fe;
- int modrem;
-{
- static struct fpn X, Y;
- struct fpn *x, *y, *r;
- u_int signX, signY, signQ;
- int j, k, l, q;
- int Last_Subtract;
-
- CPYFPN(&X, &fe->fe_f1);
- CPYFPN(&Y, &fe->fe_f2);
- x = &X;
- y = &Y;
- r = &fe->fe_f2;
-
- /*
- * Step 1
- */
- signX = x->fp_sign;
- signY = y->fp_sign;
- signQ = (signX ^ signY);
- x->fp_sign = y->fp_sign = 0;
-
- /*
- * Step 2
- */
- l = x->fp_exp - y->fp_exp;
- k = 0;
- q = 0;
- if (l >= 0) {
- CPYFPN(r, x);
- r->fp_exp -= l;
- j = l;
-
- /*
- * Step 3
- */
- while (y->fp_exp != r->fp_exp || y->fp_mant[0] != r->fp_mant[0] ||
- y->fp_mant[1] != r->fp_mant[1] ||
- y->fp_mant[2] != r->fp_mant[2]) {
-
- /* Step 3.2 */
- if (y->fp_exp < r->fp_exp || y->fp_mant[0] < r->fp_mant[0] ||
- y->fp_mant[1] < r->fp_mant[1] ||
- y->fp_mant[2] < r->fp_mant[2]) {
- CPYFPN(&fe->fe_f1, r);
- CPYFPN(&fe->fe_f2, y);
- fe->fe_f2.fp_sign = 1;
- r = fpu_add(fe);
- q++;
- }
-
- /* Step 3.3 */
- if (j == 0)
- goto Step4;
-
- /* Step 3.4 */
- k++;
- j--;
- q += q;
- r->fp_exp++;
- }
- /* Step 9 */
- goto Step9;
- }
- Step4:
- Last_Subtract = 0;
- if (modrem == 0)
- goto Step6;
-
- /*
- * Step 5
- */
- /* Step 5.1 */
- if (r->fp_exp + 1 < y->fp_exp ||
- (r->fp_exp + 1 == y->fp_exp &&
- (r->fp_mant[0] < y->fp_mant[0] || r->fp_mant[1] < y->fp_mant[1] ||
- r->fp_mant[2] < y->fp_mant[2])))
- /* if r < y/2 */
- goto Step6;
- /* Step 5.2 */
- if (r->fp_exp + 1 != y->fp_exp ||
- r->fp_mant[0] != y->fp_mant[0] || r->fp_mant[1] != y->fp_mant[1] ||
- r->fp_mant[2] != y->fp_mant[2]) {
- /* if (!(r < y/2) && !(r == y/2)) */
- Last_Subtract = 1;
- q++;
- y->fp_sign = signY;
- } else {
- /* Step 5.3 */
- /* r == y/2 */
- if (q % 2) {
- q++;
- signX = !signX;
- }
- }
-
- Step6:
- r->fp_sign = signX;
-
- /*
- * Step 7
- */
- if (Last_Subtract) {
- CPYFPN(&fe->fe_f1, r);
- CPYFPN(&fe->fe_f2, y);
- fe->fe_f2.fp_sign = !y->fp_sign;
- r = fpu_add(fe);
- }
- /*
- * Step 8
- */
- q &= 0x7f;
- q |= (signQ << 7);
- fe->fe_fpframe->fpf_fpsr =
- fe->fe_fpsr =
- (fe->fe_fpsr & ~FPSR_QTT) | (q << 16);
- return r;
-
- Step9:
- fe->fe_f1.fp_class = FPC_ZERO;
- q++;
- q &= 0x7f;
- q |= (signQ << 7);
- fe->fe_fpframe->fpf_fpsr =
- fe->fe_fpsr =
- (fe->fe_fpsr & ~FPSR_QTT) | (q << 16);
- return &fe->fe_f1;
-}
-
-struct fpn *
-fpu_rem(fe)
- struct fpemu *fe;
-{
- return __fpu_modrem(fe, 1);
-}
-
-struct fpn *
-fpu_mod(fe)
- struct fpemu *fe;
-{
- return __fpu_modrem(fe, 0);
-}
diff --git a/sys/arch/m68k/fpe/fpu_sqrt.c b/sys/arch/m68k/fpe/fpu_sqrt.c
deleted file mode 100644
index c45a61c51c9..00000000000
--- a/sys/arch/m68k/fpe/fpu_sqrt.c
+++ /dev/null
@@ -1,360 +0,0 @@
-/* $OpenBSD: fpu_sqrt.c,v 1.5 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_sqrt.c,v 1.4 2003/08/07 16:28:12 agc Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- * @(#)fpu_sqrt.c 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * Perform an FPU square root (return sqrt(x)).
- */
-
-#include <sys/types.h>
-
-#include <machine/reg.h>
-
-#include <m68k/fpe/fpu_arith.h>
-#include <m68k/fpe/fpu_emulate.h>
-
-/*
- * Our task is to calculate the square root of a floating point number x0.
- * This number x normally has the form:
- *
- * exp
- * x = mant * 2 (where 1 <= mant < 2 and exp is an integer)
- *
- * This can be left as it stands, or the mantissa can be doubled and the
- * exponent decremented:
- *
- * exp-1
- * x = (2 * mant) * 2 (where 2 <= 2 * mant < 4)
- *
- * If the exponent `exp' is even, the square root of the number is best
- * handled using the first form, and is by definition equal to:
- *
- * exp/2
- * sqrt(x) = sqrt(mant) * 2
- *
- * If exp is odd, on the other hand, it is convenient to use the second
- * form, giving:
- *
- * (exp-1)/2
- * sqrt(x) = sqrt(2 * mant) * 2
- *
- * In the first case, we have
- *
- * 1 <= mant < 2
- *
- * and therefore
- *
- * sqrt(1) <= sqrt(mant) < sqrt(2)
- *
- * while in the second case we have
- *
- * 2 <= 2*mant < 4
- *
- * and therefore
- *
- * sqrt(2) <= sqrt(2*mant) < sqrt(4)
- *
- * so that in any case, we are sure that
- *
- * sqrt(1) <= sqrt(n * mant) < sqrt(4), n = 1 or 2
- *
- * or
- *
- * 1 <= sqrt(n * mant) < 2, n = 1 or 2.
- *
- * This root is therefore a properly formed mantissa for a floating
- * point number. The exponent of sqrt(x) is either exp/2 or (exp-1)/2
- * as above. This leaves us with the problem of finding the square root
- * of a fixed-point number in the range [1..4).
- *
- * Though it may not be instantly obvious, the following square root
- * algorithm works for any integer x of an even number of bits, provided
- * that no overflows occur:
- *
- * let q = 0
- * for k = NBITS-1 to 0 step -1 do -- for each digit in the answer...
- * x *= 2 -- multiply by radix, for next digit
- * if x >= 2q + 2^k then -- if adding 2^k does not
- * x -= 2q + 2^k -- exceed the correct root,
- * q += 2^k -- add 2^k and adjust x
- * fi
- * done
- * sqrt = q / 2^(NBITS/2) -- (and any remainder is in x)
- *
- * If NBITS is odd (so that k is initially even), we can just add another
- * zero bit at the top of x. Doing so means that q is not going to acquire
- * a 1 bit in the first trip around the loop (since x0 < 2^NBITS). If the
- * final value in x is not needed, or can be off by a factor of 2, this is
- * equivalant to moving the `x *= 2' step to the bottom of the loop:
- *
- * for k = NBITS-1 to 0 step -1 do if ... fi; x *= 2; done
- *
- * and the result q will then be sqrt(x0) * 2^floor(NBITS / 2).
- * (Since the algorithm is destructive on x, we will call x's initial
- * value, for which q is some power of two times its square root, x0.)
- *
- * If we insert a loop invariant y = 2q, we can then rewrite this using
- * C notation as:
- *
- * q = y = 0; x = x0;
- * for (k = NBITS; --k >= 0;) {
- * #if (NBITS is even)
- * x *= 2;
- * #endif
- * t = y + (1 << k);
- * if (x >= t) {
- * x -= t;
- * q += 1 << k;
- * y += 1 << (k + 1);
- * }
- * #if (NBITS is odd)
- * x *= 2;
- * #endif
- * }
- *
- * If x0 is fixed point, rather than an integer, we can simply alter the
- * scale factor between q and sqrt(x0). As it happens, we can easily arrange
- * for the scale factor to be 2**0 or 1, so that sqrt(x0) == q.
- *
- * In our case, however, x0 (and therefore x, y, q, and t) are multiword
- * integers, which adds some complication. But note that q is built one
- * bit at a time, from the top down, and is not used itself in the loop
- * (we use 2q as held in y instead). This means we can build our answer
- * in an integer, one word at a time, which saves a bit of work. Also,
- * since 1 << k is always a `new' bit in q, 1 << k and 1 << (k+1) are
- * `new' bits in y and we can set them with an `or' operation rather than
- * a full-blown multiword add.
- *
- * We are almost done, except for one snag. We must prove that none of our
- * intermediate calculations can overflow. We know that x0 is in [1..4)
- * and therefore the square root in q will be in [1..2), but what about x,
- * y, and t?
- *
- * We know that y = 2q at the beginning of each loop. (The relation only
- * fails temporarily while y and q are being updated.) Since q < 2, y < 4.
- * The sum in t can, in our case, be as much as y+(1<<1) = y+2 < 6, and.
- * Furthermore, we can prove with a bit of work that x never exceeds y by
- * more than 2, so that even after doubling, 0 <= x < 8. (This is left as
- * an exercise to the reader, mostly because I have become tired of working
- * on this comment.)
- *
- * If our floating point mantissas (which are of the form 1.frac) occupy
- * B+1 bits, our largest intermediary needs at most B+3 bits, or two extra.
- * In fact, we want even one more bit (for a carry, to avoid compares), or
- * three extra. There is a comment in fpu_emu.h reminding maintainers of
- * this, so we have some justification in assuming it.
- */
-struct fpn *
-fpu_sqrt(fe)
- struct fpemu *fe;
-{
- struct fpn *x = &fe->fe_f2;
- u_int bit, q, tt;
- u_int x0, x1, x2;
- u_int y0, y1, y2;
- u_int d0, d1, d2;
- int e;
- FPU_DECL_CARRY
-
- /*
- * Take care of special cases first. In order:
- *
- * sqrt(NaN) = NaN
- * sqrt(+0) = +0
- * sqrt(-0) = -0
- * sqrt(x < 0) = NaN (including sqrt(-Inf))
- * sqrt(+Inf) = +Inf
- *
- * Then all that remains are numbers with mantissas in [1..2).
- */
- if (ISNAN(x) || ISZERO(x))
- return (x);
- if (x->fp_sign)
- return (fpu_newnan(fe));
- if (ISINF(x))
- return (x);
-
- /*
- * Calculate result exponent. As noted above, this may involve
- * doubling the mantissa. We will also need to double x each
- * time around the loop, so we define a macro for this here, and
- * we break out the multiword mantissa.
- */
-#ifdef FPU_SHL1_BY_ADD
-#define DOUBLE_X { \
- FPU_ADDS(x2, x2, x2); \
- FPU_ADDCS(x1, x1, x1); FPU_ADDC(x0, x0, x0); \
-}
-#else
-#define DOUBLE_X { \
- x0 = (x0 << 1) | (x1 >> 31); x1 = (x1 << 1) | (x2 >> 31); \
- x2 <<= 1; \
-}
-#endif
-#if (FP_NMANT & 1) != 0
-# define ODD_DOUBLE DOUBLE_X
-# define EVEN_DOUBLE /* nothing */
-#else
-# define ODD_DOUBLE /* nothing */
-# define EVEN_DOUBLE DOUBLE_X
-#endif
- x0 = x->fp_mant[0];
- x1 = x->fp_mant[1];
- x2 = x->fp_mant[2];
- e = x->fp_exp;
- if (e & 1) /* exponent is odd; use sqrt(2mant) */
- DOUBLE_X;
- /* THE FOLLOWING ASSUMES THAT RIGHT SHIFT DOES SIGN EXTENSION */
- x->fp_exp = e >> 1; /* calculates (e&1 ? (e-1)/2 : e/2 */
-
- /*
- * Now calculate the mantissa root. Since x is now in [1..4),
- * we know that the first trip around the loop will definitely
- * set the top bit in q, so we can do that manually and start
- * the loop at the next bit down instead. We must be sure to
- * double x correctly while doing the `known q=1.0'.
- *
- * We do this one mantissa-word at a time, as noted above, to
- * save work. To avoid `(1 << 31) << 1', we also do the top bit
- * outside of each per-word loop.
- *
- * The calculation `t = y + bit' breaks down into `t0 = y0, ...,
- * t2 = y2, t? |= bit' for the appropriate word. Since the bit
- * is always a `new' one, this means that three of the `t?'s are
- * just the corresponding `y?'; we use `#define's here for this.
- * The variable `tt' holds the actual `t?' variable.
- */
-
- /* calculate q0 */
-#define t0 tt
- bit = FP_1;
- EVEN_DOUBLE;
- /* if (x >= (t0 = y0 | bit)) { */ /* always true */
- q = bit;
- x0 -= bit;
- y0 = bit << 1;
- /* } */
- ODD_DOUBLE;
- while ((bit >>= 1) != 0) { /* for remaining bits in q0 */
- EVEN_DOUBLE;
- t0 = y0 | bit; /* t = y + bit */
- if (x0 >= t0) { /* if x >= t then */
- x0 -= t0; /* x -= t */
- q |= bit; /* q += bit */
- y0 |= bit << 1; /* y += bit << 1 */
- }
- ODD_DOUBLE;
- }
- x->fp_mant[0] = q;
-#undef t0
-
- /* calculate q1. note (y0&1)==0. */
-#define t0 y0
-#define t1 tt
- q = 0;
- y1 = 0;
- bit = 1 << 31;
- EVEN_DOUBLE;
- t1 = bit;
- FPU_SUBS(d1, x1, t1);
- FPU_SUBC(d0, x0, t0); /* d = x - t */
- if ((int)d0 >= 0) { /* if d >= 0 (i.e., x >= t) then */
- x0 = d0, x1 = d1; /* x -= t */
- q = bit; /* q += bit */
- y0 |= 1; /* y += bit << 1 */
- }
- ODD_DOUBLE;
- while ((bit >>= 1) != 0) { /* for remaining bits in q1 */
- EVEN_DOUBLE; /* as before */
- t1 = y1 | bit;
- FPU_SUBS(d1, x1, t1);
- FPU_SUBC(d0, x0, t0);
- if ((int)d0 >= 0) {
- x0 = d0, x1 = d1;
- q |= bit;
- y1 |= bit << 1;
- }
- ODD_DOUBLE;
- }
- x->fp_mant[1] = q;
-#undef t1
-
- /* calculate q2. note (y1&1)==0; y0 (aka t0) is fixed. */
-#define t1 y1
-#define t2 tt
- q = 0;
- y2 = 0;
- bit = 1 << 31;
- EVEN_DOUBLE;
- t2 = bit;
- FPU_SUBS(d2, x2, t2);
- FPU_SUBCS(d1, x1, t1);
- FPU_SUBC(d0, x0, t0);
- if ((int)d0 >= 0) {
- x0 = d0, x1 = d1, x2 = d2;
- q |= bit;
- y1 |= 1; /* now t1, y1 are set in concrete */
- }
- ODD_DOUBLE;
- while ((bit >>= 1) != 0) {
- EVEN_DOUBLE;
- t2 = y2 | bit;
- FPU_SUBS(d2, x2, t2);
- FPU_SUBCS(d1, x1, t1);
- FPU_SUBC(d0, x0, t0);
- if ((int)d0 >= 0) {
- x0 = d0, x1 = d1, x2 = d2;
- q |= bit;
- y2 |= bit << 1;
- }
- ODD_DOUBLE;
- }
- x->fp_mant[2] = q;
-#undef t2
-
- /*
- * The result, which includes guard and round bits, is exact iff
- * x is now zero; any nonzero bits in x represent sticky bits.
- */
- x->fp_sticky = x0 | x1 | x2;
- return (x);
-}
diff --git a/sys/arch/m68k/fpe/fpu_subr.c b/sys/arch/m68k/fpe/fpu_subr.c
deleted file mode 100644
index e59567d7c12..00000000000
--- a/sys/arch/m68k/fpe/fpu_subr.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* $OpenBSD: fpu_subr.c,v 1.5 2006/06/11 20:43:28 miod Exp $ */
-/* $NetBSD: fpu_subr.c,v 1.6 2003/08/07 16:28:12 agc Exp $ */
-
-/*
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This software was developed by the Computer Systems Engineering group
- * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
- * contributed to Berkeley.
- *
- * All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Lawrence Berkeley Laboratory.
- *
- * 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. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- *
- * @(#)fpu_subr.c 8.1 (Berkeley) 6/11/93
- */
-
-/*
- * FPU subroutines.
- */
-
-#include <sys/types.h>
-#include <sys/systm.h>
-
-#include <machine/reg.h>
-
-#include <m68k/fpe/fpu_emulate.h>
-#include <m68k/fpe/fpu_arith.h>
-
-/*
- * Shift the given number right rsh bits. Any bits that `fall off' will get
- * shoved into the sticky field; we return the resulting sticky. Note that
- * shifting NaNs is legal (this will never shift all bits out); a NaN's
- * sticky field is ignored anyway.
- */
-int
-fpu_shr(struct fpn *fp, int rsh)
-{
- u_int m0, m1, m2, s;
- int lsh;
-
-#ifdef DIAGNOSTIC
- if (rsh < 0 || (fp->fp_class != FPC_NUM && !ISNAN(fp)))
- panic("fpu_rightshift 1");
-#endif
-
- m0 = fp->fp_mant[0];
- m1 = fp->fp_mant[1];
- m2 = fp->fp_mant[2];
-
- /* If shifting all the bits out, take a shortcut. */
- if (rsh >= FP_NMANT) {
-#ifdef DIAGNOSTIC
- if ((m0 | m1 | m2) == 0)
- panic("fpu_rightshift 2");
-#endif
- fp->fp_mant[0] = 0;
- fp->fp_mant[1] = 0;
- fp->fp_mant[2] = 0;
-#ifdef notdef
- if ((m0 | m1 | m2) == 0)
- fp->fp_class = FPC_ZERO;
- else
-#endif
- fp->fp_sticky = 1;
- return (1);
- }
-
- /* Squish out full words. */
- s = fp->fp_sticky;
- if (rsh >= 32 * 2) {
- s |= m2 | m1;
- m2 = m0, m1 = 0, m0 = 0;
- } else if (rsh >= 32) {
- s |= m2;
- m2 = m1, m1 = m0, m0 = 0;
- }
-
- /* Handle any remaining partial word. */
- if ((rsh &= 31) != 0) {
- lsh = 32 - rsh;
- s |= m2 << lsh;
- m2 = (m2 >> rsh) | (m1 << lsh);
- m1 = (m1 >> rsh) | (m0 << lsh);
- m0 >>= rsh;
- }
- fp->fp_mant[0] = m0;
- fp->fp_mant[1] = m1;
- fp->fp_mant[2] = m2;
- fp->fp_sticky = s;
- return (s);
-}
-
-/*
- * Force a number to be normal, i.e., make its fraction have all zero
- * bits before FP_1, then FP_1, then all 1 bits. This is used for denorms
- * and (sometimes) for intermediate results.
- *
- * Internally, this may use a `supernormal' -- a number whose fp_mant
- * is greater than or equal to 2.0 -- so as a side effect you can hand it
- * a supernormal and it will fix it (provided fp->fp_mant[2] == 0).
- */
-void
-fpu_norm(struct fpn *fp)
-{
- u_int m0, m1, m2, sup, nrm;
- int lsh, rsh, exp;
-
- exp = fp->fp_exp;
- m0 = fp->fp_mant[0];
- m1 = fp->fp_mant[1];
- m2 = fp->fp_mant[2];
-
- /* Handle severe subnormals with 32-bit moves. */
- if (m0 == 0) {
- if (m1) {
- m0 = m1;
- m1 = m2;
- m2 = 0;
- exp -= 32;
- } else if (m2) {
- m0 = m2;
- m1 = 0;
- m2 = 0;
- exp -= 2 * 32;
- } else {
- fp->fp_class = FPC_ZERO;
- return;
- }
- }
-
- /* Now fix any supernormal or remaining subnormal. */
- nrm = FP_1;
- sup = nrm << 1;
- if (m0 >= sup) {
- /*
- * We have a supernormal number. We need to shift it right.
- * We may assume m2==0.
- */
- __asm __volatile("bfffo %1{#0:#32},%0" : "=d"(rsh) : "g"(m0));
- rsh = 31 - rsh - FP_LG;
- exp += rsh;
- lsh = 32 - rsh;
- m2 = m1 << lsh;
- m1 = (m1 >> rsh) | (m0 << lsh);
- m0 = (m0 >> rsh);
- } else if (m0 < nrm) {
- /*
- * We have a regular denorm (a subnormal number), and need
- * to shift it left.
- */
- __asm __volatile("bfffo %1{#0:#32},%0" : "=d"(lsh) : "g"(m0));
- lsh = FP_LG - 31 + lsh;
- exp -= lsh;
- rsh = 32 - lsh;
- m0 = (m0 << lsh) | (m1 >> rsh);
- m1 = (m1 << lsh) | (m2 >> rsh);
- m2 <<= lsh;
- }
-
- fp->fp_exp = exp;
- fp->fp_mant[0] = m0;
- fp->fp_mant[1] = m1;
- fp->fp_mant[2] = m2;
-}
-
-/*
- * Concoct a `fresh' Quiet NaN per Appendix N.
- * As a side effect, we set OPERR for the current exceptions.
- */
-struct fpn *
-fpu_newnan(struct fpemu *fe)
-{
- struct fpn *fp;
-
- fe->fe_fpsr |= FPSR_OPERR;
- fp = &fe->fe_f3;
- fp->fp_class = FPC_QNAN;
- fp->fp_sign = 0;
- fp->fp_mant[0] = FP_1 - 1;
- fp->fp_mant[1] = fp->fp_mant[2] = ~0;
- return (fp);
-}