From: Georg-Johann Lay Date: Fri, 3 Jul 2026 15:30:04 +0000 (+0200) Subject: AVR: Adding +/-1 to a lower reg doesn't need a scratch. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f84dfd8305963f124c624570bb6eb0c84149f67a;p=thirdparty%2Fgcc.git AVR: Adding +/-1 to a lower reg doesn't need a scratch. 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 (add3_clobber, *add3_clobber) (add3, *add3, addpsi3, *addpsi3): Add constraint alternative "Y01 Ym1" for +/-1 without scratch. --- diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index ebc3def80df..cdf676ca312 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -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); diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 57d63a8f746..f57df70db93 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -1817,10 +1817,10 @@ ;; "addhq3_clobber" "adduhq3_clobber" ;; "addha3_clobber" "adduha3_clobber" (define_insn_and_split "add3_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" @@ -1831,10 +1831,10 @@ ;; "*addhq3_clobber" "*adduhq3_clobber" ;; "*addha3_clobber" "*adduha3_clobber" (define_insn "*add3_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" { @@ -1848,10 +1848,10 @@ ;; "addsq3" "addusq3" ;; "addsa3" "addusa3" (define_insn_and_split "add3" - [(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" @@ -1859,10 +1859,10 @@ { DONE_ADD_CCC }) (define_insn "*add3" - [(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" { @@ -1951,10 +1951,10 @@ (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" @@ -1962,10 +1962,10 @@ { 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" {