[gcc r17-3809] AVR: Support 32-bit (saturated) fract multiplications

Georg-Johann Lay gjl@gcc.gnu.org
Tue Sep 1 11:25:49 GMT 2026


https://gcc.gnu.org/g:6a4982fb69c42996c9b307bd3926a4d50e8638d8

commit r17-3809-g6a4982fb69c42996c9b307bd3926a4d50e8638d8
Author: Georg-Johann Lay <avr@gjlay.de>
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 \


More information about the Gcc-cvs mailing list