https://gcc.gnu.org/g:939fa28d265d4707ad717fcff0c46329b6dc39c2

commit r15-9235-g939fa28d265d4707ad717fcff0c46329b6dc39c2
Author: Georg-Johann Lay <a...@gjlay.de>
Date:   Sun Apr 6 16:44:21 2025 +0200

    AVRrc: Support 8-bit and 16-bit fixed-point arith in libgcc.
    
    With some minor changes, 8-bit and 16-bit fixed-point operations
    can be supported on the reduced core.
    
    libgcc/
            * config/avr/t-avr (LIB1ASMFUNCS): Add (and remove from
            FUNCS_notiny): _mulhisi3, _umulhisi3, _mulqq3, _mulhq3, _muluhq3,
            _mulha3, _muluha3 _muluha3_round, _usmuluha3, _ssmulha3,
            _divqq3, _udivuqq3, _divqq_helper, _divhq3, _udivuhq3.
            _divha3 _udivuha3, _ssneg_2, _ssabs_1, _ssabs_2,
            _mask1, _ret, _roundqq3 _rounduqq3,
            _round_s2, _round_u2, _round_2_const, _addmask_2.
            * config/avr/lib1funcs.S (__umulhisi3, __mulhisi3): Make
            work on AVRrc.
            * config/avr/lib1funcs-fixed.S: Build 8-bit and 16-bit functions
            on AVRrc, too.

Diff:
---
 libgcc/config/avr/lib1funcs-fixed.S | 66 ++++++++++++++++++++++++++++---------
 libgcc/config/avr/lib1funcs.S       | 41 ++++++++++++++++++++++-
 libgcc/config/avr/t-avr             | 32 +++++++++---------
 3 files changed, 106 insertions(+), 33 deletions(-)

diff --git a/libgcc/config/avr/lib1funcs-fixed.S 
b/libgcc/config/avr/lib1funcs-fixed.S
index 278ee1b4a5dd..4115589b5707 100644
--- a/libgcc/config/avr/lib1funcs-fixed.S
+++ b/libgcc/config/avr/lib1funcs-fixed.S
@@ -31,14 +31,6 @@
 ;; Fixed point library routines for AVR
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
-#if defined __AVR_TINY__
-#define __zero_reg__ r17
-#define __tmp_reg__ r16
-#else                                                                          
                                                                    
-#define __zero_reg__ r1
-#define __tmp_reg__ r0
-#endif
-
 .section .text.libgcc.fixed, "ax", @progbits
 
 #ifndef __AVR_TINY__
@@ -251,6 +243,7 @@ DEFUN __fractsfusa
 ENDF __fractsfusa
 #endif  /* L_fractsfusa */
 
+#endif /* ! AVR_TINY */
 
 ;; For multiplication the functions here are called directly from
 ;; avr-fixed.md instead of using the standard libcall mechanisms.
@@ -295,8 +288,14 @@ DEFUN   __mulhq3
     rol     r25
     brvs    1f
     ;; Round
+#ifndef __AVR_TINY__
     sbrc    r23, 7
     adiw    r24, 1
+#else
+    lsl     r23
+    adc     r24, __zero_reg__
+    adc     r25, __zero_reg__
+#endif /* AVR_TINY? */
     ret
 1:  ;; Overflow.  TR 18037 requires  (-1)^2  not to overflow
     ldi     r24, lo8 (0x7fff)
@@ -315,8 +314,14 @@ ENDF __mulhq3
 DEFUN   __muluhq3
     XCALL   __umulhisi3
     ;; Round
+#ifndef __AVR_TINY__
     sbrc    r23, 7
     adiw    r24, 1
+#else
+    lsl     r23
+    adc     r24, __zero_reg__
+    adc     r25, __zero_reg__
+#endif /* AVR_TINY? */
     ret
 ENDF __muluhq3
 #endif  /* L_muluhq3 */
@@ -361,8 +366,14 @@ DEFUN   __muluha3_round
     mov     r25, r24
     mov     r24, r23
     ;; Round
+#ifndef __AVR_TINY__
     sbrc    r22, 7
     adiw    r24, 1
+#else
+    lsl     r22
+    adc     r24, __zero_reg__
+    adc     r25, __zero_reg__
+#endif /* AVR_TINY? */
     ret
 ENDF __muluha3_round
 #endif  /* L_muluha3_round */
@@ -372,6 +383,8 @@ ENDF __muluha3_round
     Fixed  Multiplication  16.16 x 16.16
 *******************************************************/
 
+#ifndef __AVR_TINY__
+
 ;; Bits outside the result (below LSB), used in the signed version
 #define GUARD __tmp_reg__
 
@@ -679,6 +692,8 @@ ENDF __mulusa3_round
 
 #undef GUARD
 
+#endif /* ! AVR_TINY */
+
 /***********************************************************
     Fixed  unsigned saturated Multiplication  8.8 x 8.8
 ***********************************************************/
@@ -762,8 +777,14 @@ DEFUN __ssmulha3
     ;; SS =  0  -->  0x7fff
     ldi     C3, 0x7f
     ldi     C2, 0xff
+#ifndef __AVR_TINY__
     sbrc    SS, 7
     adiw    C2, 1
+#else
+    lsl     SS
+    adc     C2, __zero_reg__
+    adc     C3, __zero_reg__
+#endif /* AVR_TINY? */
     ret
 ENDF  __ssmulha3
 #endif /* L_ssmulha3 */
@@ -778,6 +799,8 @@ ENDF  __ssmulha3
     Fixed  unsigned saturated Multiplication  16.16 x 16.16
 ***********************************************************/
 
+#ifndef __AVR_TINY__
+
 #define C0  18
 #define C1  C0+1
 #define C2  C0+2
@@ -883,6 +906,8 @@ ENDF  __ssmulsa3
 #undef C7
 #undef SS
 
+#endif /* ! AVR_TINY */
+
 /*******************************************************
       Fractional Division 8 / 8
 *******************************************************/
@@ -962,8 +987,8 @@ ENDF __divqq_helper
 
 #if defined (L_divhq3)
 DEFUN   __divhq3
-    mov     r0, r_divdH
-    eor     r0, r_divH
+    mov     __tmp_reg__, r_divdH
+    eor     __tmp_reg__, r_divH
     sbrs    r_divH, 7
     rjmp    1f
     NEG2    r_divL
@@ -1027,8 +1052,8 @@ ENDF __udivuha3_common
 *******************************************************/
 #if defined (L_divha3)
 DEFUN   __divha3
-    mov     r0, r_divdH
-    eor     r0, r_divH
+    mov     __tmp_reg__, r_divdH
+    eor     __tmp_reg__, r_divH
     sbrs    r_divH, 7
     rjmp    1f
     NEG2    r_divL
@@ -1040,7 +1065,7 @@ DEFUN   __divha3
     XCALL   __udivuha3
     lsr     r_quoH  ; adjust to 7 fractional bits
     ror     r_quoL
-    sbrs    r0, 7   ; negate result if needed
+    sbrs    __tmp_reg__, 7  ; negate result if needed
     ret
     NEG2    r_quoL
     ret
@@ -1069,6 +1094,8 @@ ENDF __udivuha3
     Fixed Division 16.16 / 16.16
 *******************************************************/
 
+#ifndef __AVR_TINY__
+
 #define r_arg1L  24    /* arg1 gets passed already in place */
 #define r_arg1H  25
 #define r_arg1HL 26
@@ -1171,6 +1198,8 @@ ENDF __udivusa3
 #undef  r_divHH
 #undef  r_cnt
 
+#endif /* ! AVR_TINY */
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Saturation, 1 Byte
@@ -1206,7 +1235,7 @@ ENDF __ssabs_1
 DEFUN __ssneg_2
     NEG2    A0
     brvc 0f
-    sbiw    A0, 1
+    wsubi   A0, 1
 0:  ret
 ENDF __ssneg_2
 #endif /* L_ssneg_2 */
@@ -1228,6 +1257,8 @@ ENDF __ssabs_2
 ;; Saturation, 4 Bytes
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+#ifndef __AVR_TINY__
+
 ;; First Argument and Return Register
 #define A0  22
 #define A1  A0+1
@@ -1413,6 +1444,8 @@ ENDF __sssub_8
 #undef B6
 #undef B7
 
+#endif /* ! AVR_TINY */
+
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Rounding Helpers
@@ -1613,6 +1646,8 @@ ENDF  __round_u2_const
 ;; Rounding, 4 Bytes
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
+#ifndef __AVR_TINY__
+
 #define A0 18
 #define A1 A0 + 1
 #define A2 A0 + 2
@@ -1915,6 +1950,7 @@ ENDF  __round_x8
 #undef RP
 #undef FBITm1
 
+#endif /* ! AVR_TINY */
 
 ;; Supply implementations / symbols for the bit-banging functions
 ;; __builtin_avr_bitsfx and __builtin_avr_fxbits
@@ -1923,5 +1959,3 @@ DEFUN __ret
     ret
 ENDF  __ret
 #endif /* L_ret */
-
-#endif /* if not __AVR_TINY__ */
diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S
index 01208927c6b0..52ce051e00fe 100644
--- a/libgcc/config/avr/lib1funcs.S
+++ b/libgcc/config/avr/lib1funcs.S
@@ -395,6 +395,7 @@ ENDF  __mulhi3
 
 #if defined (L_umulhisi3)
 DEFUN __umulhisi3
+#ifndef __AVR_TINY__
     wmov    B0, 24
     ;; Zero-extend B
     clr     B2
@@ -402,11 +403,48 @@ DEFUN __umulhisi3
     ;; Zero-extend A
     wmov    A2, B2
     XJMP    __mulsi3
+#else
+    ;; Push zero-extended R24
+    push    __zero_reg__
+    push    __zero_reg__
+    push    r25
+    push    r24
+    ;; Zero-extend R22
+    clr     R24
+    clr     R25
+    XCALL   __mulsi3
+    pop     __tmp_reg__
+    pop     __tmp_reg__
+    pop     __tmp_reg__
+    pop     __tmp_reg__
+    ret
+#endif /* AVR_TINY? */
 ENDF __umulhisi3
 #endif /* L_umulhisi3 */
 
 #if defined (L_mulhisi3)
 DEFUN __mulhisi3
+#ifdef __AVR_TINY__
+    ;; Push sign-extended R24
+    mov     __tmp_reg__, r25
+    lsl     __tmp_reg__
+    sbc     __tmp_reg__, __tmp_reg__
+    push    __tmp_reg__
+    push    __tmp_reg__
+    push    r25
+    push    r24
+    ;;  Sign-extend R22
+    mov     r24, r23
+    lsl     r24
+    sbc     r24, r24
+    sbc     r25, r25
+    XCALL   __mulsi3
+    pop     __tmp_reg__
+    pop     __tmp_reg__
+    pop     __tmp_reg__
+    pop     __tmp_reg__
+    ret
+#else
     wmov    B0, 24
     ;; Sign-extend B
     lsl     r25
@@ -418,7 +456,7 @@ DEFUN __mulhisi3
     sbrc    A1, 7
     com     A2
     mov     A3, A2
-    XJMP __mulsi3
+    XJMP    __mulsi3
 #else /*  no __AVR_ERRATA_SKIP_JMP_CALL__ */
     ;; Zero-extend A and __mulsi3 will run at least twice as fast
     ;; compared to a sign-extended A.
@@ -434,6 +472,7 @@ DEFUN __mulhisi3
     sbc     CC3, B1
     XJMP __mulsi3_helper
 #endif /*  __AVR_ERRATA_SKIP_JMP_CALL__ */
+#endif /* AVR_TINY? */
 ENDF __mulhisi3
 #endif /* L_mulhisi3 */
 
diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr
index b10542c8945e..d181784e0e72 100644
--- a/libgcc/config/avr/t-avr
+++ b/libgcc/config/avr/t-avr
@@ -4,6 +4,7 @@ LIB1ASMFUNCS = \
        _mulhi3 \
        _mulqihi3 _umulqihi3 \
        _mulpsi3 \
+       _mulhisi3 _umulhisi3 \
        _mulsi3 \
        _udivmodqi4 \
        _divmodqi4 \
@@ -33,12 +34,23 @@ LIB1ASMFUNCS = \
        _popcountsi2 \
        _popcountqi2 \
        _bswapsi2 \
-       _fmul _fmuls _fmulsu
+       _fmul _fmuls _fmulsu \
+       _mulqq3 \
+       _mulhq3 _muluhq3 \
+       _mulha3 _muluha3 _muluha3_round \
+       _usmuluha3 _ssmulha3 \
+       _divqq3 _udivuqq3 _divqq_helper \
+       _divhq3 _udivuhq3 \
+       _divha3 _udivuha3 \
+       _ssneg_2 \
+       _ssabs_1 _ssabs_2 \
+       _mask1 _ret \
+       _roundqq3 _rounduqq3 \
+       _round_s2 _round_u2 _round_2_const _addmask_2 \
 
 # The below functions either use registers that are not present
 # in tiny core, or use a different register convention (don't save
 # callee saved regs, for example)
-# _mulhisi3 and variations - clobber R18, R19
 # All *di funcs - use regs < R16 or expect args in regs < R20
 # _prologue and _epilogue save registers < R16
 # _load, __fload and _xload variations - expect lpm and elpm support
@@ -46,8 +58,6 @@ LIB1ASMFUNCS = \
 
 FUNCS_notiny = \
        _mulsqipsi3 \
-       _mulhisi3 \
-       _umulhisi3 \
        _usmulhisi3 \
        _muluhisi3 \
        _mulshisi3 \
@@ -81,24 +91,14 @@ FUNCS_notiny += \
        _fractsfqq _fractsfuqq \
        _fractsfhq _fractsfuhq _fractsfha _fractsfuha \
        _fractsfsq _fractsfusq _fractsfsa _fractsfusa \
-       _mulqq3 \
-       _mulhq3 _muluhq3 \
-       _mulha3 _muluha3 _muluha3_round \
        _mulsa3 _mulusa3 \
-       _usmuluha3 _ssmulha3 \
        _usmulusa3 _ssmulsa3 \
-       _divqq3 _udivuqq3 _divqq_helper \
-       _divhq3 _udivuhq3 \
-       _divha3 _udivuha3 \
        _divsa3 _udivusa3 \
        _clr_8 \
-       _ssneg_2 _ssneg_4 _ssneg_8 \
-       _ssabs_1 _ssabs_2 _ssabs_4 _ssabs_8 \
+       _ssneg_4 _ssneg_8 \
+       _ssabs_4 _ssabs_8 \
        _ssadd_8 _sssub_8 \
        _usadd_8 _ussub_8 \
-       _mask1 _ret \
-       _roundqq3 _rounduqq3 \
-       _round_s2 _round_u2 _round_2_const _addmask_2 \
        _round_s4 _round_u4 _round_4_const _addmask_4 \
        _round_x8 \
        _rounddq3 _roundudq3 \

Reply via email to