diff mbox series

[avr,committed] Implement fma, fmal.

Message ID 1eff6955-3ddf-7d83-eb49-c56d47aa6637@gjlay.de
State New
Headers show
Series [avr,committed] Implement fma, fmal. | expand

Commit Message

Georg-Johann Lay Oct. 17, 2023, 9:52 a.m. UTC
This commit implements fma and fmal which were missing from LibF7.

Johann

--

LibF7: Implement fma / fmal.

libgcc/config/avr/libf7/
	* libf7.h (F7_SIZEOF): New macro.
	* libf7-asm.sx: Use F7_SIZEOF instead of magic number "10".
	(F7MOD_D_fma_, __fma): New module and function.
	(fma) [-mdouble=64]: Define as alias for __fma.
	(fmal) [-mlong-double=64]: Define as alias for __fma.
	* libf7-common.mk (F7_ASM_PARTS): Add D_fma.
diff mbox series

Patch

diff --git a/libgcc/config/avr/libf7/libf7-asm.sx 
b/libgcc/config/avr/libf7/libf7-asm.sx
index 8fbd66bd290..5df167fe73c 100644
--- a/libgcc/config/avr/libf7/libf7-asm.sx
+++ b/libgcc/config/avr/libf7/libf7-asm.sx
@@ -283,8 +283,8 @@  DEFUN copy
      cp      XL,     ZL
      cpc     XH,     ZH
      breq 9f
-    adiw    XL,     10
-    adiw    ZL,     10
+    adiw    XL,     F7_SIZEOF
+    adiw    ZL,     F7_SIZEOF
      set
      bld     ZERO,   1
      bld     ZERO,   3   ; ZERO = 0b1010 = 10.
@@ -312,8 +312,8 @@  DEFUN copy_P
      st      X+,     TMP
      dec     ZERO
      brne .Loop
-    sbiw    X,      10
-    sbiw    Z,      10
+    sbiw    X,      F7_SIZEOF
+    sbiw    Z,      F7_SIZEOF
      ret
  ENDF copy_P
  #endif /* F7MOD_copy_P_ */
@@ -1328,6 +1328,58 @@  DEFUN sqrt_approx
  #undef Carry


+#ifdef F7MOD_D_fma_
+_DEFUN __fma
+    DALIAS fma
+    LALIAS fmal
+
+#define n_pushed    4
+#define n_frame     (2 * F7_SIZEOF)
+
+    do_prologue_saves n_pushed, n_frame
+    ;; Y = FramePointer + 1
+    adiw    Y,      1
+
+    ;; FP + 1 = (f7_t) arg1
+    wmov    r16,    Y
+    ;; The double argument arg1 is already in R18[].
+    XCALL   F7_NAME (set_double_impl)
+
+    ;; The double argument arg2 is in R10[].  Move it to R18[].
+    wmov    r18,    r10
+    wmov    r20,    r12
+    wmov    r22,    r14
+    ;; R16, R17 are clobbered.  Fetch them from where prologue_saves 
put them.
+    ldd     r24,    Y + n_frame + 3     ; Saved R16
+    ldd     r25,    Y + n_frame + 2     ; Saved R17
+    ;; FP + 1 + 10 = (f7_t) arg2
+    subi    r16,    lo8 (-F7_SIZEOF)
+    sbci    r17,    hi8 (-F7_SIZEOF)
+    XCALL   F7_NAME (set_double_impl)
+
+    wmov    r24,    Y                   ; &arg1
+    wmov    r22,    r16                 ; &arg2
+    XCALL   F7_NAME (Imul)              ; arg1 *= arg2
+
+    ;; The 3rd double argument arg3 was passed on the stack.  Move it 
to R18[],
+    ;; Don't use f7_set_pdouble() because that function is unused (for 
now).
+    .irp n, 0, 1, 2, 3, 4, 5, 6, 7
+    ldd     18+\n,  Y + n_frame + n_pushed + PC_SIZE + \n
+    .endr
+    XCALL   F7_NAME (set_double_impl)
+
+    wmov    r24,    Y                   ; &arg1
+    wmov    r22,    r16                 ; &arg2
+    XCALL   F7_NAME (Iadd)              ; arg1 += arg2
+
+    wmov    r24,    Y                   ; &arg1
+    XCALL   F7_NAME (get_double)
+
+    do_epilogue_restores n_pushed, n_frame
+_ENDF __fma
+#endif /* F7MOD_D_fma_ */
+
+
  #ifdef F7MOD_D_fabs_
  _DEFUN __fabs
      DALIAS fabs
@@ -1493,7 +1545,7 @@  DEFUN call_dd   ; WHAT = R13 = 3
      wmov    r14,     Z

  #define n_pushed    4
-#define n_frame     10
+#define n_frame     F7_SIZEOF

      do_prologue_saves n_pushed, n_frame
      ;; Y = FramePointer + 1
@@ -1565,7 +1617,7 @@  DEFUN call_ddd
      ret

  #define n_pushed    4
-#define n_frame     20
+#define n_frame     (2 * F7_SIZEOF)

  call.2:
      do_prologue_saves n_pushed, n_frame
@@ -1576,9 +1628,8 @@  DEFUN call_ddd
      ;; First double argument is already in R18[].
      XCALL   F7_NAME (set_double_impl)
      ;; FP + 11 = (f7_t) arg2
-    wmov    r16,    Y
-    subi    r16,    lo8 (-10)
-    sbci    r17,    hi8 (-10)
+    subi    r16,    lo8 (-F7_SIZEOF)
+    sbci    r17,    hi8 (-F7_SIZEOF)
      ;; Move second double argument to R18[].
      wmov    r18,    r10
      wmov    r20,    r12
diff --git a/libgcc/config/avr/libf7/libf7-common.mk 
b/libgcc/config/avr/libf7/libf7-common.mk
index e417715a7e5..d541b48ff3c 100644
--- a/libgcc/config/avr/libf7/libf7-common.mk
+++ b/libgcc/config/avr/libf7/libf7-common.mk
@@ -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
+F7_ASM_PARTS += D_class D_fma
  F7_ASM_PARTS += D_isnan D_isinf D_isfinite D_signbit D_copysign D_neg 
D_fabs

  F7_ASM_PARTS += call_dd call_ddd
diff --git a/libgcc/config/avr/libf7/libf7.h 
b/libgcc/config/avr/libf7/libf7.h
index b50e6e218ba..2b6beac0df8 100644
--- a/libgcc/config/avr/libf7/libf7.h
+++ b/libgcc/config/avr/libf7/libf7.h
@@ -29,6 +29,7 @@ 

  #define F7_MANT_BYTES 7
  #define F7_MANT_BITS (8 * F7_MANT_BYTES)
+#define F7_SIZEOF (1 + F7_MANT_BYTES + 2)

  /*  Using the following GCC features:
      --  Unnamed structs / unions (GNU-C)