From fa548c5afa5736f335f40f19a338f59296833569 Mon Sep 17 00:00:00 2001 From: Georg-Johann Lay Date: Sun, 19 Oct 2025 16:42:07 +0200 Subject: [PATCH] AVR: The nzb=1 patterns with IOR, XOR, AND work the same way with PLUS. gcc/ * config/avr/avr.cc (avr_nonzero_bits_lsr_operands_p): Also handle PLUS. * config/avr/avr.md (pixaop): New code iterator for PLUS, IOR, XOR, AND. (nzb=1 insns): Use pixaop instead of bitop code iterator. Handle PLUS in outputs. --- gcc/config/avr/avr.cc | 3 +- gcc/config/avr/avr.md | 131 ++++++++++++++++++++++-------------------- 2 files changed, 70 insertions(+), 64 deletions(-) diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 0cee9256577..227c12a9b32 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -15222,7 +15222,7 @@ avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op, /* A helper for the insn condition of "*nzb=1..lsr[.not]_split" - where is AND, IOR or XOR. Return true when + where is AND, IOR, XOR or PLUS. Return true when OP[0] = OP[1] >> OP[2] @@ -15251,6 +15251,7 @@ avr_nonzero_bits_lsr_operands_p (rtx_code code, rtx *op) case IOR: case XOR: + case PLUS: return op1_non0 >> offs == 1; case AND: diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 103b38dc38c..30a02a4b6c9 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -343,6 +343,7 @@ (define_code_iterator piaop [plus ior and]) (define_code_iterator pixop [plus ior xor]) (define_code_iterator bitop [xor ior and]) +(define_code_iterator pixaop [plus ior xor and]) (define_code_iterator xior [xor ior]) (define_code_iterator eqne [eq ne]) (define_code_iterator gelt [ge lt]) @@ -10519,41 +10520,41 @@ ;; split by that pass must have insn attribute "nzb" set to "yes". Moreover, ;; the insns to split must be single_sets and must not touch control flow. -(define_code_attr nzb_constr_rdr [(and "r") (ior "d") (xor "r")]) -(define_code_attr nzb_use1_nnr [(and "n") (ior "n") (xor "r")]) +(define_code_attr nzb_constr_rdrr [(and "r") (ior "d") (xor "r") (plus "r")]) +(define_code_attr nzb_use1_nnrn [(and "n") (ior "n") (xor "r") (plus "n")]) (define_insn_and_split "*nzb=1..zerox_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (zero_extract:QI (match_operand:QI 1 "register_operand") - (const_int 1) - (match_operand:QI 2 "const_0_to_7_operand")) - (match_operand:QI 3 "register_operand")))] + (pixaop:QI (zero_extract:QI (match_operand:QI 1 "register_operand") + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed - && ( == IOR || == XOR + && ( == IOR || == XOR || == PLUS || nonzero_bits (operands[3], QImode) == 1)" { gcc_unreachable (); } "optimize && avropt_use_nonzero_bits && !reload_completed" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (match_dup 1) - (const_int 1) - (match_dup 2)) - (unspec:QI [(match_dup 3) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (match_dup 1) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" [(set_attr "nzb" "yes")]) (define_insn "*nzb=1..zerox" - [(set (match_operand:QI 0 "register_operand" "=") - (bitop:QI (zero_extract:QI (match_operand:QI 1 "register_operand" "r") - (const_int 1) - (match_operand:QI 2 "const_0_to_7_operand" "n")) - (unspec:QI [(match_operand:QI 3 "register_operand" "0") - ] UNSPEC_NZB))) - (use (match_operand:QI 4 "nonmemory_operand" "")) + [(set (match_operand:QI 0 "register_operand" "=") + (pixaop:QI (zero_extract:QI (match_operand:QI 1 "register_operand" "r") + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand" "n")) + (unspec:QI [(match_operand:QI 3 "register_operand" "0") + ] UNSPEC_NZB))) + (use (match_operand:QI 4 "nonmemory_operand" "")) (clobber (reg:CC REG_CC))] "optimize && avropt_use_nonzero_bits" { @@ -10563,6 +10564,8 @@ return "sbrc %1,%2\;ori %0,1"; else if ( == XOR) return "sbrc %1,%2\;eor %0,%4"; + else if ( == PLUS) + return "sbrc %1,%2\;inc %0"; else gcc_unreachable (); } @@ -10570,9 +10573,9 @@ (define_insn_and_split "*nzb=1..lsr_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (lshiftrt:QI (match_operand:QI 1 "register_operand") - (match_operand:QI 2 "const_0_to_7_operand")) - (match_operand:QI 3 "register_operand")))] + (pixaop:QI (lshiftrt:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed && avr_nonzero_bits_lsr_operands_p (, operands)" @@ -10580,11 +10583,11 @@ "optimize && avropt_use_nonzero_bits && !reload_completed" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (match_dup 1) - (const_int 1) - (match_dup 2)) - (unspec:QI [(match_dup 3) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (match_dup 1) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" @@ -10592,26 +10595,26 @@ (define_insn_and_split "*nzb=1..zerox.not_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (zero_extract:QI (xor:QI (match_operand:QI 1 "register_operand") - (match_operand:QI 4 "const_int_operand")) - (const_int 1) - (match_operand:QI 2 "const_0_to_7_operand")) - (match_operand:QI 3 "register_operand")))] + (pixaop:QI (zero_extract:QI (xor:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 4 "const_int_operand")) + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed && INTVAL (operands[2]) == exact_log2 (0xff & INTVAL (operands[4])) - && ( == IOR + && ( == IOR || == XOR || == PLUS || nonzero_bits (operands[3], QImode) == 1)" { gcc_unreachable (); } "optimize && avropt_use_nonzero_bits && !reload_completed" ; "*nzb=1..zerox.not" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) - (const_int 1) - (match_dup 2)) - (unspec:QI [(match_dup 3) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" @@ -10619,10 +10622,10 @@ (define_insn_and_split "*nzb=1..lsr.not_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (lshiftrt:QI (xor:QI (match_operand:QI 1 "register_operand") - (match_operand:QI 4 "const_int_operand")) - (match_operand:QI 2 "const_0_to_7_operand")) - (match_operand:QI 3 "register_operand")))] + (pixaop:QI (lshiftrt:QI (xor:QI (match_operand:QI 1 "register_operand") + (match_operand:QI 4 "const_int_operand")) + (match_operand:QI 2 "const_0_to_7_operand")) + (match_operand:QI 3 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed && INTVAL (operands[2]) == exact_log2 (0xff & INTVAL (operands[4])) @@ -10632,11 +10635,11 @@ && !reload_completed" ; "*nzb=1..zerox.not" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) - (const_int 1) - (match_dup 2)) - (unspec:QI [(match_dup 3) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (match_dup 2)) + (unspec:QI [(match_dup 3) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" @@ -10644,36 +10647,36 @@ (define_insn_and_split "*nzb=1..ge0_split" [(set (match_operand:QI 0 "register_operand") - (bitop:QI (ge:QI (match_operand:QI 1 "register_operand") - (const_int 0)) - (match_operand:QI 2 "register_operand")))] + (pixaop:QI (ge:QI (match_operand:QI 1 "register_operand") + (const_int 0)) + (match_operand:QI 2 "register_operand")))] "optimize && avropt_use_nonzero_bits && !reload_completed - && ( == IOR || == XOR + && ( == IOR || == XOR || == PLUS || nonzero_bits (operands[2], QImode) == 1)" { gcc_unreachable (); } "optimize && avropt_use_nonzero_bits && !reload_completed" ; "*nzb=1..zerox.not" [(parallel [(set (match_dup 0) - (bitop:QI (zero_extract:QI (not:QI (match_dup 1)) - (const_int 1) - (const_int 7)) - (unspec:QI [(match_dup 2) - ] UNSPEC_NZB))) + (pixaop:QI (zero_extract:QI (not:QI (match_dup 1)) + (const_int 1) + (const_int 7)) + (unspec:QI [(match_dup 2) + ] UNSPEC_NZB))) (use (const_int 1)) (clobber (reg:CC REG_CC))])] "" [(set_attr "nzb" "yes")]) (define_insn "*nzb=1..zerox.not" - [(set (match_operand:QI 0 "register_operand" "=") - (bitop:QI (zero_extract:QI (not:QI (match_operand:QI 1 "register_operand" "r")) - (const_int 1) - (match_operand:QI 2 "const_0_to_7_operand" "n")) - (unspec:QI [(match_operand:QI 3 "register_operand" "0") - ] UNSPEC_NZB))) - (use (match_operand:QI 4 "nonmemory_operand" "")) + [(set (match_operand:QI 0 "register_operand" "=") + (pixaop:QI (zero_extract:QI (not:QI (match_operand:QI 1 "register_operand" "r")) + (const_int 1) + (match_operand:QI 2 "const_0_to_7_operand" "n")) + (unspec:QI [(match_operand:QI 3 "register_operand" "0") + ] UNSPEC_NZB))) + (use (match_operand:QI 4 "nonmemory_operand" "")) (clobber (reg:CC REG_CC))] "optimize && avropt_use_nonzero_bits" { @@ -10683,6 +10686,8 @@ return "sbrs %1,%2\;ori %0,1"; else if ( == XOR) return "sbrs %1,%2\;eor %0,%4"; + else if ( == PLUS) + return "sbrs %1,%2\;inc %0"; else gcc_unreachable (); } -- 2.47.3