https://gcc.gnu.org/g:6a4982fb69c42996c9b307bd3926a4d50e8638d8
commit r17-3809-g6a4982fb69c42996c9b307bd3926a4d50e8638d8 Author: Georg-Johann Lay <[email protected]> Date: Tue Sep 1 13:12:19 2026 +0200 AVR: Support 32-bit (saturated) fract multiplications The SQmode and USQmode multiplications were still missing, so I added them. They follow the default ABI. libgcc/ * config/avr/t-avr (FUNCS_notiny): Add _mulsq3. * config/avr/lib1funcs-fixed.S (__mulsq3, __ssmulsq3): Implement. * config/avr/lib1funcs.S (__umulsidi3): Add ENTRYs __mulusq3, __usmulusq3. Diff: --- libgcc/config/avr/lib1funcs-fixed.S | 65 +++++++++++++++++++++++++++++++++++++ libgcc/config/avr/lib1funcs.S | 4 +++ libgcc/config/avr/t-avr | 1 + 3 files changed, 70 insertions(+) diff --git a/libgcc/config/avr/lib1funcs-fixed.S b/libgcc/config/avr/lib1funcs-fixed.S index 1ac7b5cf9862..5fac4ae464b8 100644 --- a/libgcc/config/avr/lib1funcs-fixed.S +++ b/libgcc/config/avr/lib1funcs-fixed.S @@ -906,6 +906,71 @@ ENDF __ssmulsa3 #undef C7 #undef SS +/******************************************************** + Fixed signed (saturated) Multiplication s.31 x s.31 +*********************************************************/ + +;;; Argument 1 and result +#define A0 22 +#define A1 A0+1 +#define A2 A0+2 +#define A3 A0+3 + +;;; Argument 2 +#define B0 18 +#define B1 B0+1 +#define B2 B0+2 +#define B3 B0+3 + +#if defined (L_mulsq3) +DEFUN __mulsq3 +ENTRY __ssmulsq3 + ;; tmp.7 = result sign + mov __tmp_reg__, A3 + eor __tmp_reg__, B3 + push __tmp_reg__ + .call_if_neg A3, __negsi2 ; A = |A| + .call_if_neg B3, __negsi2_r18 ; B = |B| + + XCALL __umulsidi3 + ;; Adjust for only 31 fractional bits. + lsl A0 + rol A1 + rol A2 + rol A3 + + ;; r30.7 = result sign + pop r30 + + brcs .Lsaturate + ;; In the negative result case, A = 0x80.. is no overflow, + ;; but treating it as such keeps the value unchanged. + brmi .Lsaturate ; Overflow? + ;; Handle result sign. + sbrs r30, 7 + ret + XJMP __negsi2 +.Lsaturate: + ;; r30.7 = 0 -> C = 1 -> 0x7f.. + ;; r30.7 = 1 -> C = 0 -> 0x80.. + cpi r30, 0x80 + sbc A0, A0 + sbc A1, A1 + wmov A2, A0 + subi A3, 0x80 + ret +ENDF __mulsq3 +#endif /* L_mulsq3 */ + +#undef A0 +#undef A1 +#undef A2 +#undef A3 +#undef B0 +#undef B1 +#undef B2 +#undef B3 + /******************************************************* Fixed 64 x 64 saturated Multiplication *******************************************************/ diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S index 1a7ed9483cf0..c2df9d928717 100644 --- a/libgcc/config/avr/lib1funcs.S +++ b/libgcc/config/avr/lib1funcs.S @@ -943,6 +943,8 @@ ENDF __muldi3 ;; X = R20[2] = B2[2] ;; Z = R22[2] = A0[2] DEFUN __umulsidi3 +ENTRY __mulusq3 +ENTRY __usmulusq3 clt ;; FALLTHRU ENDF __umulsidi3 @@ -1091,6 +1093,8 @@ DEFUN __mulsidi3 ENDF __mulsidi3 DEFUN __umulsidi3 +ENTRY __mulusq3 +ENTRY __usmulusq3 clt ; skipped ;; Save 10 Registers: R10..R17, R28, R29 do_prologue_saves 10 diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr index 947666269f75..891afd364732 100644 --- a/libgcc/config/avr/t-avr +++ b/libgcc/config/avr/t-avr @@ -98,6 +98,7 @@ FUNCS_notiny += \ _fractsfhq _fractsfuhq _fractsfha _fractsfuha \ _fractsfsq _fractsfusq _fractsfsa _fractsfusa \ _mulsa3 _mulusa3 \ + _mulsq3 \ _usmulusa3 _ssmulsa3 \ _umulditi3_raw \ _muluda3 _muluta3 _muludq3 \
