https://gcc.gnu.org/g:9f8e18213cbcfbadce56f7f531bd61fe4c7eab11

commit r15-3659-g9f8e18213cbcfbadce56f7f531bd61fe4c7eab11
Author: Georg-Johann Lay <a...@gjlay.de>
Date:   Sun Sep 15 20:37:48 2024 +0200

    AVR: Partially revert r15-3623.
    
    ADIW doesn't mix with CPC / SBIC because it's not only about
    propagating the Z flag but also about carry.
    
    gcc/
            * config/avr/avr.cc (avr_out_compare): Don't mix ADIW with SBCI / 
CPC.

Diff:
---
 gcc/config/avr/avr.cc | 32 ++++++++++----------------------
 1 file changed, 10 insertions(+), 22 deletions(-)

diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index 4cb51ea68dc7..5597f3ef74dc 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -6026,25 +6026,15 @@ avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
   if (n_bytes == 4
       && eqne_p
       && AVR_HAVE_ADIW
-      && REGNO (xreg) >= REG_22)
+      && REGNO (xreg) >= REG_22
+      && (xval == const0_rtx
+         || (IN_RANGE (avr_int16 (xval, 2), 0, 63)
+             && reg_unused_after (insn, xreg))))
     {
-      if (xval == const0_rtx)
-       return avr_asm_len ("sbiw %C0,0"           CR_TAB
-                           "cpc %B0,__zero_reg__" CR_TAB
-                           "cpc %A0,__zero_reg__", xop, plen, 3);
-
-      int16_t hi16 = avr_int16 (xval, 2);
-      if (reg_unused_after (insn, xreg)
-         && (IN_RANGE (hi16, 0, 63)
-             || (eqne_p
-                 && IN_RANGE (hi16, -63, -1))))
-       {
-         rtx op[] = { xop[0], avr_word (xval, 2) };
-         avr_asm_len (hi16 < 0 ? "adiw %C0,%n1" : "sbiw %C0,%1",
-                      op, plen, 1);
-         return avr_asm_len ("sbci %B0,hi8(%1)" CR_TAB
-                             "sbci %A0,lo8(%1)", xop, plen, 2);
-       }
+      xop[2] = avr_word (xval, 2);
+      return avr_asm_len ("sbiw %C0,%2"      CR_TAB
+                         "sbci %B0,hi8(%1)" CR_TAB
+                         "sbci %A0,lo8(%1)", xop, plen, 3);
     }
 
   bool changed[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
@@ -6078,12 +6068,10 @@ avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
 
          if (IN_RANGE (val16, -63, -1)
              && eqne_p
+             && n_bytes == 2
              && reg_unused_after (insn, xreg))
            {
-             avr_asm_len ("adiw %0,%n1", xop, plen, 1);
-             changed[0] = changed[1] = true;
-             i++;
-             continue;
+             return avr_asm_len ("adiw %0,%n1", xop, plen, 1);
            }
        }

Reply via email to