]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AVR: Adding +/-1 to a lower reg doesn't need a scratch.
authorGeorg-Johann Lay <avr@gjlay.de>
Fri, 3 Jul 2026 15:30:04 +0000 (17:30 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Fri, 3 Jul 2026 17:24:53 +0000 (19:24 +0200)
Adding +/-1 to a lower register can be performed by sequences like
   sec
   adc r14, __zero_reg__
   adc r15, __zero_reg__
resp.
   sec
   sbc r14, __zero_reg__
   sbc r15, __zero_reg__
that don't need a scratch reg.  The code size is unchanged but
the register pressure goes down.

gcc/
* config/avr/avr.cc (avr_out_plus_1): Handle +/-1 on the
lower regs without needing a scratch.
* config/avr/avr.md (add<mode>3_clobber, *add<mode>3_clobber)
(add<mode>3, *add<mode>3, addpsi3, *addpsi3): Add constraint
alternative "Y01 Ym1" for +/-1 without scratch.

gcc/config/avr/avr.cc
gcc/config/avr/avr.md

index ebc3def80df0adb0d34ff1ead928ca92f2f839bf..cdf676ca312ff7a63c51a1ba49ea517479237fa7 100644 (file)
@@ -8921,6 +8921,22 @@ avr_out_plus_1 (rtx xinsn, rtx *xop, int *plen, rtx_code code,
   if (xval == const0_rtx)
     return;
 
+  // Adding +/-1 to a lower reg doesn't need a scratch.
+
+  if (IN_RANGE (n_bytes, 2, 4)
+      && code_sat == UNKNOWN
+      && (xval == const1_rtx || xval == constm1_rtx)
+      && ! test_hard_reg_class (LD_REGS, xop[0]))
+    {
+      avr_asm_len ("sec", nullptr, plen, 1);
+
+      for (auto r = REGNO (xop[0]); r < REGNO (xop[0]) + n_bytes; ++r)
+       avr_asm_len (xval == const1_rtx
+                    ? "adc %0,__zero_reg__"
+                    : "sbc %0,__zero_reg__", &all_regs_rtx[r], plen, 1);
+      return;
+    }
+
   if (MINUS == code)
     xval = simplify_unary_operation (NEG, imode, xval, imode);
 
index 57d63a8f7463740de9c8fc2af63c9bf396f54680..f57df70db930199142d1d137b51554e5665f6caf 100644 (file)
 ;; "addhq3_clobber" "adduhq3_clobber"
 ;; "addha3_clobber" "adduha3_clobber"
 (define_insn_and_split "add<mode>3_clobber"
-  [(set (match_operand:ALL2 0 "register_operand"            "=!w    ,d    ,r")
-        (plus:ALL2 (match_operand:ALL2 1 "register_operand"  "%0    ,0    ,0")
-                   (match_operand:ALL2 2 "const_operand"     "IJ YIJ,n Ynn,n Ynn")))
-   (clobber (match_scratch:QI 3                             "=X     ,X    ,&d"))]
+  [(set (match_operand:ALL2 0 "register_operand"            "=!w    ,d    ,*l     ,r")
+        (plus:ALL2 (match_operand:ALL2 1 "register_operand"  "%0    ,0    ,0      ,0")
+                   (match_operand:ALL2 2 "const_operand"     "IJ YIJ,n Ynn,Y01 Ym1,n Ynn")))
+   (clobber (match_scratch:QI 3                             "=X     ,X    ,X      ,&d"))]
   ""
   "#"
   "&& reload_completed"
 ;; "*addhq3_clobber"  "*adduhq3_clobber"
 ;; "*addha3_clobber"  "*adduha3_clobber"
 (define_insn "*add<mode>3_clobber"
-  [(set (match_operand:ALL2 0 "register_operand"            "=!w    ,d    ,r")
-        (plus:ALL2 (match_operand:ALL2 1 "register_operand"  "%0    ,0    ,0")
-                   (match_operand:ALL2 2 "const_operand"     "IJ YIJ,n Ynn,n Ynn")))
-   (clobber (match_scratch:QI 3                             "=X     ,X    ,&d"))
+  [(set (match_operand:ALL2 0 "register_operand"            "=!w    ,d    ,*l     ,r")
+        (plus:ALL2 (match_operand:ALL2 1 "register_operand"  "%0    ,0    ,0      ,0")
+                   (match_operand:ALL2 2 "const_operand"     "IJ YIJ,n Ynn,Y01 Ym1,n Ynn")))
+   (clobber (match_scratch:QI 3                             "=X     ,X    ,X      ,&d"))
    (clobber (reg:CC REG_CC))]
   "reload_completed"
   {
 ;; "addsq3" "addusq3"
 ;; "addsa3" "addusa3"
 (define_insn_and_split "add<mode>3"
-  [(set (match_operand:ALL4 0 "register_operand"          "=??r,d ,r")
-        (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
-                   (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
-   (clobber (match_scratch:QI 3                             "=X,X ,&d"))]
+  [(set (match_operand:ALL4 0 "register_operand"          "=??r,d ,*r     ,r")
+        (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0      ,0")
+                   (match_operand:ALL4 2 "nonmemory_operand" "r,i ,Y01 Ym1,n Ynn")))
+   (clobber (match_scratch:QI 3                             "=X,X ,X      ,&d"))]
   ""
   "#"
   "&& reload_completed"
   { DONE_ADD_CCC })
 
 (define_insn "*add<mode>3"
-  [(set (match_operand:ALL4 0 "register_operand"          "=??r,d ,r")
-        (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0")
-                   (match_operand:ALL4 2 "nonmemory_operand" "r,i ,n Ynn")))
-   (clobber (match_scratch:QI 3                             "=X,X ,&d"))
+  [(set (match_operand:ALL4 0 "register_operand"          "=??r,d ,*r     ,r")
+        (plus:ALL4 (match_operand:ALL4 1 "register_operand" "%0,0 ,0      ,0")
+                   (match_operand:ALL4 2 "nonmemory_operand" "r,i ,Y01 Ym1,n Ynn")))
+   (clobber (match_scratch:QI 3                             "=X,X ,X      ,&d"))
    (clobber (reg:CC REG_CC))]
   "reload_completed"
   {
 
 
 (define_insn_and_split "addpsi3"
-  [(set (match_operand:PSI 0 "register_operand"         "=??r,d ,d,r")
-        (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
-                  (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
-   (clobber (match_scratch:QI 3                           "=X,X ,X,&d"))]
+  [(set (match_operand:PSI 0 "register_operand"         "=??r,d ,d,*r     ,r")
+        (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0      ,0")
+                  (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,Y01 Ym1,n")))
+   (clobber (match_scratch:QI 3                           "=X,X ,X,X      ,&d"))]
   ""
   "#"
   "&& reload_completed"
   { DONE_ADD_CCC })
 
 (define_insn "*addpsi3"
-  [(set (match_operand:PSI 0 "register_operand"         "=??r,d ,d,r")
-        (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0")
-                  (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,n")))
-   (clobber (match_scratch:QI 3                           "=X,X ,X,&d"))
+  [(set (match_operand:PSI 0 "register_operand"         "=??r,d ,d,*r     ,r")
+        (plus:PSI (match_operand:PSI 1 "register_operand" "%0,0 ,0,0      ,0")
+                  (match_operand:PSI 2 "nonmemory_operand" "r,s ,n,Y01 Ym1,n")))
+   (clobber (match_scratch:QI 3                           "=X,X ,X,X      ,&d"))
    (clobber (reg:CC REG_CC))]
   "reload_completed"
   {