OSDN Git Service

* config/h8300/h8300.c (print_operand) : Modify case 'V' and
[pf3gnuchains/gcc-fork.git] / gcc / config / h8300 / h8300.md
index e718a82..513ad4c 100644 (file)
@@ -1,6 +1,7 @@
 ;; GCC machine description for Renesas H8/300
 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-;; 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010
+;; Free Software Foundation, Inc.
 
 ;;   Contributed by Steve Chamberlain (sac@cygnus.com),
 ;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
@@ -9,7 +10,7 @@
 
 ;; GCC is free software; you can redistribute it and/or modify
 ;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
+;; the Free Software Foundation; either version 3, or (at your option)
 ;; any later version.
 
 ;; GCC is distributed in the hope that it will be useful,
@@ -18,9 +19,8 @@
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
 
 ;; We compute exact length on each instruction for most of the time.
 ;; In some case, most notably bit operations that may involve memory
@@ -92,7 +92,7 @@
                                (const_int -126))
                            (le (plus (minus (match_dup 0) (pc))
                                      (symbol_ref "DELAY_SLOT_LENGTH (insn)"))
-                               (const_int 126)))
+                               (const_int 125)))
                       (const_int 2)
                       (if_then_else (and (eq_attr "cpu" "h8300h")
                                          (and (ge (minus (pc) (match_dup 0))
 (define_attr "can_delay" "no,yes"
   (cond [(eq_attr "type" "branch,bitbranch,call")
           (const_string "no")
-        (ne (symbol_ref "get_attr_length (insn)") (const_int 2))
+        (geu (symbol_ref "get_attr_length (insn)") (const_int 2))
           (const_string "no")]
        (const_string "yes")))
 
 ;; Only allow jumps to have a delay slot if we think they might
-;; be short enough.  This is just an optimisation: we don't know
+;; be short enough.  This is just an optimization: we don't know
 ;; for certain whether they will be or not.
 (define_delay (and (eq_attr "delay_slot" "jump")
                   (eq (symbol_ref "get_attr_length (insn)") (const_int 2)))
               (ne (symbol_ref "TARGET_H8300H") (const_int 0)) (const_int 10)
               (ne (symbol_ref "TARGET_H8300S") (const_int 0)) (const_int 10)]
              (const_int 14)))])
+
+(include "predicates.md")
 \f
 ;; ----------------------------------------------------------------------
 ;; MOVE INSTRUCTIONS
        (match_operand:QI 1 "general_operand_src" "P4>X,rQi"))]
   "TARGET_H8300SX"
   "@
-    mov.b      %X1,%X0
+    mov.b      %X1:4,%X0
     mov.b      %X1,%X0"
   [(set_attr "length_table" "mov_imm4,movb")
    (set_attr "cc" "set_znv")])
   "TARGET_H8300SX"
   "@
    sub.w       %T0,%T0
-   mov.w       %T1,%T0
-   mov.w       %T1,%T0
+   mov.w       %T1:3,%T0
+   mov.w       %T1:4,%T0
    mov.w       %T1,%T0
    mov.w       %T1,%T0"
   [(set_attr "length_table" "*,*,mov_imm4,short_immediate,movw")
     case 5:
       return \"mov.w   %T1,%e0\;mov.w  %T1,%f0\";
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }"
   [(set (attr "length")
   "TARGET_H8300SX"
   "@
    sub.l       %S0,%S0
-   mov.l       %S1,%S0
+   mov.l       %S1:3,%S0
    mov.l       %S1,%S0
    mov.l       %S1,%S0
    clrmac
     case 5:
       return \"mov.w   %T1,%e0\;mov.w  %T1,%f0\";
     default:
-      abort ();
+      gcc_unreachable ();
     }
 }"
   [(set (attr "length")
 ;; ----------------------------------------------------------------------
 
 (define_insn ""
-  [(set (cc0) (zero_extract:HI (match_operand:QI 0 "bit_memory_operand" "r,U")
-                              (const_int 1)
-                              (match_operand 1 "const_int_operand" "n,n")))]
+  [(set (cc0) (compare
+              (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "r,U")
+                               (const_int 1)
+                               (match_operand 1 "const_int_operand" "n,n"))
+              (const_int 0)))]
   "TARGET_H8300"
   "btst        %Z1,%Y0"
   [(set_attr "length" "2,4")
    (set_attr "cc" "set_zn,set_zn")])
 
 (define_insn ""
-  [(set (cc0) (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
-                              (const_int 1)
-                              (match_operand 1 "const_int_operand" "n")))]
+  [(set (cc0) (compare
+              (zero_extract:HI (match_operand:HI 0 "register_operand" "r")
+                               (const_int 1)
+                               (match_operand 1 "const_int_operand" "n"))
+              (const_int 0)))]
   "TARGET_H8300"
   "btst        %Z1,%Y0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_zn")])
 
 (define_insn_and_split "*tst_extzv_1_n"
-  [(set (cc0)
-       (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
-                        (const_int 1)
-                        (match_operand 1 "const_int_operand" "n,n,n")))
+  [(set (cc0) (compare
+              (zero_extract:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>")
+                               (const_int 1)
+                               (match_operand 1 "const_int_operand" "n,n,n"))
+              (const_int 0)))
    (clobber (match_scratch:QI 2 "=X,X,&r"))]
   "(TARGET_H8300H || TARGET_H8300S)"
   "@
    && !OK_FOR_U (operands[0])"
   [(set (match_dup 2)
        (match_dup 0))
-   (parallel [(set (cc0) (zero_extract:SI (match_dup 2)
-                                         (const_int 1)
-                                         (match_dup 1)))
+   (parallel [(set (cc0) (compare (zero_extract:SI (match_dup 2)
+                                                  (const_int 1)
+                                                  (match_dup 1))
+                                 (const_int 0)))
              (clobber (scratch:QI))])]
   ""
   [(set_attr "length" "2,8,10")
    (set_attr "cc" "set_zn,set_zn,set_zn")])
 
 (define_insn ""
-  [(set (cc0) (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-                              (const_int 1)
-                              (match_operand 1 "const_int_operand" "n")))]
+  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+                                       (const_int 1)
+                                       (match_operand 1 "const_int_operand" "n"))
+                      (const_int 0)))]
   "(TARGET_H8300H || TARGET_H8300S)
    && INTVAL (operands[1]) <= 15"
   "btst        %Z1,%Y0"
    (set_attr "cc" "set_zn")])
 
 (define_insn_and_split "*tstsi_upper_bit"
-  [(set (cc0)
-       (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-                        (const_int 1)
-                        (match_operand 1 "const_int_operand" "n")))
+  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+                                       (const_int 1)
+                                       (match_operand 1 "const_int_operand" "n"))
+                      (const_int 0)))
    (clobber (match_scratch:SI 2 "=&r"))]
   "(TARGET_H8300H || TARGET_H8300S)
    && INTVAL (operands[1]) >= 16"
                        (const_int -65536))
                (lshiftrt:SI (match_dup 0)
                             (const_int 16))))
-   (set (cc0)
-       (zero_extract:SI (match_dup 2)
-                        (const_int 1)
-                        (match_dup 3)))]
+   (set (cc0) (compare (zero_extract:SI (match_dup 2)
+                                       (const_int 1)
+                                       (match_dup 3))
+                      (const_int 0)))]
   "operands[3] = GEN_INT (INTVAL (operands[1]) - 16);")
 
 (define_insn "*tstsi_variable_bit"
-  [(set (cc0)
-       (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
-                        (const_int 1)
-                        (and:SI (match_operand:SI 1 "register_operand" "r")
-                                (const_int 7))))]
+  [(set (cc0) (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
+                                       (const_int 1)
+                                       (and:SI (match_operand:SI 1 "register_operand" "r")
+                                               (const_int 7)))
+                      (const_int 0)))]
   "TARGET_H8300H || TARGET_H8300S"
   "btst        %w1,%w0"
   [(set_attr "length" "2")
 
 (define_insn_and_split "*tstsi_variable_bit_qi"
   [(set (cc0)
-       (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
-                        (const_int 1)
-                        (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
-                                (const_int 7))))
+       (compare
+        (zero_extract:SI (zero_extend:SI (match_operand:QI 0 "general_operand_src" "r,U,mn>"))
+                         (const_int 1)
+                         (and:SI (match_operand:SI 1 "register_operand" "r,r,r")
+                                 (const_int 7)))
+         (const_int 0)))
    (clobber (match_scratch:QI 2 "=X,X,&r"))]
   "(TARGET_H8300H || TARGET_H8300S)"
   "@
    && !OK_FOR_U (operands[0])"
   [(set (match_dup 2)
        (match_dup 0))
-   (parallel [(set (cc0) (zero_extract:SI (zero_extend:SI (match_dup 2))
-                                         (const_int 1)
-                                         (and:SI (match_dup 1)
-                                                 (const_int 7))))
+   (parallel [(set (cc0) (compare (zero_extract:SI (zero_extend:SI (match_dup 2))
+                                                  (const_int 1)
+                                                  (and:SI (match_dup 1)
+                                                          (const_int 7)))
+                                 (const_int 0)))
              (clobber (scratch:QI))])]
   ""
   [(set_attr "length" "2,8,10")
    (set_attr "cc" "set_zn,set_zn,set_zn")])
 
-(define_insn "tstqi"
-  [(set (cc0) (match_operand:QI 0 "register_operand" "r"))]
+(define_insn "*tstqi"
+  [(set (cc0) (compare (match_operand:QI 0 "register_operand" "r")
+                      (const_int 0)))]
   ""
   "mov.b       %X0,%X0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
-(define_insn "tsthi"
-  [(set (cc0) (match_operand:HI 0 "register_operand" "r"))]
+(define_insn "*tsthi"
+  [(set (cc0) (compare (match_operand:HI 0 "register_operand" "r")
+                      (const_int 0)))]
   ""
   "mov.w       %T0,%T0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
 (define_insn "*tsthi_upper"
-  [(set (cc0)
-       (and:HI (match_operand:HI 0 "register_operand" "r")
-               (const_int -256)))]
+  [(set (cc0) (compare (and:HI (match_operand:HI 0 "register_operand" "r")
+                              (const_int -256))
+                      (const_int 0)))]
   ""
   "mov.b       %t0,%t0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
-(define_insn "tstsi"
-  [(set (cc0) (match_operand:SI 0 "register_operand" "r"))]
+(define_insn "*tstsi"
+  [(set (cc0) (compare (match_operand:SI 0 "register_operand" "r")
+                      (const_int 0)))]
   "TARGET_H8300H || TARGET_H8300S"
   "mov.l       %S0,%S0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
 (define_insn "*tstsi_upper"
-  [(set (cc0)
-       (and:SI (match_operand:SI 0 "register_operand" "r")
-               (const_int -65536)))]
+  [(set (cc0) (compare (and:SI (match_operand:SI 0 "register_operand" "r")
+                              (const_int -65536))
+                      (const_int 0)))]
   ""
   "mov.w       %e0,%e0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
-(define_insn "cmpqi"
+(define_insn "*cmpqi"
   [(set (cc0)
        (compare (match_operand:QI 0 "h8300_dst_operand" "rQ")
                 (match_operand:QI 1 "h8300_src_operand" "rQi")))]
   [(set_attr "length_table" "addb")
    (set_attr "cc" "compare")])
 
-(define_expand "cmphi"
-  [(set (cc0)
-       (compare (match_operand:HI 0 "h8300_dst_operand" "")
-                (match_operand:HI 1 "h8300_src_operand" "")))]
-  ""
-  "
-{
-  /* Force operand1 into a register if we're compiling
-     for the H8/300.  */
-  if (GET_CODE (operands[1]) != REG && TARGET_H8300)
-    operands[1] = force_reg (HImode, operands[1]);
-}")
-
 (define_insn "*cmphi_h8300_znvc"
   [(set (cc0)
        (compare (match_operand:HI 0 "register_operand" "r")
        (compare (match_operand:HI 0 "h8300_dst_operand" "rU,rQ")
                 (match_operand:HI 1 "h8300_src_operand" "P3>X,rQi")))]
   "TARGET_H8300H || TARGET_H8300S"
-  "cmp.w       %T1,%T0"
+  "*
+{
+  switch (which_alternative)
+    {
+    case 0:
+      if (!TARGET_H8300SX)
+       return \"cmp.w  %T1,%T0\";
+      else
+       return \"cmp.w  %T1:3,%T0\";
+    case 1:
+      return \"cmp.w   %T1,%T0\";
+    default:
+      gcc_unreachable ();
+      }
+}"
   [(set_attr "length_table" "short_immediate,addw")
    (set_attr "cc" "compare,compare")])
 
        (compare (match_operand:SI 0 "h8300_dst_operand" "r,rQ")
                 (match_operand:SI 1 "h8300_src_operand" "P3>X,rQi")))]
   "TARGET_H8300H || TARGET_H8300S"
-  "cmp.l       %S1,%S0"
+  "*
+{
+  switch (which_alternative)
+    {
+    case 0:
+      if (!TARGET_H8300SX)
+       return \"cmp.l  %S1,%S0\";
+      else
+       return \"cmp.l  %S1:3,%S0\";
+    case 1:
+      return \"cmp.l   %S1,%S0\";
+    default:
+      gcc_unreachable ();
+    }
+}"
   [(set_attr "length" "2,*")
    (set_attr "length_table" "*,addl")
    (set_attr "cc" "compare,compare")])
   [(set (match_operand:HI 0 "stack_pointer_operand" "")
        (plus:HI (match_dup 0)
                 (match_operand 1 "const_int_gt_2_operand" "")))]
-  "TARGET_H8300 && flow2_completed"
+  "TARGET_H8300 && epilogue_completed"
   [(const_int 0)]
   "split_adds_subs (HImode, operands); DONE;")
 
                 (match_operand:HI 2 "h8300_src_operand" "P3>X,P3<X,J,rQi")))]
   "TARGET_H8300SX && h8300_operands_match_p (operands)"
   "@
-   add.w       %T2,%T0
-   sub.w       %G2,%T0
+   add.w       %T2:3,%T0
+   sub.w       %G2:3,%T0
    add.b       %t2,%t0
    add.w       %T2,%T0"
   [(set_attr "length_table" "short_immediate,short_immediate,*,addw")
 ;; ----------------------------------------------------------------------
 ;; AND INSTRUCTIONS
 ;; ----------------------------------------------------------------------
+(define_insn "bclrqi_msx"
+  [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
+       (and:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:QI 2 "single_zero_operand" "Y0")))]
+  "TARGET_H8300SX"
+  "bclr\\t%W2,%0"
+  [(set_attr "length" "8")])
+
+(define_split
+  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
+       (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:HI 2 "single_zero_operand" "Y0")))]
+  "TARGET_H8300SX"
+  [(set (match_dup 0)
+       (and:QI (match_dup 1)
+               (match_dup 2)))]
+{
+  operands[0] = adjust_address (operands[0], QImode, 1);
+  operands[1] = adjust_address (operands[1], QImode, 1);
+})
 
+(define_insn "bclrhi_msx"
+  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+       (and:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:HI 2 "single_zero_operand" "Y0")))]
+  "TARGET_H8300SX"
+  "bclr\\t%W2,%0"
+  [(set_attr "length" "8")])
 (define_insn "*andqi3_2"
   [(set (match_operand:QI 0 "bit_operand" "=rQ,r")
        (and:QI (match_operand:QI 1 "bit_operand" "%0,WU")
 ;; ----------------------------------------------------------------------
 ;; OR INSTRUCTIONS
 ;; ----------------------------------------------------------------------
+(define_insn "bsetqi_msx"
+  [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
+       (ior:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:QI 2 "single_one_operand" "Y2")))]
+  "TARGET_H8300SX" 
+  "bset\\t%V2,%0"
+  [(set_attr "length" "8")])
+
+(define_split
+  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
+       (ior:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:HI 2 "single_one_operand" "Y2")))]
+  "TARGET_H8300SX"
+  [(set (match_dup 0)
+       (ior:QI (match_dup 1)
+               (match_dup 2)))]
+{
+  operands[0] = adjust_address (operands[0], QImode, 1);
+  operands[1] = adjust_address (operands[1], QImode, 1);
+})
+
+(define_insn "bsethi_msx"
+  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+       (ior:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:HI 2 "single_one_operand" "Y2")))]
+  "TARGET_H8300SX"
+  "bset\\t%V2,%0"
+  [(set_attr "length" "8")])
 
 (define_insn "iorqi3_1"
   [(set (match_operand:QI 0 "bit_operand" "=rQ,U")
 ;; ----------------------------------------------------------------------
 ;; XOR INSTRUCTIONS
 ;; ----------------------------------------------------------------------
+(define_insn "bnotqi_msx"
+  [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
+       (xor:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:QI 2 "single_one_operand" "Y2")))]
+  "TARGET_H8300SX"
+  "bnot\\t%V2,%0"
+  [(set_attr "length" "8")])
+
+(define_split
+  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=U")
+       (xor:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:HI 2 "single_one_operand" "Y2")))]
+  "TARGET_H8300SX"
+  [(set (match_dup 0)
+       (xor:QI (match_dup 1)
+               (match_dup 2)))]
+{
+  operands[0] = adjust_address (operands[0], QImode, 1);
+  operands[1] = adjust_address (operands[1], QImode, 1);
+})
+
+(define_insn "bnothi_msx"
+  [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
+       (xor:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+               (match_operand:HI 2 "single_one_operand" "Y2")))]
+  "TARGET_H8300SX"
+  "bnot\\t%V2,%0"
+  [(set_attr "length" "8")])
 
 (define_insn "xorqi3_1"
   [(set (match_operand:QI 0 "bit_operand" "=r,U")
 
 ;; Conditional jump instructions
 
-(define_expand "ble"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (LE, operands[0]); DONE;")
-
-(define_expand "bleu"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (LEU, operands[0]); DONE;")
-
-(define_expand "bge"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (GE, operands[0]); DONE;")
-
-(define_expand "bgeu"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (GEU, operands[0]); DONE;")
-
-(define_expand "blt"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (LT, operands[0]); DONE;")
-
-(define_expand "bltu"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (LTU, operands[0]); DONE;")
-
-(define_expand "bgt"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (GT, operands[0]); DONE;")
-
-(define_expand "bgtu"
-  [(match_operand 0 "" "")]
+(define_expand "cbranchqi4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:QI 1 "h8300_dst_operand" "")
+          (match_operand:QI 2 "h8300_src_operand" "")]))
+   (use (match_operand 3 ""))]
   ""
-  "h8300_expand_branch (GTU, operands[0]); DONE;")
+  "h8300_expand_branch (operands); DONE;")
 
-(define_expand "beq"
-  [(match_operand 0 "" "")]
+(define_expand "cbranchhi4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:HI 1 "h8300_dst_operand" "")
+          (match_operand:HI 2 "h8300_src_operand" "")]))
+   (use (match_operand 3 ""))]
   ""
-  "h8300_expand_branch (EQ, operands[0]); DONE;")
+  "
+{
+  /* Force operand1 into a register if we're compiling
+     for the H8/300.  */
+  if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
+      && TARGET_H8300)
+    operands[2] = force_reg (HImode, operands[2]);
+  h8300_expand_branch (operands); DONE;
+}")
 
-(define_expand "bne"
-  [(match_operand 0 "" "")]
-  ""
-  "h8300_expand_branch (NE, operands[0]); DONE;")
+(define_expand "cbranchsi4"
+  [(use (match_operator 0 "ordered_comparison_operator"
+         [(match_operand:SI 1 "h8300_dst_operand" "")
+          (match_operand:SI 2 "h8300_src_operand" "")]))
+   (use (match_operand 3 ""))]
+  "TARGET_H8300H || TARGET_H8300S"
+  "h8300_expand_branch (operands); DONE;")
 
 (define_insn "branch_true"
   [(set (pc)
 
          vec = XVEC (final_sequence, 0);
          final_sequence = 0;
-         final_scan_insn (RTVEC_ELT (vec, 1), asm_out_file, optimize, 0, 1, & seen);
-         final_scan_insn (RTVEC_ELT (vec, 0), asm_out_file, optimize, 0, 1, & seen);
+         final_scan_insn (RTVEC_ELT (vec, 1), asm_out_file, optimize, 1, & seen);
+         final_scan_insn (RTVEC_ELT (vec, 0), asm_out_file, optimize, 1, & seen);
          INSN_DELETED_P (RTVEC_ELT (vec, 1)) = 1;
          return \"\";
        }
     return \"mov.l\\ter0,@-er7\;stc\\tccr,r0l\;mov.b\\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\\t#128,ccr\";
   else if (TARGET_H8300S)
     return \"stc\texr,@-er7\;mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(6,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr\";
-    abort ();
+  gcc_unreachable ();
 }"
   [(set_attr "length" "20")])
 \f
   [(set_attr "length" "8,12")])
 
 ;; The following pattern is needed because without the pattern, the
-;; combiner would split (sign_extend:SI (reg:QI)) into into two 24-bit
+;; combiner would split (sign_extend:SI (reg:QI)) into two 24-bit
 ;; shifts, one ashift and one ashiftrt.
 
 (define_insn_and_split "*extendqisi2_h8300hs"
 ;; ----------------------------------------------------------------------
 ;;
 ;; We make some attempt to provide real efficient shifting.  One example is
-;; doing an 8 bit shift of a 16 bit value by moving a byte reg into the other
+;; doing an 8-bit shift of a 16-bit value by moving a byte reg into the other
 ;; reg and moving 0 into the former reg.
 ;;
 ;; We also try to achieve this in a uniform way.  IE: We don't try to achieve
 ;; give the optimizer more cracks at the code.  However, we wish to do things
 ;; like optimizing shifting the sign bit to bit 0 by rotating the other way.
 ;; There is rtl to handle this (rotate + and), but the H8/300 doesn't handle
-;; 16 bit rotates.  Also, if we emit complicated rtl, combine may not be able
+;; 16-bit rotates.  Also, if we emit complicated rtl, combine may not be able
 ;; to detect cases it can optimize.
 ;;
 ;; For these and other fuzzy reasons, I've decided to go the less pretty but
                        [(match_dup 0)
                         (match_operand:QI 1 "register_operand" "")]))
    (clobber (match_operand:QI 3 "register_operand" ""))]
-  "flow2_completed
+  "epilogue_completed
    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
-  [(set (cc0)
-       (match_dup 1))
+  [(set (cc0) (compare (match_dup 1)
+                      (const_int 0)))
    (set (pc)
         (if_then_else (le (cc0) (const_int 0))
                      (label_ref (match_dup 5))
       (clobber (scratch:QI))])
    (set (match_dup 1)
        (plus:QI (match_dup 1) (const_int -1)))
-   (set (cc0)
-       (match_dup 1))
+   (set (cc0) (compare (match_dup 1)
+                      (const_int 0)))
    (set (pc)
         (if_then_else (ne (cc0) (const_int 0))
                      (label_ref (match_dup 4))
                        [(match_dup 0)
                         (match_operand:QI 1 "register_operand" "")]))
    (clobber (match_operand:QI 3 "register_operand" ""))]
-  "flow2_completed
+  "epilogue_completed
    && !find_regno_note (insn, REG_DEAD, REGNO (operands[1]))"
   [(set (match_dup 3)
        (match_dup 1))
-   (set (cc0)
-       (match_dup 3))
+   (set (cc0) (compare (match_dup 3)
+                      (const_int 0)))
    (set (pc)
         (if_then_else (le (cc0) (const_int 0))
                      (label_ref (match_dup 5))
       (clobber (scratch:QI))])
    (set (match_dup 3)
        (plus:QI (match_dup 3) (const_int -1)))
-   (set (cc0)
-       (match_dup 3))
+   (set (cc0) (compare (match_dup 3)
+                      (const_int 0)))
    (set (pc)
         (if_then_else (ne (cc0) (const_int 0))
                      (label_ref (match_dup 4))
                                 (match_operand:HI 3 "const_int_operand" "n"))
                         (const_int 1)
                         (match_operand:HI 2 "const_int_operand" "n")))]
-  "TARGET_H8300
+  "(TARGET_H8300 || TARGET_H8300SX)
    && (1 << INTVAL (operands[2])) == INTVAL (operands[3])"
   "sub.w       %0,%0\;bild     %Z2,%Y1\;bst    #0,%X0"
   [(set_attr "length" "8")])
            }
           if (! bit_memory_operand (operands[0], GET_MODE (operands[0])))
            {
-             if (no_new_pseudos)
+             if (!can_create_pseudo_p ())
                FAIL;
              operands[0] =
                replace_equiv_address (operands[0],
            FAIL;
          if (! register_operand (operands[3], QImode))
            {
-             if (no_new_pseudos)
+             if (!can_create_pseudo_p ())
                FAIL;
              operands[3] = force_reg (QImode, operands[3]);
            }
   if (GET_CODE (operands[0]) == MEM
       || GET_CODE (operands[3]) == MEM)
     FAIL;
+
+  if (GET_CODE (operands[3]) != REG)
+    operands[3] = force_reg (HImode, operands[3]);
 }")
 
 (define_insn ""
                  == MODE_INT))
            operands[0] = SUBREG_REG (operands[0]);
 
-         if (no_new_pseudos)
+         if (!can_create_pseudo_p ())
            temp = gen_lowpart (QImode, operands[0]);
          else
            temp = gen_reg_rtx (QImode);
            FAIL;
           if (! bit_memory_operand (operands[1], QImode))
            {
-             if (no_new_pseudos)
+             if (!can_create_pseudo_p ())
                FAIL;
              operands[1] =
                replace_equiv_address (operands[1],
   [(set_attr "cc" "none_0hit")
    (set_attr "length_table" "bitfield")])
 
-(define_expand "seq"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (eq:HI (cc0) (const_int 0)))]
+(define_expand "cstoreqi4"
+  [(use (match_operator 1 "eqne_operator"
+         [(match_operand:QI 2 "h8300_dst_operand" "")
+          (match_operand:QI 3 "h8300_src_operand" "")]))
+   (clobber (match_operand:HI 0 "register_operand"))]
   "TARGET_H8300SX"
-  "")
+  "h8300_expand_store (operands); DONE;")
 
-(define_expand "sne"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (ne:HI (cc0) (const_int 0)))]
+(define_expand "cstorehi4"
+  [(use (match_operator 1 "eqne_operator"
+         [(match_operand:HI 2 "h8300_dst_operand" "")
+          (match_operand:HI 3 "h8300_src_operand" "")]))
+   (clobber (match_operand:HI 0 "register_operand"))]
   "TARGET_H8300SX"
-  "")
+  "h8300_expand_store (operands); DONE;")
+
+(define_expand "cstoresi4"
+  [(use (match_operator 1 "eqne_operator"
+         [(match_operand:SI 2 "h8300_dst_operand" "")
+          (match_operand:SI 3 "h8300_src_operand" "")]))
+   (clobber (match_operand:HI 0 "register_operand"))]
+  "TARGET_H8300SX"
+  "h8300_expand_store (operands); DONE;")
 
 (define_insn "*bstzhireg"
   [(set (match_operand:HI 0 "register_operand" "=r")
   [(set (cc0) (match_dup 5))
    (set (zero_extract:QI (match_dup 0) (const_int 1) (match_dup 1))
        (match_op_dup:QI 2 [(cc0) (const_int 0)]))]
-  "
-{
-  if (operands[4] == const0_rtx && GET_CODE (operands[3]) == REG)
-    operands[5] = operands[3];
-  else
-    operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
-}"
+  "operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*bstz"
        (if_then_else:QI
         (match_op_dup 1 [(cc0) (const_int 0)])
         (ior:QI (match_dup 4) (match_dup 5)) (match_dup 4)))]
-  "
-{
-  if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
-    operands[6] = operands[2];
-  else
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*condbset"
        (if_then_else:QI
         (match_op_dup 1 [(cc0) (const_int 0)])
         (and:QI (match_dup 4) (match_dup 5)) (match_dup 4)))]
-  "
-{
-  if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
-    operands[6] = operands[2];
-  else
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*condbclr"
                 (ashift:QI (const_int 1)
                            (match_operand:QI 5 "register_operand" "r,r")))
         (match_dup 4)))]
-  "
-{
-  if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
-    operands[6] = operands[2];
-  else
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*condbsetreg"
                 (ashift:QI (const_int 1)
                            (match_operand:QI 5 "register_operand" "r,r")))
         (match_dup 4)))]
-  "
-{
-  if (operands[3] == const0_rtx && GET_CODE (operands[2]) == REG)
-    operands[6] = operands[2];
-  else
-    operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
-}"
+  "operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);"
   [(set_attr "cc" "set_znv,compare")])
    
 (define_insn "*condbclrreg"
   "(TARGET_H8300H || TARGET_H8300S)"
   "#"
   "&& reload_completed"
-  [(set (cc0)
-       (zero_extract:SI (match_dup 1)
-                        (const_int 1)
-                        (const_int 0)))
+  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+                                       (const_int 1)
+                                       (const_int 0))
+                      (const_int 0)))
    (set (pc)
         (if_then_else (eq (cc0)
                          (const_int 0))
   "(TARGET_H8300H || TARGET_H8300S)"
   "#"
   "&& reload_completed"
-  [(set (cc0)
-       (zero_extract:SI (match_dup 1)
-                        (const_int 1)
-                        (const_int 0)))
+  [(set (cc0) (compare (zero_extract:SI (match_dup 1)
+                                       (const_int 1)
+                                       (const_int 0))
+                      (const_int 0)))
    (set (pc)
         (if_then_else (ne (cc0)
                          (const_int 0))
                (match_dup 0)))
    (clobber (match_operand:SI 2 "register_operand" ""))]
   "(TARGET_H8300H || TARGET_H8300S)
-   && flow2_completed
+   && epilogue_completed
    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
    && REGNO (operands[0]) != REGNO (operands[1])"
   [(parallel [(set (match_dup 3)
                (match_dup 0)))
    (clobber (match_operand:SI 2 "register_operand" ""))]
   "(TARGET_H8300H || TARGET_H8300S)
-   && flow2_completed
+   && epilogue_completed
    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
         && REGNO (operands[0]) != REGNO (operands[1]))"
   [(set (match_dup 2)
                 (match_dup 0)))
    (clobber (match_operand:SI 2 "register_operand" ""))]
   "(TARGET_H8300H || TARGET_H8300S)
-   && flow2_completed
+   && epilogue_completed
    && find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
    && REGNO (operands[0]) != REGNO (operands[1])"
   [(parallel [(set (match_dup 3)
                 (match_dup 0)))
    (clobber (match_operand:SI 2 "register_operand" ""))]
   "(TARGET_H8300H || TARGET_H8300S)
-   && flow2_completed
+   && epilogue_completed
    && !(find_regno_note (insn, REG_DEAD, REGNO (operands[1]))
         && REGNO (operands[0]) != REGNO (operands[1]))"
   [(set (match_dup 2)
   ""
   "#"
   ""
-  [(set (cc0)
-       (match_dup 0))
+  [(set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (ge (cc0)
                          (const_int 0))
   ""
   "#"
   ""
-  [(set (cc0)
-       (match_dup 0))
+  [(set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (lt (cc0)
                          (const_int 0))
   [(set (match_operand:HI 0 "register_operand" "")
        (plus:HI (match_dup 0)
                 (match_operand 1 "incdec_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
        (unspec:HI [(match_dup 0)
                    (match_dup 1)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_operand:SI 0 "register_operand" "")
        (plus:SI (match_dup 0)
                 (match_operand 1 "incdec_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
        (unspec:SI [(match_dup 0)
                    (match_dup 1)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
 
 (define_peephole2
   [(parallel [(set (cc0)
-                  (zero_extract:SI (match_operand:QI 0 "register_operand" "")
-                                   (const_int 1)
-                                   (const_int 7)))
+                  (compare (zero_extract:SI (match_operand:QI 0 "register_operand" "")
+                                            (const_int 1)
+                                            (const_int 7))
+                           (const_int 0)))
              (clobber (scratch:QI))])
    (set (pc)
        (if_then_else (match_operator 1 "eqne_operator"
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)"
-  [(set (cc0)
-        (match_dup 0))
+  [(set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   "operands[3] = gen_lowpart (HImode, operands[0]);
    operands[4] = gen_lowpart (HImode, operands[1]);")
 
+;; Convert a memory comparison to a move if there is a scratch register.
+
+(define_peephole2
+  [(match_scratch:QI 1 "r")
+   (set (cc0)
+       (compare (match_operand:QI 0 "memory_operand" "")
+                (const_int 0)))]
+  ""
+  [(set (match_dup 1)
+       (match_dup 0))
+   (set (cc0) (compare (match_dup 1)
+                      (const_int 0)))]
+  "")
+
+(define_peephole2
+  [(match_scratch:HI 1 "r")
+   (set (cc0)
+       (compare (match_operand:HI 0 "memory_operand" "")
+                (const_int 0)))]
+  "(TARGET_H8300H || TARGET_H8300S)"
+  [(set (match_dup 1)
+       (match_dup 0))
+   (set (cc0) (compare (match_dup 1)
+                      (const_int 0)))]
+  "")
+
+(define_peephole2
+  [(match_scratch:SI 1 "r")
+   (set (cc0)
+       (compare (match_operand:SI 0 "memory_operand" "")
+                (const_int 0)))]
+  "(TARGET_H8300H || TARGET_H8300S)"
+  [(set (match_dup 1)
+       (match_dup 0))
+   (set (cc0) (compare (match_dup 1)
+                      (const_int 0)))]
+  "")
+
+
 ;; (compare (reg:HI) (const_int)) takes 4 bytes, so we try to achieve
 ;; the equivalent with shorter sequences.  Here is the summary.  Cases
 ;; are grouped for each define_peephole2.
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)
+   && INTVAL (operands[1]) != 0
    && peep2_reg_dead_p (1, operands[0])"
   [(set (match_dup 0)
        (unspec:HI [(match_dup 0)
                    (match_dup 4)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
                   (ashiftrt:HI (match_dup 0)
                                (match_dup 4)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 2)
                      (label_ref (match_dup 3))
                   (ashiftrt:HI (match_dup 0)
                                (match_dup 4)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 5)
                      (label_ref (match_dup 3))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "TARGET_H8300H || TARGET_H8300S"
-  [(set (cc0)
-       (and:HI (match_dup 0)
-               (const_int -256)))
+  [(set (cc0) (compare (and:HI (match_dup 0)
+                              (const_int -256))
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 1)
                      (label_ref (match_dup 2))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "TARGET_H8300H || TARGET_H8300S"
-  [(set (cc0)
-       (and:HI (match_dup 0)
-               (const_int -256)))
+  [(set (cc0) (compare (and:HI (match_dup 0)
+                              (const_int -256))
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 3)
                      (label_ref (match_dup 2))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)
+   && INTVAL (operands[1]) != 0
    && peep2_reg_dead_p (1, operands[0])"
   [(set (match_dup 0)
        (unspec:SI [(match_dup 0)
                    (match_dup 4)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_dup 0)
        (plus:SI (match_dup 0)
                 (match_dup 4)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
    && ((INTVAL (operands[1]) & 0x00ff) == INTVAL (operands[1])
        || (INTVAL (operands[1]) & 0xff00) == INTVAL (operands[1])
        || INTVAL (operands[1]) == 0x0000ffff)
+   && INTVAL (operands[1]) != 0
    && INTVAL (operands[1]) != 1
    && INTVAL (operands[1]) != 2"
   [(set (match_dup 0)
        (xor:SI (match_dup 0)
                (match_dup 1)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
                (match_dup 4)))
    (set (match_dup 0)
        (not:SI (match_dup 0)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
        (unspec:SI [(match_dup 0)
                    (const_int -1)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
                   (ashiftrt:SI (match_dup 4)
                                (match_dup 5)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 2)
                      (label_ref (match_dup 3))
                   (ashiftrt:SI (match_dup 4)
                                (match_dup 5)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 6)
                      (label_ref (match_dup 3))
                   (ashiftrt:SI (match_dup 0)
                                (match_dup 4)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 2)
                      (label_ref (match_dup 3))
                   (ashiftrt:SI (match_dup 0)
                                (match_dup 4)))
              (clobber (scratch:QI))])
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 5)
                      (label_ref (match_dup 3))
   [(set (match_dup 0)
        (and:SI (match_dup 0)
                (match_dup 4)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 2)
                      (label_ref (match_dup 3))
   [(set (match_dup 0)
        (and:SI (match_dup 0)
                (match_dup 4)))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 5)
                      (label_ref (match_dup 3))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "TARGET_H8300H || TARGET_H8300S"
-  [(set (cc0)
-       (and:SI (match_dup 0)
-               (const_int -65536)))
+  [(set (cc0) (compare (and:SI (match_dup 0)
+                              (const_int -65536))
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 1)
                      (label_ref (match_dup 2))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "TARGET_H8300H || TARGET_H8300S"
-  [(set (cc0)
-       (and:SI (match_dup 0)
-               (const_int -65536)))
+  [(set (cc0) (compare (and:SI (match_dup 0)
+                              (const_int -65536))
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_dup 3)
                      (label_ref (match_dup 2))
                      (label_ref (match_operand 2 "" ""))
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)
+   && INTVAL (operands[1]) != 0
    && !peep2_reg_dead_p (1, operands[0])
    && !same_cmp_following_p (insn)"
   [(set (match_dup 4)
        (unspec:SI [(match_dup 4)
                    (match_dup 5)]
                   UNSPEC_INCDEC))
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_operand:HI 0 "register_operand" "")
        (and:HI (match_dup 0)
                (match_operand:HI 1 "const_int_qi_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
   [(set (match_dup 4)
        (and:QI (match_dup 4)
                (match_dup 5)))
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_operand:SI 0 "register_operand" "")
        (and:SI (match_dup 0)
                (match_operand:SI 1 "const_int_qi_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
   [(set (match_dup 4)
        (and:QI (match_dup 4)
                (match_dup 5)))
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
   [(set (match_operand:SI 0 "register_operand" "")
        (and:SI (match_dup 0)
                (match_operand:SI 1 "const_int_hi_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 3 "eqne_operator"
                        [(cc0) (const_int 0)])
   [(set (match_dup 4)
        (and:HI (match_dup 4)
                (match_dup 5)))
-   (set (cc0)
-       (match_dup 4))
+   (set (cc0) (compare (match_dup 4)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 3 [(cc0) (const_int 0)])
                      (label_ref (match_dup 2))
    (set (match_dup 0)
        (xor:SI (match_dup 0)
                (match_operand:SI 2 "const_int_qi_operand" "")))
-   (set (cc0)
-       (match_dup 0))
+   (set (cc0) (compare (match_dup 0)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_operator 4 "eqne_operator"
                        [(cc0) (const_int 0)])
    (set (match_dup 5)
        (xor:QI (match_dup 5)
                (match_dup 7)))
-   (set (cc0)
-       (match_dup 5))
+   (set (cc0) (compare (match_dup 5)
+                      (const_int 0)))
    (set (pc)
        (if_then_else (match_op_dup 4 [(cc0) (const_int 0)])
                      (label_ref (match_dup 3))
            (match_operand 3 "h8300_src_operand" "")]))
    (set (match_operand 4 "memory_operand" "")
        (match_dup 0))]
-  "0 /* Disabale because it break compiling fp-bit.c.  */
+  "0 /* Disable because it breaks compiling fp-bit.c.  */
    && TARGET_H8300SX
    && peep2_reg_dead_p (3, operands[0])
    && !reg_overlap_mentioned_p (operands[0], operands[3])
        (match_operator 3 "h8sx_binary_memory_operator"
           [(match_operand 4 "h8300_dst_operand" "")
            (match_dup 0)]))]
-  "0 /* Disabale because it break compiling fp-bit.c.  */
+  "0 /* Disable because it breaks compiling fp-bit.c.  */
    && TARGET_H8300SX
    && peep2_reg_dead_p (2, operands[0])
    && !reg_overlap_mentioned_p (operands[0], operands[4])"
                 (match_operand 2 "h8300_src_operand" "")))]
   "TARGET_H8300SX
    && peep2_reg_dead_p (2, operands[0])
-   && !reg_overlap_mentioned_p (operands[0], operands[2])"
+   && !reg_overlap_mentioned_p (operands[0], operands[2])
+   && operands[2] != const0_rtx"
   [(set (cc0)
        (compare (match_dup 1)
                 (match_dup 2)))])