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 Implement inverse trigonometric functions ...



details:   https://anonhg.NetBSD.org/src/rev/ccad3c515dd8
branches:  trunk
changeset: 786191:ccad3c515dd8
user:      isaki <isaki%NetBSD.org@localhost>
date:      Fri Apr 19 13:57:52 2013 +0000

description:
Implement inverse trigonometric functions (i.e., FACOS, FASIN, FATAN
instructions).
o arccos is calculated using arcsin.
o arcsin is calculated using arctan.
o arctan is calculated by the CORDIC.

diffstat:

 sys/arch/m68k/fpe/fpu_trig.c |  106 ++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 99 insertions(+), 7 deletions(-)

diffs (136 lines):

diff -r 488458fbea7f -r ccad3c515dd8 sys/arch/m68k/fpe/fpu_trig.c
--- a/sys/arch/m68k/fpe/fpu_trig.c      Fri Apr 19 13:45:45 2013 +0000
+++ b/sys/arch/m68k/fpe/fpu_trig.c      Fri Apr 19 13:57:52 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: fpu_trig.c,v 1.11 2013/04/19 13:31:11 isaki Exp $      */
+/*     $NetBSD: fpu_trig.c,v 1.12 2013/04/19 13:57:52 isaki Exp $      */
 
 /*
  * Copyright (c) 1995  Ken Nakata
@@ -57,28 +57,120 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fpu_trig.c,v 1.11 2013/04/19 13:31:11 isaki Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fpu_trig.c,v 1.12 2013/04/19 13:57:52 isaki Exp $");
 
 #include "fpu_emulate.h"
 
+/*
+ * arccos(x) = pi/2 - arcsin(x)
+ */
 struct fpn *
 fpu_acos(struct fpemu *fe)
 {
-       /* stub */
-       return &fe->fe_f2;
+       struct fpn *r;
+
+       if (ISNAN(&fe->fe_f2))
+               return &fe->fe_f2;
+       if (ISINF(&fe->fe_f2))
+               return fpu_newnan(fe);
+
+       r = fpu_asin(fe);
+       CPYFPN(&fe->fe_f2, r);
+
+       /* pi/2 - asin(x) */
+       fpu_const(&fe->fe_f1, FPU_CONST_PI);
+       fe->fe_f1.fp_exp--;
+       fe->fe_f2.fp_sign = !fe->fe_f2.fp_sign;
+       r = fpu_add(fe);
+
+       return r;
 }
 
+/*
+ *                          x
+ * arcsin(x) = arctan(---------------)
+ *                     sqrt(1 - x^2) 
+ */
 struct fpn *
 fpu_asin(struct fpemu *fe)
 {
-       /* stub */
-       return &fe->fe_f2;
+       struct fpn x;
+       struct fpn *r;
+
+       if (ISNAN(&fe->fe_f2))
+               return &fe->fe_f2;
+       if (ISZERO(&fe->fe_f2))
+               return &fe->fe_f2;
+
+       if (ISINF(&fe->fe_f2))
+               return fpu_newnan(fe);
+
+       CPYFPN(&x, &fe->fe_f2);
+
+       /* x^2 */
+       CPYFPN(&fe->fe_f1, &fe->fe_f2);
+       r = fpu_mul(fe);
+
+       /* 1 - x^2 */
+       CPYFPN(&fe->fe_f2, r);
+       fe->fe_f2.fp_sign = 1;
+       fpu_const(&fe->fe_f1, FPU_CONST_1);
+       r = fpu_add(fe);
+
+       /* sqrt(1-x^2) */
+       CPYFPN(&fe->fe_f2, r);
+       r = fpu_sqrt(fe);
+
+       /* x/sqrt */
+       CPYFPN(&fe->fe_f2, r);
+       CPYFPN(&fe->fe_f1, &x);
+       r = fpu_div(fe);
+
+       /* arctan */
+       CPYFPN(&fe->fe_f2, r);
+       return fpu_atan(fe);
 }
 
+/*
+ * arctan(x):
+ *
+ *     if (x < 0) {
+ *             x = abs(x);
+ *             sign = 1;
+ *     }
+ *     y = arctan(x);
+ *     if (sign) {
+ *             y = -y;
+ *     }
+ */
 struct fpn *
 fpu_atan(struct fpemu *fe)
 {
-       /* stub */
+       struct fpn a;
+       struct fpn x;
+       struct fpn v;
+
+       if (ISNAN(&fe->fe_f2))
+               return &fe->fe_f2;
+       if (ISZERO(&fe->fe_f2))
+               return &fe->fe_f2;
+
+       CPYFPN(&a, &fe->fe_f2);
+
+       if (ISINF(&fe->fe_f2)) {
+               /* f2 <- pi/2 */
+               fpu_const(&fe->fe_f2, FPU_CONST_PI);
+               fe->fe_f2.fp_exp--;
+
+               fe->fe_f2.fp_sign = a.fp_sign;
+               return &fe->fe_f2;
+       }
+
+       fpu_const(&x, FPU_CONST_1);
+       fpu_const(&fe->fe_f2, FPU_CONST_0);
+       CPYFPN(&v, &fe->fe_f2);
+       fpu_cordit1(fe, &x, &a, &fe->fe_f2, &v);
+
        return &fe->fe_f2;
 }
 



Home | Main Index | Thread Index | Old Index