]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AVR: Add R18:SI = neg R18:SI to libgcc.
authorGeorg-Johann Lay <avr@gjlay.de>
Wed, 8 Jul 2026 17:40:26 +0000 (19:40 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Wed, 8 Jul 2026 19:42:34 +0000 (21:42 +0200)
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.

libgcc/config/avr/asm-defs.h
libgcc/config/avr/lib1funcs-fixed.S
libgcc/config/avr/lib1funcs.S
libgcc/config/avr/t-avr

index 62879464f9d3bfbd7d3531db49781c15be8b86bb..cf943f046e9ad96c4cd024362a9163f9a4561286 100644 (file)
 .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.
 
index 4b77ee2dd56d1c1420e7d8770dae45c000647826..0414b3a2eed9d2f1a1984b0a0b65f4e7d0c2cf91 100644 (file)
@@ -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
index 6af40122f022545ad5eea41da5e077accb598da2..2e30c796ef94b4f9833aaa2149c6a056387be7b7 100644 (file)
@@ -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. */
 
index 9b05c8575b6ace8ec4891df62a64cffb2f3da5bc..2f9a2efc3cf49958a85369c8f1ea13a441fdac41 100644 (file)
@@ -14,6 +14,7 @@ LIB1ASMFUNCS = \
        _udivmodsi4 \
        _divmodsi4 \
        _negsi2 \
+       _negsi2_r18 \
        _exit \
        _cleanup \
        _tablejump2 \