[gcc r17-2262] AVR: Add R18:SI = neg R18:SI to libgcc.

Georg-Johann Lay via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:7b350a051058e95bb2640469bd040daab671f26c

commit r17-2262-g7b350a051058e95bb2640469bd040daab671f26c
Author: Georg-Johann Lay <[email protected]>
Date:   Wed Jul 8 19:40:26 2026 +0200

    AVR: Add R18:SI = neg R18:SI to libgcc.
    
    This patch factors out negating R18:SI which is used in several
    places.  It also adds
    
       .macro  .call_if_neg  reg, labl
    
    for convenience.  It calls <labl> iff <reg> < 0.
    
    libgcc/
            * config/avr/t-avr (LIB1ASMFUNCS): Add _negsi2_r18.
            * config/avr/asm-defs.h (.call_if_neg): New .macro.
            * config/avr/lib1funcs.S (__divmodsi4): Use .call_if_neg.
            (__negsi2_r18): New function.
            * config/avr/lib1funcs-fixed.S (__divsa3): Use .call_if_neg.

Diff:
---
 libgcc/config/avr/asm-defs.h        | 15 ++++++++++
 libgcc/config/avr/lib1funcs-fixed.S |  5 +---
 libgcc/config/avr/lib1funcs.S       | 55 ++++++++++++++++++-------------------
 libgcc/config/avr/t-avr             |  1 +
 4 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/libgcc/config/avr/asm-defs.h b/libgcc/config/avr/asm-defs.h
index 62879464f9d3..cf943f046e9a 100644
--- a/libgcc/config/avr/asm-defs.h
+++ b/libgcc/config/avr/asm-defs.h
@@ -159,6 +159,21 @@
 .endm ; .branch_plus
 
 
+;;; [R]CALL label LABL when REG is negative (REG.7 = 1).
+;;; Otherwise, fallthrough.
+.macro  .call_if_neg  reg, labl
+#ifdef __AVR_ERRATA_SKIP_JMP_CALL__
+    ;; Some cores have a problem skipping 2-word instructions.
+    tst     \reg
+    brpl    .L.call_if_neg.\@
+#else
+    sbrc    \reg, 7
+#endif /* skip erratum */
+    XCALL   \labl
+.L.call_if_neg.\@:
+.endm ; .call_if_neg
+
+
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Macros for convenience.
 
diff --git a/libgcc/config/avr/lib1funcs-fixed.S b/libgcc/config/avr/lib1funcs-fixed.S
index 4b77ee2dd56d..0414b3a2eed9 100644
--- a/libgcc/config/avr/lib1funcs-fixed.S
+++ b/libgcc/config/avr/lib1funcs-fixed.S
@@ -1118,10 +1118,7 @@ ENDF __udivuha3
 DEFUN   __divsa3
     mov     r0, r_arg1HH
     eor     r0, r_divHH
-    sbrs    r_divHH, 7
-    rjmp    1f
-    NEG4    r_divL
-1:
+    .call_if_neg r_divHH, __negsi2_r18
     sbrs    r_arg1HH, 7
     rjmp    2f
     NEG4    r_arg1L
diff --git a/libgcc/config/avr/lib1funcs.S b/libgcc/config/avr/lib1funcs.S
index 6af40122f022..2e30c796ef94 100644
--- a/libgcc/config/avr/lib1funcs.S
+++ b/libgcc/config/avr/lib1funcs.S
@@ -1504,42 +1504,21 @@ ENDF __udivmodsi4
 #if defined (L_divmodsi4)
 DEFUN __divmodsi4
     mov     __tmp_reg__,r_arg2HH
-    bst     r_arg1HH,7          ; store sign of dividend
+    bst     r_arg1HH,7                  ; store sign of dividend
     brtc    0f
-    com     __tmp_reg__         ; r0.7 is sign of result
-    XCALL   __negsi2            ; dividend negative: negate
+    com     __tmp_reg__                 ; r0.7 is sign of result
+    XCALL   __negsi2                    ; dividend negative: negate
 0:
-    sbrc    r_arg2HH,7
-    rcall   __divmodsi4_neg2    ; divisor negative: negate
-    XCALL   __udivmodsi4        ; do the unsigned div/mod
-    sbrc    __tmp_reg__, 7      ; correct quotient sign
-    rcall   __divmodsi4_neg2
-    brtc    __divmodsi4_exit    ; correct remainder sign
+    .call_if_neg r_arg2HH, __negsi2_r18 ; divisor negative: negate
+    XCALL   __udivmodsi4                ; do the unsigned div/mod
+    .call_if_neg __tmp_reg__, __negsi2_r18 ; correct quotient sign
+    brtc    __divmodsi4_exit            ; correct remainder sign
     XJMP    __negsi2
-__divmodsi4_neg2:
-    ;; correct divisor/quotient sign
-    com     r_arg2HH
-    com     r_arg2HL
-    com     r_arg2H
-    neg     r_arg2L
-    sbci    r_arg2H,0xff
-    sbci    r_arg2HL,0xff
-    sbci    r_arg2HH,0xff
 __divmodsi4_exit:
     ret
 ENDF __divmodsi4
 #endif /* defined (L_divmodsi4) */
 
-#if defined (L_negsi2)
-;; (set (reg:SI 22)
-;;      (neg:SI (reg:SI 22)))
-;; Sets the V flag for signed overflow tests
-DEFUN __negsi2
-    NEG4    22
-    ret
-ENDF __negsi2
-#endif /* L_negsi2 */
-
 #undef r_remHH
 #undef r_remHL
 #undef r_remH
@@ -1554,6 +1533,26 @@ ENDF __negsi2
 #undef r_arg2L
 #undef r_cnt
 
+#if defined (L_negsi2)
+;; (set (reg:SI 22)
+;;      (neg:SI (reg:SI 22)))
+;; Sets the V flag for signed overflow tests
+DEFUN __negsi2
+    NEG4    22
+    ret
+ENDF __negsi2
+#endif /* L_negsi2 */
+
+#if defined (L_negsi2_r18)
+;; (set (reg:SI 18)
+;;      (neg:SI (reg:SI 18)))
+;; Sets the V flag for signed overflow tests
+DEFUN __negsi2_r18
+    NEG4    18
+    ret
+ENDF __negsi2_r18
+#endif /* L_negsi2_r18 */
+
 /* *di routines use registers below R19 and won't work with tiny arch
    right now. */
 
diff --git a/libgcc/config/avr/t-avr b/libgcc/config/avr/t-avr
index 9b05c8575b6a..2f9a2efc3cf4 100644
--- a/libgcc/config/avr/t-avr
+++ b/libgcc/config/avr/t-avr
@@ -14,6 +14,7 @@ LIB1ASMFUNCS = \
 	_udivmodsi4 \
 	_divmodsi4 \
 	_negsi2 \
+	_negsi2_r18 \
 	_exit \
 	_cleanup \
 	_tablejump2 \
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.