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
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
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)