public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-7947] LibF7: Implement atan2.
@ 2023-10-12 13:51 Georg-Johann Lay
  0 siblings, 0 replies; only message in thread
From: Georg-Johann Lay @ 2023-10-12 13:51 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:f37fae519b731eb7fc62947c07658b6e0c16b5e3

commit r13-7947-gf37fae519b731eb7fc62947c07658b6e0c16b5e3
Author: Georg-Johann Lay <avr@gjlay.de>
Date:   Thu Oct 12 15:32:41 2023 +0200

    LibF7: Implement atan2.
    
    libgcc/config/avr/libf7/
            * libf7.c (F7MOD_atan2_, f7_atan2): New module and function.
            * libf7.h: Adjust comments.
            * libf7-common.mk (CALL_PROLOGUES): Add atan2.

Diff:
---
 libgcc/config/avr/libf7/libf7-common.mk |  2 +-
 libgcc/config/avr/libf7/libf7.c         | 60 ++++++++++++++++++++++++++++++++-
 libgcc/config/avr/libf7/libf7.h         |  2 +-
 3 files changed, 61 insertions(+), 3 deletions(-)

diff --git a/libgcc/config/avr/libf7/libf7-common.mk b/libgcc/config/avr/libf7/libf7-common.mk
index 28663b52e6c..e417715a7e5 100644
--- a/libgcc/config/avr/libf7/libf7-common.mk
+++ b/libgcc/config/avr/libf7/libf7-common.mk
@@ -43,7 +43,7 @@ m_xd += lrint lround
 # -mcall-prologues
 CALL_PROLOGUES += divx sqrt cbrt get_double set_double logx exp exp10 pow10
 CALL_PROLOGUES += put_C truncx round minmax sincos tan cotan pow powi fmod
-CALL_PROLOGUES += atan asinacos madd_msub hypot init horner sinhcosh tanh
+CALL_PROLOGUES += atan atan2 asinacos madd_msub hypot init horner sinhcosh tanh
 
 # -mstrict-X
 STRICT_X += log addsub truncx ldexp exp
diff --git a/libgcc/config/avr/libf7/libf7.c b/libgcc/config/avr/libf7/libf7.c
index 8fb57ef90cc..5c165dd28f9 100644
--- a/libgcc/config/avr/libf7/libf7.c
+++ b/libgcc/config/avr/libf7/libf7.c
@@ -1099,7 +1099,7 @@ f7_t* f7_ldexp (f7_t *cc, const f7_t *aa, int delta)
 
   F7_CONST_ADDR (<ident> CST, f7_t* PTMP)
 
-      Return an LD address to for some f7_const_X[_P] constant.
+      Return an LD address to some f7_const_X[_P] constant.
       *PTMP might be needed to hold a copy of f7_const_X_P in RAM.
 
   f7_t*       F7_U16_ADDR (uint16_t     X, f7_t* PTMP)   // USE_LPM
@@ -2186,6 +2186,64 @@ void f7_atan (f7_t *cc, const f7_t *aa)
 #endif // F7MOD_atan_
 
 
+#ifdef F7MOD_atan2_
+F7_WEAK
+void f7_atan2 (f7_t *cc, const f7_t *yy, const f7_t *xx)
+{
+  uint8_t y_class = f7_classify (yy);
+  uint8_t x_class = f7_classify (xx);
+
+  // (NaN, *) -> NaN
+  // (*, NaN) -> NaN
+  if (f7_class_nan (y_class | x_class))
+    return f7_set_nan (cc);
+
+  // (0, 0) -> 0
+  if (f7_class_zero (y_class & x_class))
+    return f7_clr (cc);
+
+  f7_t pi7, *pi = &pi7;
+  f7_const (pi, pi);
+
+  // (Inf, +Inf) -> +pi/4;    (-Inf, +Inf) -> +3pi/4
+  // (Inf, -Inf) -> -pi/4;    (-Inf, -Inf) -> -3pi/4
+  if (f7_class_inf (y_class & x_class))
+    {
+      f7_copy (cc, pi);
+      if (! f7_class_sign (x_class))
+	cc->expo = F7_(const_pi_expo) - 1; // pi / 2
+      pi->expo = F7_(const_pi_expo) - 2;   // pi / 4
+      f7_Isub (cc, pi);
+      cc->flags = y_class & F7_FLAG_sign;
+      return;
+    }
+
+  // sign(pi) := sign(y)
+  pi->flags = y_class & F7_FLAG_sign;
+
+  // Only use atan(*) with |*| <= 1.
+
+  if (f7_cmp_abs (yy, xx) > 0)
+    {
+      // |y| > |x|:  atan2 = sgn(y) * pi/2 - atan (x / y);
+      pi->expo = F7_(const_pi_expo) - 1;  // +- pi / 2
+      f7_div (cc, xx, yy);
+      f7_atan (cc, cc);
+      f7_IRsub (cc, pi);
+    }
+  else
+    {
+      // x >  |y|:  atan2 = atan (y / x)
+      // x < -|y|:  atan2 = atan (y / x) +- pi
+      f7_div (cc, yy, xx);
+      f7_atan (cc, cc);
+      if (f7_class_sign (x_class))
+	f7_Iadd (cc, pi);
+    }
+}
+#endif // F7MOD_atan2_
+
+
 #ifdef F7MOD_asinacos_
 
 #define ARRAY_NAME coeff_func_a_zahler
diff --git a/libgcc/config/avr/libf7/libf7.h b/libgcc/config/avr/libf7/libf7.h
index 03fe6abe839..7236e611341 100644
--- a/libgcc/config/avr/libf7/libf7.h
+++ b/libgcc/config/avr/libf7/libf7.h
@@ -600,6 +600,7 @@ extern void f7_sin (f7_t*, const f7_t*);
 extern void f7_cos (f7_t*, const f7_t*);
 extern void f7_tan (f7_t*, const f7_t*);
 extern void f7_atan (f7_t*, const f7_t*);
+extern void f7_atan2 (f7_t*, const f7_t*, const f7_t*);
 extern void f7_asin (f7_t*, const f7_t*);
 extern void f7_acos (f7_t*, const f7_t*);
 extern void f7_tanh (f7_t*, const f7_t*);
@@ -611,7 +612,6 @@ extern void f7_exp10 (f7_t*, const f7_t*);
 extern void f7_pow10 (f7_t*, const f7_t*);
 
 // Just prototypes, not implemented yet.
-extern void f7_atan2 (f7_t*, const f7_t*, const f7_t*);
 extern long f7_lrint (const f7_t*);
 extern long f7_lround (const f7_t*);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-10-12 13:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-12 13:51 [gcc r13-7947] LibF7: Implement atan2 Georg-Johann Lay

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).