[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