]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AVR/LibF7: Implement sincos.
authorGeorg-Johann Lay <avr@gjlay.de>
Mon, 6 Oct 2025 19:31:46 +0000 (21:31 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Mon, 6 Oct 2025 19:37:59 +0000 (21:37 +0200)
libgcc/config/avr/libf7/
* libf7-common.mk (F7_ASM_PARTS): Add D_sincos.
* libf7-asm.sx: (D_sincos): New module implements sincos / sincosl.

gcc/testsuite/
* gcc.target/avr/sincos-1.c: New test.

gcc/testsuite/gcc.target/avr/sincos-1.c [new file with mode: 0644]
libgcc/config/avr/libf7/libf7-asm.sx
libgcc/config/avr/libf7/libf7-common.mk

diff --git a/gcc/testsuite/gcc.target/avr/sincos-1.c b/gcc/testsuite/gcc.target/avr/sincos-1.c
new file mode 100644 (file)
index 0000000..3cf543c
--- /dev/null
@@ -0,0 +1,35 @@
+/* { dg-do run { target { ! avr_tiny } } } */
+/* { dg-additional-options { -std=gnu99 -Os -mcall-prologues } } */
+
+#if __SIZEOF_LONG_DOUBLE__ == 8
+typedef long double D;
+
+extern void sincosl (D, D*, D*);
+extern D sinl (D);
+extern D cosl (D);
+
+D s1, c1;
+
+int main (void)
+{
+  for (D x = -20; x < 20; x += 1.1)
+    {
+      sincosl (x, &s1, &c1);
+
+      __asm ("" : "+r" (x) :: "memory");
+
+      if (s1 != sinl (x))
+       __builtin_exit (1);
+
+      if (c1 != cosl (x))
+       __builtin_exit (2);
+    }
+
+  return 0;
+}
+#else
+int main (void)
+{
+  return 0;
+}
+#endif
index 33e8f78006cf9107c753dc4edde072742f063dc7..bafb490c5c7e2884d36121b43e4099e5a31cfa2c 100644 (file)
@@ -1989,6 +1989,59 @@ LALIAS fmaxl
 _ENDF __fmax
 #endif /* F7MOD_D_fminfmax_ */
 
+
+#ifdef F7MOD_D_sincos_
+;;; void sincos (double R18, double *R16, double *R14);
+_DEFUN __sincos
+DALIAS sincos
+LALIAS sincosl
+
+#define n_pushed    4
+#define n_frame    (2 * F7_SIZEOF)
+    do_prologue_saves n_pushed, n_frame
+    ;; Y = FramePointer + 1
+    adiw    Y,      1
+    ;; R16 = frame-arg 1
+    wmov    r16,    Y
+    ;; The double argument is in R18[].
+    XCALL   F7_NAME (set_double_impl)
+    ;; void f7_sincos (f7_t *ss, f7_t *cc, const f7_t *aa)
+    ;; Note that aa may equal ss or cc.
+    wmov    r20,    r16                 ; aa
+    wmov    r24,    r16                 ; ss = FP + 1
+    subi    r16,    lo8(-F7_SIZEOF)
+    sbci    r17,    hi8(-F7_SIZEOF)
+    wmov    r22,    r16                 ; cc = FP + 1 + F7_SIZEOF
+    XCALL   F7_NAME (sincos)
+
+    ;; double R18 = get_double (cc)
+    wmov    r24,    r16
+    XCALL   F7_NAME (get_double)
+    wmov    XL,     r14                 ; double *pcos
+    rcall   store.r18.X                 ; *pcos = R18
+
+    ;; double R18 = get_double (ss)
+    wmov    r24,    Y
+    XCALL   F7_NAME (get_double)
+    ldd     XL,     Y + n_frame + 3     ; Saved R16
+    ldd     XH,     Y + n_frame + 2     ; Saved R17
+    rcall   store.r18.X                 ; *psin = R18
+
+    do_epilogue_restores n_pushed, n_frame
+
+store.r18.X:
+    st      X+,     r18
+    st      X+,     r19
+    st      X+,     r20
+    st      X+,     r21
+    st      X+,     r22
+    st      X+,     r23
+    st      X+,     r24
+    st      X+,     r25
+    ret
+_ENDF __sincos
+#endif /* F7MOD_D_sincos_ */
+
 #ifdef F7MOD_call_dd_
 
 ;; Provide double wrappers for functions that operate on f7_t and get f7_t*.
index 2d3adaf45697869437fd24ac68e3ba52abaa46ed..153266ba141ed92b290f7552a26d970f99071687 100644 (file)
@@ -22,7 +22,7 @@ F7_ASM_PARTS += addsub_mant_scaled store load
 F7_ASM_PARTS += to_integer to_unsigned clz normalize_with_carry normalize
 F7_ASM_PARTS += store_expo sqrt16 sqrt_approx div
 
-F7_ASM_PARTS += D_class D_fma D_powi
+F7_ASM_PARTS += D_class D_fma D_powi D_sincos
 F7_ASM_PARTS += D_isnan D_isinf D_isfinite D_signbit D_copysign D_neg D_fabs
 F7_ASM_PARTS += D_cmp D_eq D_ne D_ge D_gt D_le D_lt D_unord D_fminfmax