https://gcc.gnu.org/g:b65eb20e8fff1bc572a49fae254055ccfc7799aa
commit r17-3805-gb65eb20e8fff1bc572a49fae254055ccfc7799aa Author: Georg-Johann Lay <[email protected]> Date: Tue Sep 1 09:47:46 2026 +0200 AVR: Fix 64-bit signed fixed-point multiply The recently added 64-bit signed fixed-point multiply calculated |B| but didn't restore it, which is wrong code when the caller reuses B after the multiplication in the assumption that the respective callee-saved regs are unaltered. This patch stores the sign of B and unclobbers B by negating it twice when it is negative, instead of only once. libgcc/ * config/avr/lib1funcs-fixed.S (__mulQ64_work): Restore B = R10..R17 to its orignal value. Diff: --- libgcc/config/avr/lib1funcs-fixed.S | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/libgcc/config/avr/lib1funcs-fixed.S b/libgcc/config/avr/lib1funcs-fixed.S index 142b832c2a18..1ac7b5cf9862 100644 --- a/libgcc/config/avr/lib1funcs-fixed.S +++ b/libgcc/config/avr/lib1funcs-fixed.S @@ -1152,6 +1152,8 @@ ENDF __multa3 DEFUN __mulQ64_work mov __tmp_reg__, A7 eor __tmp_reg__, B7 + bst B7, 7 + bld __tmp_reg__, 0 push __tmp_reg__ .call_if_neg A7, __negdi2 ; A = |A| @@ -1160,6 +1162,20 @@ DEFUN __mulQ64_work set ; for signed XICALL ; __muluxx3.2 + ;; r30.7 = sign result + ;; r30.0 = sign B + pop r30 + + ;; If we clobbered B, unclobber it now. +#ifdef __AVR_ERRATA_SKIP_JMP_CALL__ + asr r30 + brcc 0f +#else + sbrc r30, 0 +#endif + XCALL __negdi2_r10 +0: + ;; Adjust for signed Q formats that have one FBIT less. lsl A0 ;; Insert LSB from the unsigned mult. @@ -1172,9 +1188,6 @@ DEFUN __mulQ64_work rol A6 rol A7 - ;; r30.7 = result sign - pop r30 - ;; Handle overflow. brcs .Lsaturate ;; In the negative result case, A = 0x80.. is no overflow,
