https://gcc.gnu.org/g:5f3e4237ca0b2f410a718b7cf2a3481cf7635a60

commit r14-12708-g5f3e4237ca0b2f410a718b7cf2a3481cf7635a60
Author: Georg-Johann Lay <[email protected]>
Date:   Sun Jun 28 12:08:04 2026 +0200

    AVR: ad target/125752 - Simplify double -> 64-bit fixed conversions.
    
    When converting a fixed-point value to double, there is no need to
    use ldexp to adjust for FBIT of the result.  Instead, FBIT can be
    added to the double exponent without any further ado.  When the
    input is +/-0.0 then the outcome of adding FBIT to the exponent
    is a small number that __fix[uns]dfdi converts to 0.
    
            PR target/125752
    libgcc/config/avr/libf7/
            * libf7.c (d_to_ufx, d_to_sfx): Remove prototypes.
            (__fractdfda, __fractdfuda, __fractdfta, __fractdfuta)
            (__fractdfdq, __fractdfudq): Move implementation to...
            * libf7-asm.sx: ...here.
            (d_to_fx64): Remove.
            * libf7-common.mk (F7_ASM_PARTS): Add D2dq, D2udq, D2da,
            D2uda, D2ta, D2uta.
            (F7F_asm): Remove d_to_fx64.
            * t-libf7 (LIBF7_DF_CONV): Remove fractdfda, fractdfta,
            fractdfdq, fractdfuda, fractdfuta, fractdfudq.
            * f7-renames.h: Rebuild.
    
    (cherry picked from commit 997a7e79258e7209718c5366b6a1d3be31c76b8b)

Diff:
---
 libgcc/config/avr/libf7/f7-renames.h    |  1 -
 libgcc/config/avr/libf7/libf7-asm.sx    | 92 ++++++++++++++++++---------------
 libgcc/config/avr/libf7/libf7-common.mk |  7 ++-
 libgcc/config/avr/libf7/libf7.c         | 52 -------------------
 libgcc/config/avr/libf7/t-libf7         |  2 -
 5 files changed, 53 insertions(+), 101 deletions(-)

diff --git a/libgcc/config/avr/libf7/f7-renames.h 
b/libgcc/config/avr/libf7/f7-renames.h
index ba4410ee7c3f..92f47817b49d 100644
--- a/libgcc/config/avr/libf7/f7-renames.h
+++ b/libgcc/config/avr/libf7/f7-renames.h
@@ -222,7 +222,6 @@
 #define f7_sqrt16_floor_asm __f7_sqrt16_floor_asm
 #define f7_lshrdi3_asm __f7_lshrdi3_asm
 #define f7_ashldi3_asm __f7_ashldi3_asm
-#define f7_d_to_fx64_asm __f7_d_to_fx64_asm
 #define f7_ufx64_to_d_asm __f7_ufx64_to_d_asm
 #define f7_sfx64_to_d_asm __f7_sfx64_to_d_asm
 #define f7_class_D_asm __f7_class_D_asm
diff --git a/libgcc/config/avr/libf7/libf7-asm.sx 
b/libgcc/config/avr/libf7/libf7-asm.sx
index 6f50e401e0a3..6e4f3eef6ada 100644
--- a/libgcc/config/avr/libf7/libf7-asm.sx
+++ b/libgcc/config/avr/libf7/libf7-asm.sx
@@ -2465,48 +2465,56 @@ _DEFUN __fractdfusa
 _ENDF __fractdfusa
 #endif /* F7MOD_D2usa_ */
 
-
-#ifdef F7MOD_D2fx_
-;;; Convert double R18 to a 64-bit fixed point value.
-;;; R18 d_to_fx64 (double R18, int8_t fbit R16);
-;;; |FBIT| accounts for the extra fbits compared to [u]int64_t.
-;;; FBIT < 0 indicates a signed conversion.
-;;; FBIT > 0 indicates an unsigned conversion.
-DEFUN d_to_fx64
-    do_prologue_saves  4, F7_SIZEOF
-
-    ;; Y = FramePointer + 1
-    adiw    Y,      1
-
-    ;; FP + 1 = (f7_t) arg
-    wmov    r16,    Y
-
-    ;; Convert double R18 to f7_t *R16.
-    XCALL   F7_NAME (set_double_impl)
-
-    ;; Prepare for *R24 = ldexp (*R24, R22).  ldexp() accounts for the
-    ;; fractional bits of the fixed point value, i.e. we have to <<= FBIT.
-    wmov    r24,    r16
-    ;; Zero-extend FBIT.
-    clr     r23
-    ;; R16 has been clobbered.  Fetch it from where prologue_saves put it.
-    ldd     r22,    Y + F7_SIZEOF + 3       ; Saved R16
-    tst     r22
-    brmi 1f
-
-    ;; Positive FBIT indicates an unsigned conversion.
-    XCALL   F7_NAME (Ildexp)
-    XCALL   F7_NAME (get_u64)
-    rjmp 9f
-
-1:  ;; Negative FBIT indicates a signed conversion.
-    neg     r22                 ; FBIT := |FBIT|
-    XCALL   F7_NAME (Ildexp)
-    XCALL   F7_NAME (get_s64)
-
-9:  do_epilogue_restores  4, F7_SIZEOF
-ENDF d_to_fx64
-#endif /* F7MOD_D2fx_ */
+#ifdef F7MOD_D2da_
+_DEFUN __fractdfda
+    ;; Multiply with 2^FBIT to get a DA result in r25:r18.
+    subi    r24, dex_lo (-__DA_FBIT__)
+    sbci    r25, dex_hi (-__DA_FBIT__)
+    XJMP    __fixdfdi
+_ENDF __fractdfda
+#endif /* F7MOD_D2da_ */
+
+#ifdef F7MOD_D2uda_
+_DEFUN __fractdfuda
+    ;; Multiply with 2^FBIT to get an UDA result in r25:r18.
+    subi    r25, dex_hi (-__UDA_FBIT__)
+    XJMP    __fixunsdfdi
+_ENDF __fractdfuda
+#endif /* F7MOD_D2uda_ */
+
+#ifdef F7MOD_D2ta_
+_DEFUN __fractdfta
+    ;; Multiply with 2^FBIT to get a TA result in r25:r18.
+    subi    r24, dex_lo (-__TA_FBIT__)
+    sbci    r25, dex_hi (-__TA_FBIT__)
+    XJMP    __fixdfdi
+_ENDF __fractdfta
+#endif /* F7MOD_D2ta_ */
+
+#ifdef F7MOD_D2uta_
+_DEFUN __fractdfuta
+    ;; Multiply with 2^FBIT to get an UTA result in r25:r18.
+    subi    r25, dex_hi (-__UTA_FBIT__)
+    XJMP    __fixunsdfdi
+_ENDF __fractdfuta
+#endif /* F7MOD_D2uta_ */
+
+#ifdef F7MOD_D2dq_
+_DEFUN __fractdfdq
+    ;; Multiply with 2^FBIT to get a DQ result in r25:r18.
+    subi    r24, dex_lo (-__DQ_FBIT__)
+    sbci    r25, dex_hi (-__DQ_FBIT__)
+    XJMP    __fixdfdi
+_ENDF __fractdfdq
+#endif /* F7MOD_D2dq_ */
+
+#ifdef F7MOD_D2udq_
+_DEFUN __fractdfudq
+    ;; Multiply with 2^FBIT to get an UDQ result in r25:r18.
+    subi    r25, dex_hi (-__UDQ_FBIT__)
+    XJMP    __fixunsdfdi
+_ENDF __fractdfudq
+#endif /* F7MOD_D2udq_ */
 
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/libgcc/config/avr/libf7/libf7-common.mk 
b/libgcc/config/avr/libf7/libf7-common.mk
index 4c3091f4f437..3ebe101c9c10 100644
--- a/libgcc/config/avr/libf7/libf7-common.mk
+++ b/libgcc/config/avr/libf7/libf7-common.mk
@@ -34,9 +34,8 @@ F7_ASM_PARTS +=            ha2D uha2D sa2D usa2D da2D uda2D 
ta2D uta2D
 F7_ASM_PARTS += fx2D
 
 # Double -> fixed-point conversions
-F7_ASM_PARTS += D2qq D2uqq D2hq D2uhq
-F7_ASM_PARTS +=            D2ha D2uha D2sa D2usa
-F7_ASM_PARTS += D2fx
+F7_ASM_PARTS += D2qq D2uqq D2hq D2uhq            D2dq D2udq
+F7_ASM_PARTS +=            D2ha D2uha D2sa D2usa D2da D2uda D2ta D2uta
 
 # Integer -> double conversions
 F7_ASM_PARTS += D_floatsidf D_floatunsidf
@@ -109,7 +108,7 @@ F7F_asm += set_u64 set_s64 addsub_mant_scaled mul_mant
 F7F_asm += to_integer to_unsigned clr_mant_lsbs
 F7F_asm += div sqrt_approx sqrt16_round sqrt16_floor
 F7F_asm += lshrdi3 ashldi3
-F7F_asm += d_to_fx64 ufx64_to_d sfx64_to_d
+F7F_asm += ufx64_to_d sfx64_to_d
 F7F_asm += class_D
 
 F7F_asm += call_ddd call_xdd call_ddx
diff --git a/libgcc/config/avr/libf7/libf7.c b/libgcc/config/avr/libf7/libf7.c
index 9825625b9003..4e3cc9fc6348 100644
--- a/libgcc/config/avr/libf7/libf7.c
+++ b/libgcc/config/avr/libf7/libf7.c
@@ -140,58 +140,6 @@ f7_double_t __floatdidf (int64_t x)
 #endif // F7MOD_floatdidf_
 
 
-extern uint64_t d_to_ufx (f7_double_t, int8_t) F7ASM(f7_d_to_fx64_asm);
-extern int64_t  d_to_sfx (f7_double_t, int8_t) F7ASM(f7_d_to_fx64_asm);
-
-#ifdef F7MOD_fractdfda_
-F7_WEAK
-int64_t __fractdfda (f7_double_t d)
-{
-  return d_to_sfx (d, -__DA_FBIT__);
-}
-#endif // F7MOD_fractdfda_
-
-#ifdef F7MOD_fractdfuda_
-F7_WEAK
-uint64_t __fractdfuda (f7_double_t d)
-{
-  return d_to_ufx (d, __UDA_FBIT__);
-}
-#endif // F7MOD_fractdfuda_
-
-#ifdef F7MOD_fractdfta_
-F7_WEAK
-int64_t __fractdfta (f7_double_t d)
-{
-  return d_to_sfx (d, -__TA_FBIT__);
-}
-#endif // F7MOD_fractdfta_
-
-#ifdef F7MOD_fractdfuta_
-F7_WEAK
-uint64_t __fractdfuta (f7_double_t d)
-{
-  return d_to_ufx (d, __UTA_FBIT__);
-}
-#endif // F7MOD_fractdfuta_
-
-#ifdef F7MOD_fractdfdq_
-F7_WEAK
-int64_t __fractdfdq (f7_double_t d)
-{
-  return d_to_sfx (d, -__DQ_FBIT__);
-}
-#endif // F7MOD_fractdfdq_
-
-#ifdef F7MOD_fractdfudq_
-F7_WEAK
-uint64_t __fractdfudq (f7_double_t d)
-{
-  return d_to_ufx (d, __UDQ_FBIT__);
-}
-#endif // F7MOD_fractdfudq_
-
-
 #ifdef F7MOD_init_
 f7_t* f7_init_impl (uint64_t mant, uint8_t flags, f7_t *cc, int16_t expo)
 {
diff --git a/libgcc/config/avr/libf7/t-libf7 b/libgcc/config/avr/libf7/t-libf7
index 5e589b082823..f17e67e8523a 100644
--- a/libgcc/config/avr/libf7/t-libf7
+++ b/libgcc/config/avr/libf7/t-libf7
@@ -9,8 +9,6 @@ F7_PREFIX = __f7_
 include $(libf7)/libf7-common.mk
 
 LIBF7_DF_CONV +=  floatundidf floatdidf # floatunsidf floatsidf
-LIBF7_DF_CONV +=  fractdfda fractdfta fractdfdq
-LIBF7_DF_CONV +=  fractdfuda fractdfuta fractdfudq
 
 # Wrappers like f7_lt_impl for f7_lt etc. because the latter is inline.
 LIBF7_DF_CMP  += lt le gt ge ne eq unord

Reply via email to