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
