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 Add hyperboric and trigonometric functions...



details:   https://anonhg.NetBSD.org/src/rev/2930bf113f1d
branches:  trunk
changeset: 770394:2930bf113f1d
user:      tsutsui <tsutsui%NetBSD.org@localhost>
date:      Sat Oct 15 15:14:29 2011 +0000

description:
Add hyperboric and trigonometric functions to m68k FPE, written by isaki@.
With these emulations (~4KB text) xeyes on XM6i works better.
Discussed with isaki@ at OSC 2011 Hiroshima.

diffstat:

 sys/arch/m68k/fpe/fpu_emulate.c |    7 +-
 sys/arch/m68k/fpe/fpu_emulate.h |    5 +-
 sys/arch/m68k/fpe/fpu_hyperb.c  |  102 +++++++++-
 sys/arch/m68k/fpe/fpu_trig.c    |  425 +++++++++++++++++++++++++++++++++++++++-
 4 files changed, 521 insertions(+), 18 deletions(-)

diffs (truncated from 657 to 300 lines):

diff -r 86944d801fc7 -r 2930bf113f1d sys/arch/m68k/fpe/fpu_emulate.c
--- a/sys/arch/m68k/fpe/fpu_emulate.c   Sat Oct 15 13:02:24 2011 +0000
+++ b/sys/arch/m68k/fpe/fpu_emulate.c   Sat Oct 15 15:14:29 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_emulate.c,v 1.35 2011/07/18 14:11:27 isaki Exp $   */
+/*     $NetBSD: fpu_emulate.c,v 1.36 2011/10/15 15:14:29 tsutsui Exp $ */
 
 /*
  * Copyright (c) 1995 Gordon W. Ross
@@ -37,7 +37,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_emulate.c,v 1.35 2011/07/18 14:11:27 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_emulate.c,v 1.36 2011/10/15 15:14:29 tsutsui Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -65,7 +65,6 @@
 static int fpu_emul_type1(struct fpemu *, struct instruction *);
 static int fpu_emul_brcc(struct fpemu *, struct instruction *);
 static int test_cc(struct fpemu *, int);
-static struct fpn *fpu_cmp(struct fpemu *);
 
 #ifdef DEBUG_FPE
 #define DUMP_INSN(insn)                                                        \
@@ -494,7 +493,7 @@
        return sig;
 }
 
-static struct fpn *
+struct fpn *
 fpu_cmp(struct fpemu *fe)
 {
        struct fpn *x = &fe->fe_f1, *y = &fe->fe_f2;
diff -r 86944d801fc7 -r 2930bf113f1d sys/arch/m68k/fpe/fpu_emulate.h
--- a/sys/arch/m68k/fpe/fpu_emulate.h   Sat Oct 15 13:02:24 2011 +0000
+++ b/sys/arch/m68k/fpe/fpu_emulate.h   Sat Oct 15 15:14:29 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_emulate.h,v 1.17 2011/10/09 01:34:19 tsutsui Exp $ */
+/*     $NetBSD: fpu_emulate.h,v 1.18 2011/10/15 15:14:30 tsutsui Exp $ */
 
 /*
  * Copyright (c) 1995 Gordon Ross
@@ -244,6 +244,9 @@
 #include "fpu_arith_proto.h"
 
 int fpu_emulate(struct frame *frame, struct fpframe *fpf, ksiginfo_t *ksi);
+struct fpn *fpu_cmp(struct fpemu *);
+
+struct fpn *fpu_sincos_taylor(struct fpemu *, struct fpn *, u_int, int);
 
 /*
  * "helper" functions
diff -r 86944d801fc7 -r 2930bf113f1d sys/arch/m68k/fpe/fpu_hyperb.c
--- a/sys/arch/m68k/fpe/fpu_hyperb.c    Sat Oct 15 13:02:24 2011 +0000
+++ b/sys/arch/m68k/fpe/fpu_hyperb.c    Sat Oct 15 15:14:29 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_hyperb.c,v 1.5 2011/07/18 07:44:30 isaki Exp $     */
+/*     $NetBSD: fpu_hyperb.c,v 1.6 2011/10/15 15:14:30 tsutsui Exp $   */
 
 /*
  * Copyright (c) 1995  Ken Nakata
@@ -31,8 +31,33 @@
  *     @(#)fpu_hyperb.c        10/24/95
  */
 
+/*
+ * Copyright (c) 2011 Tetsuya Isaki. 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/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_hyperb.c,v 1.5 2011/07/18 07:44:30 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_hyperb.c,v 1.6 2011/10/15 15:14:30 tsutsui Exp $");
 
 #include "fpu_emulate.h"
 
@@ -52,20 +77,87 @@
 struct fpn *
 fpu_cosh(struct fpemu *fe)
 {
-       /* stub */
+       struct fpn s0;
+       struct fpn *r;
+       int hyperb = 1;
+
+       fe->fe_fpsr &= ~FPSR_EXCP; /* clear all exceptions */
+
+       if (ISNAN(&fe->fe_f2))
+               return &fe->fe_f2;
+
+       if (ISINF(&fe->fe_f2)) {
+               fe->fe_f2.fp_sign = 0;
+               return &fe->fe_f2;
+       }
+
+       fpu_const(&s0, 0x32);   /* 1.0 */
+       r = fpu_sincos_taylor(fe, &s0, 1, hyperb);
+       CPYFPN(&fe->fe_f2, r);
+
+       fpu_upd_fpsr(fe, &fe->fe_f2);
        return &fe->fe_f2;
 }
 
 struct fpn *
 fpu_sinh(struct fpemu *fe)
 {
-       /* stub */
+       struct fpn s0;
+       struct fpn *r;
+       int hyperb = 1;
+
+       fe->fe_fpsr &= ~FPSR_EXCP; /* clear all exceptions */
+
+       if (ISNAN(&fe->fe_f2))
+               return &fe->fe_f2;
+       if (ISINF(&fe->fe_f2))
+               return &fe->fe_f2;
+
+       CPYFPN(&s0, &fe->fe_f2);
+       r = fpu_sincos_taylor(fe, &s0, 2, hyperb);
+       CPYFPN(&fe->fe_f2, r);
+
+       fpu_upd_fpsr(fe, &fe->fe_f2);
        return &fe->fe_f2;
 }
 
 struct fpn *
 fpu_tanh(struct fpemu *fe)
 {
-       /* stub */
+       struct fpn x;
+       struct fpn s;
+       struct fpn *r;
+       int sign;
+
+       fe->fe_fpsr &= ~FPSR_EXCP; /* clear all exceptions */
+
+       if (ISNAN(&fe->fe_f2))
+               return &fe->fe_f2;
+
+       if (ISINF(&fe->fe_f2)) {
+               sign = fe->fe_f2.fp_sign;
+               fpu_const(&fe->fe_f2, 0x32);
+               fe->fe_f2.fp_sign = sign;
+               return &fe->fe_f2;
+       }
+
+       CPYFPN(&x, &fe->fe_f2);
+
+       /* sinh(x) */
+       CPYFPN(&fe->fe_f2, &x);
+       r = fpu_sinh(fe);
+       CPYFPN(&s, r);
+
+       /* cosh(x) */
+       CPYFPN(&fe->fe_f2, &x);
+       r = fpu_cosh(fe);
+       CPYFPN(&fe->fe_f2, r);
+
+       CPYFPN(&fe->fe_f1, &s);
+       r = fpu_div(fe);
+
+       CPYFPN(&fe->fe_f2, r);
+
+       fpu_upd_fpsr(fe, &fe->fe_f2);
        return &fe->fe_f2;
 }
diff -r 86944d801fc7 -r 2930bf113f1d sys/arch/m68k/fpe/fpu_trig.c
--- a/sys/arch/m68k/fpe/fpu_trig.c      Sat Oct 15 13:02:24 2011 +0000
+++ b/sys/arch/m68k/fpe/fpu_trig.c      Sat Oct 15 15:14:29 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_trig.c,v 1.5 2011/07/18 07:44:30 isaki Exp $       */
+/*     $NetBSD: fpu_trig.c,v 1.6 2011/10/15 15:14:30 tsutsui Exp $     */
 
 /*
  * Copyright (c) 1995  Ken Nakata
@@ -31,11 +31,39 @@
  *     @(#)fpu_trig.c  10/24/95
  */
 
+/*
+ * Copyright (c) 2011 Tetsuya Isaki. 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/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_trig.c,v 1.5 2011/07/18 07:44:30 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_trig.c,v 1.6 2011/10/15 15:14:30 tsutsui Exp $");
 
 #include "fpu_emulate.h"
 
+static inline struct fpn *fpu_cos_halfpi(struct fpemu *);
+static inline struct fpn *fpu_sin_halfpi(struct fpemu *);
+
 struct fpn *
 fpu_acos(struct fpemu *fe)
 {
@@ -57,30 +85,411 @@
        return &fe->fe_f2;
 }
 
+/*
+ * taylor expansion used by sin(), cos(), sinh(), cosh().
+ * hyperb is for sinh(), cosh().
+ */
 struct fpn *
-fpu_cos(struct fpemu *fe)
+fpu_sincos_taylor(struct fpemu *fe, struct fpn *s0, u_int f, int hyperb)
 {
-       /* stub */
+       struct fpn res;
+       struct fpn x2;
+       struct fpn *s1;
+       struct fpn *r;
+       int sign;
+       u_int k;
+
+       /* x2 := x * x */
+       CPYFPN(&fe->fe_f1, &fe->fe_f2);
+       r = fpu_mul(fe);
+       CPYFPN(&x2, r);
+
+       /* res := s0 */
+       CPYFPN(&res, s0);
+
+       sign = 1;       /* sign := (-1)^n */
+
+       for (;;) {
+               /* (f1 :=) s0 * x^2 */
+               CPYFPN(&fe->fe_f1, s0);
+               CPYFPN(&fe->fe_f2, &x2);
+               r = fpu_mul(fe);
+               CPYFPN(&fe->fe_f1, r);
+
+               /*
+                * for sin(),  s1 := s0 * x^2 / (2n+1)2n
+                * for cos(),  s1 := s0 * x^2 / 2n(2n-1)
+                */
+               k = f * (f + 1);
+               fpu_explode(fe, &fe->fe_f2, FTYPE_LNG, &k);
+               s1 = fpu_div(fe);
+
+               /* break if s1 is enough small */
+               if (ISZERO(s1))
+                       break;
+               if (res.fp_exp - s1->fp_exp >= FP_NMANT)
+                       break;
+
+               /* s0 := s1 for next loop */
+               CPYFPN(s0, s1);
+
+               CPYFPN(&fe->fe_f2, s1);
+               if (!hyperb) {
+                       /* (-1)^n */
+                       fe->fe_f2.fp_sign = sign;
+               }
+
+               /* res += s1 */



Home | Main Index | Thread Index | Old Index