]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
AVR: The nzb=1 patterns with IOR, XOR, AND work the same way with PLUS.
authorGeorg-Johann Lay <avr@gjlay.de>
Sun, 19 Oct 2025 14:42:07 +0000 (16:42 +0200)
committerGeorg-Johann Lay <avr@gjlay.de>
Sun, 19 Oct 2025 14:48:35 +0000 (16:48 +0200)
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
gcc/config/avr/avr.md

index 0cee92565777e67efa3eb626b21aaff6a588d083..227c12a9b3203b38f8f72278c3dfe4a663c39736 100644 (file)
@@ -15222,7 +15222,7 @@ avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
 
 
 /* A helper for the insn condition of "*nzb=1.<code>.lsr[.not]_split"
-   where <code> is AND, IOR or XOR.  Return true when
+   where <code> is AND, IOR, XOR or PLUS.  Return true when
 
       OP[0] <code>= 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:
index 103b38dc38c66a7821fa7f49d7d63f39f9b5c4a8..30a02a4b6c9dd947effed75d9477e9a570cb2002 100644 (file)
 (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])
 ;; 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.<code>.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
-   && (<CODE> == IOR || <CODE> == XOR
+   && (<CODE> == IOR || <CODE> == XOR || <CODE> == 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.<code>.zerox"
-  [(set (match_operand:QI 0 "register_operand"                "=<nzb_constr_rdr>")
-        (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" "<nzb_use1_nnr>"))
+  [(set (match_operand:QI 0 "register_operand"                "=<nzb_constr_rdrr>")
+        (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" "<nzb_use1_nnrn>"))
    (clobber (reg:CC REG_CC))]
   "optimize && avropt_use_nonzero_bits"
   {
       return "sbrc %1,%2\;ori %0,1";
     else if (<CODE> == XOR)
       return "sbrc %1,%2\;eor %0,%4";
+    else if (<CODE> == PLUS)
+      return "sbrc %1,%2\;inc %0";
     else
       gcc_unreachable ();
   }
 
 (define_insn_and_split "*nzb=1.<code>.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 (<CODE>, operands)"
   "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))])]
   ""
 
 (define_insn_and_split "*nzb=1.<code>.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]))
-   && (<CODE> == IOR
+   && (<CODE> == IOR || <CODE> == XOR || <CODE> == PLUS
        || nonzero_bits (operands[3], QImode) == 1)"
   { gcc_unreachable (); }
   "optimize && avropt_use_nonzero_bits
    && !reload_completed"
   ; "*nzb=1.<code>.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))])]
   ""
 
 (define_insn_and_split "*nzb=1.<code>.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]))
    && !reload_completed"
   ; "*nzb=1.<code>.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))])]
   ""
 
 (define_insn_and_split "*nzb=1.<code>.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
-   && (<CODE> == IOR || <CODE> == XOR
+   && (<CODE> == IOR || <CODE> == XOR || <CODE> == PLUS
        || nonzero_bits (operands[2], QImode) == 1)"
   { gcc_unreachable (); }
   "optimize && avropt_use_nonzero_bits
    && !reload_completed"
   ; "*nzb=1.<code>.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.<code>.zerox.not"
-  [(set (match_operand:QI 0 "register_operand"                    "=<nzb_constr_rdr>")
-        (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" "<nzb_use1_nnr>"))
+  [(set (match_operand:QI 0 "register_operand"                    "=<nzb_constr_rdrr>")
+        (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" "<nzb_use1_nnrn>"))
    (clobber (reg:CC REG_CC))]
   "optimize && avropt_use_nonzero_bits"
   {
       return "sbrs %1,%2\;ori %0,1";
     else if (<CODE> == XOR)
       return "sbrs %1,%2\;eor %0,%4";
+    else if (<CODE> == PLUS)
+      return "sbrs %1,%2\;inc %0";
     else
       gcc_unreachable ();
   }