Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/m68k/fpe PR 7220 from Ken Nakata:



details:   https://anonhg.NetBSD.org/src/rev/f5d77bc18a4b
branches:  trunk
changeset: 473355:f5d77bc18a4b
user:      briggs <briggs%NetBSD.org@localhost>
date:      Sun May 30 20:17:48 1999 +0000

description:
PR 7220 from Ken Nakata:
        I've fixed most (not all) m68k FPE bugs that give bogus
calculation results, esp. fsqrt instruction.  Also, the internal FP
representation has been reduced from 115-bit mantissa to 67-bit
mantissa which reduced the required mantissa operation roughly by one
fourth.  I've done an extensive (though not exhaustive - it's
impossible!) test on the internal routines by feeding them randomly
generated FP numbers, and found that the new code is more precise than
MC68040 FPU (it seems to have a rounding bug).

[ Only change was to keep fpu_calcea.c's name instead of renaming to
  fpu_ea.c in Ken's patch.  --akb ]

diffstat:

 sys/arch/m68k/fpe/fpu_add.c     |   14 +-
 sys/arch/m68k/fpe/fpu_arith.h   |  105 ++++---
 sys/arch/m68k/fpe/fpu_calcea.c  |  494 +++++++++++++++++++++----------------
 sys/arch/m68k/fpe/fpu_div.c     |   19 +-
 sys/arch/m68k/fpe/fpu_emulate.c |  522 +++++++++++++++++++--------------------
 sys/arch/m68k/fpe/fpu_emulate.h |   57 +--
 sys/arch/m68k/fpe/fpu_explode.c |    9 +-
 sys/arch/m68k/fpe/fpu_fmovecr.c |   56 ++--
 sys/arch/m68k/fpe/fpu_fscale.c  |  106 ++++----
 sys/arch/m68k/fpe/fpu_fstore.c  |   60 ++--
 sys/arch/m68k/fpe/fpu_implode.c |   65 ++--
 sys/arch/m68k/fpe/fpu_int.c     |   14 +-
 sys/arch/m68k/fpe/fpu_log.c     |   79 +++--
 sys/arch/m68k/fpe/fpu_mul.c     |   25 +-
 sys/arch/m68k/fpe/fpu_rem.c     |   12 +-
 sys/arch/m68k/fpe/fpu_sqrt.c    |   51 +---
 sys/arch/m68k/fpe/fpu_subr.c    |   75 ++---
 17 files changed, 880 insertions(+), 883 deletions(-)

diffs (truncated from 3301 to 300 lines):

diff -r 5a372ef10cc8 -r f5d77bc18a4b sys/arch/m68k/fpe/fpu_add.c
--- a/sys/arch/m68k/fpe/fpu_add.c       Sun May 30 19:13:33 1999 +0000
+++ b/sys/arch/m68k/fpe/fpu_add.c       Sun May 30 20:17:48 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_add.c,v 1.2 1996/04/30 11:52:09 briggs Exp $ */
+/*     $NetBSD: fpu_add.c,v 1.3 1999/05/30 20:17:48 briggs Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -63,7 +63,7 @@
        register struct fpemu *fe;
 {
        register struct fpn *x = &fe->fe_f1, *y = &fe->fe_f2, *r;
-       register u_int r0, r1, r2, r3;
+       register u_int r0, r1, r2;
        register int rd;
 
        /*
@@ -139,8 +139,7 @@
                 * (but remember to adjust the exponent).
                 */
                /* r->fp_mant = x->fp_mant + y->fp_mant */
-               FPU_ADDS(r->fp_mant[3], x->fp_mant[3], y->fp_mant[3]);
-               FPU_ADDCS(r->fp_mant[2], x->fp_mant[2], y->fp_mant[2]);
+               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) {
@@ -172,13 +171,12 @@
                 */
                /* r->fp_mant = x->fp_mant - y->fp_mant */
                FPU_SET_CARRY(y->fp_sticky);
-               FPU_SUBCS(r3, x->fp_mant[3], y->fp_mant[3]);
                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 | r3) == 0) {
+                       if ((r0 | r1 | r2) == 0) {
                                /* case ii */
                                r->fp_class = FPC_ZERO;
                                r->fp_sign = (rd == FPCR_MINF);
@@ -196,12 +194,10 @@
                                panic("fpu_add");
 #endif
                        r->fp_sign = y->fp_sign;
-                       FPU_SUBS(r3, 0, r3);
-                       FPU_SUBCS(r2, 0, r2);
+                       FPU_SUBS(r2, 0, r2);
                        FPU_SUBCS(r1, 0, r1);
                        FPU_SUBC(r0, 0, r0);
                }
-               r->fp_mant[3] = r3;
                r->fp_mant[2] = r2;
                r->fp_mant[1] = r1;
                r->fp_mant[0] = r0;
diff -r 5a372ef10cc8 -r f5d77bc18a4b sys/arch/m68k/fpe/fpu_arith.h
--- a/sys/arch/m68k/fpe/fpu_arith.h     Sun May 30 19:13:33 1999 +0000
+++ b/sys/arch/m68k/fpe/fpu_arith.h     Sun May 30 20:17:48 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_arith.h,v 1.1 1995/11/03 04:46:59 briggs Exp $ */
+/*     $NetBSD: fpu_arith.h,v 1.2 1999/05/30 20:17:48 briggs Exp $ */
 
 /*
  * Copyright (c) 1992, 1993
@@ -58,46 +58,7 @@
  * for example.
  */
 
-#ifdef sparc
-
-/* set up for extended-precision arithemtic */
-#define        FPU_DECL_CARRY
-
-/*
- * 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("addx %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
-#define        FPU_ADDS(r, x, y) \
-       asm volatile("addcc %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
-#define        FPU_ADDCS(r, x, y) \
-       asm volatile("addxcc %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
-#define        FPU_SUBC(r, x, y) \
-       asm volatile("subx %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
-#define        FPU_SUBS(r, x, y) \
-       asm volatile("subcc %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
-#define        FPU_SUBCS(r, x, y) \
-       asm volatile("subxcc %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
-
-#define        FPU_GET_CARRY(r) asm volatile("addx %%g0,%%g0,%0" : "=r"(r))
-#define        FPU_SET_CARRY(v) asm volatile("addcc %0,-1,%%g0" : : "r"(v))
-
-#define        FPU_SHL1_BY_ADD /* shift left 1 faster by ADDC than (a<<1)|(b>>31) */
-
-#else /* non sparc */
+#ifndef FPE_USE_ASM
 
 /* set up for extended-precision arithemtic */
 #define        FPU_DECL_CARRY quad_t fpu_carry, fpu_tmp;
@@ -150,4 +111,64 @@
 #define        FPU_GET_CARRY(r) (r) = (!!fpu_carry)
 #define        FPU_SET_CARRY(v) fpu_carry = ((v) != 0)
 
-#endif
+#else
+
+/* set up for extended-precision arithemtic */
+#define        FPU_DECL_CARRY register 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 -r 5a372ef10cc8 -r f5d77bc18a4b sys/arch/m68k/fpe/fpu_calcea.c
--- a/sys/arch/m68k/fpe/fpu_calcea.c    Sun May 30 19:13:33 1999 +0000
+++ b/sys/arch/m68k/fpe/fpu_calcea.c    Sun May 30 20:17:48 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_calcea.c,v 1.7 1996/10/16 06:27:05 scottr Exp $    */
+/*     $NetBSD: fpu_calcea.c,v 1.8 1999/05/30 20:17:48 briggs Exp $    */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
@@ -77,104 +77,125 @@
     /* Set the most common value here. */
     ea->ea_regnum = 8 + (modreg & 7);
 
-    switch (modreg & 070) {
-    case 0:                    /* Dn */
-       ea->ea_regnum &= 7;
-    case 010:                  /* An */
+    if ((modreg & 060) == 0) {
+       /* register direct */
+       ea->ea_regnum = modreg & 0xf;
        ea->ea_flags = EA_DIRECT;
-       if (fpu_debug_level & DL_DECODEEA) {
-           printf("  decode_ea: register direct reg=%d\n", ea->ea_regnum);
+#ifdef DEBUG_FPE
+       printf("decode_ea: register direct reg=%d\n", ea->ea_regnum);
+#endif
+    } else if (modreg == 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.
+     */
+    else if (frame->f_format == 4) {
+       /* 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)\n", (void *)ea->ea_fea);
+#endif
+       if ((modreg & 070) == 030) {
+           /* postincrement mode */
+           ea->ea_flags |= EA_POSTINCR;
+       } else if ((modreg & 070) == 040) {
+           /* predecrement mode */
+           ea->ea_flags |= EA_PREDECR;
        }
-       break;
-
-    case 020:                  /* (An) */
-       ea->ea_flags = 0;
-       if (fpu_debug_level & DL_DECODEEA) {
-           printf("  decode_ea: register indirect reg=%d\n", ea->ea_regnum);
-       }
-       break;
-
-    case 030:                  /* (An)+ */
-       ea->ea_flags = EA_POSTINCR;
-       if (fpu_debug_level & DL_DECODEEA) {
-           printf("  decode_ea: reg indirect postincrement reg=%d\n",
-                  ea->ea_regnum);
-       }
-       break;
+    } else {
+       /* 020/030 */
+       switch (modreg & 070) {
 
-    case 040:                  /* -(An) */
-       ea->ea_flags = EA_PREDECR;
-       if (fpu_debug_level & DL_DECODEEA) {
-           printf("  decode_ea: reg indirect predecrement reg=%d\n",
-                  ea->ea_regnum);
-       }
-       break;
-
-    case 050:                  /* (d16,An) */
-       ea->ea_flags = EA_OFFSET;
-       sig = fetch_disp(frame, insn, 1, &ea->ea_offset);
-       if (fpu_debug_level & DL_DECODEEA) {
-           printf("  decode_ea: reg indirect with displacement reg=%d\n",
-                  ea->ea_regnum);
-       }
-       break;
-
-    case 060:                  /* (d8,An,Xn) */
-       ea->ea_flags = EA_INDEXED;
-       sig = decode_ea6(frame, insn, ea, modreg);
-       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);
-           if (fpu_debug_level & DL_DECODEEA) {
-               printf("  decode_ea: absolute address (word)\n");
-           }
+       case 020:                       /* (An) */
+           ea->ea_flags = 0;
+#ifdef DEBUG_FPE
+           printf("decode_ea: register indirect reg=%d\n", ea->ea_regnum);
+#endif
            break;
 
-       case 1:                 /* (xxxxxxxx).L */
-           ea->ea_flags = EA_ABS;
-           sig = fetch_disp(frame, insn, 2, &ea->ea_absaddr);
-           if (fpu_debug_level & DL_DECODEEA) {
-               printf("  decode_ea: absolute address (long)\n");
-           }
+       case 030:                       /* (An)+ */
+           ea->ea_flags = EA_POSTINCR;
+#ifdef DEBUG_FPE



Home | Main Index | Thread Index | Old Index