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.
Johann
--
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.diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc
index ebc3def80df..277d3952df1 100644
--- a/gcc/config/avr/avr.cc
+++ b/gcc/config/avr/avr.cc
@@ -8921,6 +8919,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 @@ (define_peephole2 ; addhi3_clobber
;; "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"
@@ -1831,10 +1831,10 @@ (define_insn_and_split "add<mode>3_clobber"
;; "*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"
{
@@ -1848,10 +1848,10 @@ (define_insn "*add<mode>3_clobber"
;; "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"
@@ -1859,10 +1859,10 @@ (define_insn_and_split "add<mode>3"
{ 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"
{
@@ -1951,10 +1951,10 @@ (define_insn "*sub<HISI:mode>3.<code>.<QIPSI:mode>"
(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 @@ (define_insn_and_split "addpsi3"
{ 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"
{