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