]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/h8300/h8300.md
Update copyright years.
[thirdparty/gcc.git] / gcc / config / h8300 / h8300.md
index 01a31c2de98a567e96a409328c1473671bf1f901..4c219a70eea444c293f932b36ae843bffea78088 100644 (file)
@@ -1,7 +1,5 @@
 ;; GCC machine description for Renesas H8/300
-;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011, 2012
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1992-2020 Free Software Foundation, Inc.
 
 ;;   Contributed by Steve Chamberlain (sac@cygnus.com),
 ;;   Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
@@ -79,7 +77,7 @@
 (define_attr "type" "branch,arith,bitbranch,call"
   (const_string "arith"))
 
-(define_attr "length_table" "none,addb,addw,addl,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"
+(define_attr "length_table" "none,add,logicb,movb,movw,movl,mova_zero,mova,unary,mov_imm4,short_immediate,bitfield,bitbranch"
   (const_string "none"))
 
 ;; The size of instructions in bytes.
 
 (define_mode_iterator P [(HI "Pmode == HImode") (SI "Pmode == SImode")])
 
+(define_mode_iterator QHI [QI HI])
+
+(define_mode_iterator HSI [HI SI])
+
+(define_mode_iterator QHSI [QI HI SI])
+
+(define_mode_iterator QHSIF [QI HI SI SF])
+
+(define_code_iterator shifts [ashift ashiftrt lshiftrt])
+
+(define_code_iterator ors [ior xor])
 \f
 ;; ----------------------------------------------------------------------
 ;; MOVE INSTRUCTIONS
 
 ;; movqi
 
-(define_insn "*movqi_h8300"
-  [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
-       (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
-  "TARGET_H8300
-   && h8300_move_ok (operands[0], operands[1])"
-  "@
-   sub.b       %X0,%X0
-   mov.b       %R1,%X0
-   mov.b       %X1,%R0
-   mov.b       %R1,%X0
-   mov.b       %R1,%X0
-   mov.b       %X1,%R0"
-  [(set_attr "length" "2,2,2,2,4,4")
-   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
-
-(define_insn "*movqi_h8300hs"
+(define_insn "*movqi_h8nosx"
   [(set (match_operand:QI 0 "general_operand_dst" "=r,r ,<,r,r,m")
        (match_operand:QI 1 "general_operand_src" " I,r>,r,n,m,r"))]
-  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
+  "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
     && h8300_move_ok (operands[0], operands[1])"
   "@
    sub.b       %X0,%X0
    mov.b       %X1,%R0"
   [(set (attr "length")
        (symbol_ref "compute_mov_length (operands)"))
-   (set_attr "cc" "set_zn,set_znv,set_znv,clobber,set_znv,set_znv")])
+   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
 
 (define_insn "*movqi_h8sx"
   [(set (match_operand:QI 0 "general_operand_dst" "=Z,rQ")
   [(set_attr "length_table" "mov_imm4,movb")
    (set_attr "cc" "set_znv")])
 
-(define_expand "movqi"
-  [(set (match_operand:QI 0 "general_operand_dst" "")
-       (match_operand:QI 1 "general_operand_src" ""))]
+(define_expand "mov<mode>"
+  [(set (match_operand:QHSIF 0 "general_operand_dst" "")
+       (match_operand:QHSIF 1 "general_operand_src" ""))]
   ""
   {
-    /* One of the ops has to be in a register.  */
-    if (!TARGET_H8300SX && !h8300_move_ok (operands[0], operands[1]))
-      operands[1] = copy_to_mode_reg (QImode, operands[1]);
+    enum machine_mode mode = <MODE>mode;
+    if (TARGET_H8300 && (mode == SImode || mode == SFmode))
+      {
+       /* The original H8/300 needs to split up 32 bit moves.  */
+       if (h8300_expand_movsi (operands))
+         DONE;
+      }
+    else if (!TARGET_H8300SX)
+      {
+       /* Other H8 chips, except the H8/SX family can only handle a
+          single memory operand, which is checked by h8300_move_ok.
+
+          We could perhaps have h8300_move_ok handle the H8/SX better
+          and just remove the !TARGET_H8300SX conditional.  */
+       if (!h8300_move_ok (operands[0], operands[1]))
+         operands[1] = copy_to_mode_reg (mode, operand1);
+      }
   })
 
 (define_insn "movstrictqi"
 
 ;; movhi
 
-(define_insn "*movhi_h8300"
-  [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
-       (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
-  "TARGET_H8300
-   && h8300_move_ok (operands[0], operands[1])"
-  "@
-   sub.w       %T0,%T0
-   mov.w       %T1,%T0
-   mov.w       %T1,%T0
-   mov.w       %T1,%T0
-   mov.w       %T1,%T0
-   mov.w       %T1,%T0"
-  [(set (attr "length")
-       (symbol_ref "compute_mov_length (operands)"))
-   (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv,set_znv")])
-
-(define_insn "*movhi_h8300hs"
+(define_insn "*movhi_h8nosx"
   [(set (match_operand:HI 0 "general_operand_dst" "=r,r,<,r,r,m")
        (match_operand:HI 1 "general_operand_src" "I,r>,r,i,m,r"))]
-  "(TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
+  "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S) && !TARGET_H8300SX
     && h8300_move_ok (operands[0], operands[1])"
   "@
    sub.w       %T0,%T0
    (set_attr "length" "2,2,*,*,*")
    (set_attr "cc" "set_zn,set_znv,set_znv,set_znv,set_znv")])
 
-(define_expand "movhi"
-  [(set (match_operand:HI 0 "general_operand_dst" "")
-       (match_operand:HI 1 "general_operand_src" ""))]
-  ""
-  {
-    /* One of the ops has to be in a register.  */
-    if (!h8300_move_ok (operands[0], operands[1]))
-      operands[1] = copy_to_mode_reg (HImode, operand1);
-  })
-
 (define_insn "movstricthi"
   [(set (strict_low_part (match_operand:HI 0 "general_operand_dst" "+r,r,r"))
                         (match_operand:HI 1 "general_operand_src" "I,P3>X,rmi"))]
 
 ;; movsi
 
-(define_expand "movsi"
-  [(set (match_operand:SI 0 "general_operand_dst" "")
-       (match_operand:SI 1 "general_operand_src" ""))]
-  ""
-  {
-    if (TARGET_H8300)
-      {
-       if (h8300_expand_movsi (operands))
-         DONE;
-      }
-    else if (!TARGET_H8300SX)
-      {
-       /* One of the ops has to be in a register.  */
-       if (!h8300_move_ok (operands[0], operands[1]))
-         operands[1] = copy_to_mode_reg (SImode, operand1);
-      }
-  })
-
 (define_insn "*movsi_h8300"
   [(set (match_operand:SI 0 "general_operand_dst" "=r,r,r,o,<,r")
        (match_operand:SI 1 "general_operand_src" "I,r,io,r,r,>"))]
    (set_attr "length_table" "*,movl")
    (set_attr "cc" "set_zn,set_znv")])
 
-;; Implement block moves using movmd.  Defining movmemsi allows the full
+;; Implement block copies using movmd.  Defining cpymemsi allows the full
 ;; range of constant lengths (up to 0x40000 bytes when using movmd.l).
 ;; See h8sx_emit_movmd for details.
 
-(define_expand "movmemsi"
+(define_expand "cpymemsi"
   [(use (match_operand:BLK 0 "memory_operand" ""))
    (use (match_operand:BLK 1 "memory_operand" ""))
    (use (match_operand:SI 2 "" ""))
    (use (match_operand:SI 3 "const_int_operand" ""))]
-  "TARGET_H8300SX"
+  "TARGET_H8300SX && 0"
   {
     if (h8sx_emit_movmd (operands[0], operands[1], operands[2], INTVAL (operands[3])))
       DONE;
      (clobber (match_dup 5))
      (set (match_dup 2)
          (const_int 0))])]
-  "TARGET_H8300SX"
+  "TARGET_H8300SX && 0"
   {
     operands[4] = copy_rtx (XEXP (operands[0], 0));
     operands[5] = copy_rtx (XEXP (operands[1], 0));
 ;; This is a difficult instruction to reload since operand 0 must be the
 ;; frame pointer.  See h8300_reg_class_from_letter for an explanation.
 
-(define_insn "movmd_internal_normal"
-  [(set (mem:BLK (match_operand:HI 3 "register_operand" "0,r"))
-       (mem:BLK (match_operand:HI 4 "register_operand" "1,1")))
-   (unspec [(match_operand:HI 5 "register_operand" "2,2")
-           (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD)
-   (clobber (match_operand:HI 0 "register_operand" "=d,??D"))
-   (clobber (match_operand:HI 1 "register_operand" "=f,f"))
-   (set (match_operand:HI 2 "register_operand" "=c,c")
-       (const_int 0))]
-  "TARGET_H8300SX && TARGET_NORMAL_MODE"
-  "@
-    movmd%m6
-    #"
-  [(set_attr "length" "2,14")
-   (set_attr "can_delay" "no")
-   (set_attr "cc" "none,clobber")])
-
-(define_insn "movmd_internal"
-  [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r"))
-       (mem:BLK (match_operand:SI 4 "register_operand" "1,1")))
+(define_insn "movmd_internal_<mode>"
+  [(set (mem:BLK (match_operand:P 3 "register_operand" "0,r"))
+       (mem:BLK (match_operand:P 4 "register_operand" "1,1")))
    (unspec [(match_operand:HI 5 "register_operand" "2,2")
            (match_operand:HI 6 "const_int_operand" "n,n")] UNSPEC_MOVMD)
-   (clobber (match_operand:SI 0 "register_operand" "=d,??D"))
-   (clobber (match_operand:SI 1 "register_operand" "=f,f"))
+   (clobber (match_operand:P 0 "register_operand" "=d,??D"))
+   (clobber (match_operand:P 1 "register_operand" "=f,f"))
    (set (match_operand:HI 2 "register_operand" "=c,c")
        (const_int 0))]
-  "TARGET_H8300SX && !TARGET_NORMAL_MODE"
+  "TARGET_H8300SX && 0"
   "@
     movmd%m6
     #"
        (match_operand:BLK 1 "memory_operand" ""))
    (unspec [(match_operand:HI 2 "register_operand" "")
            (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
-   (clobber (match_operand:HI 4 "register_operand" ""))
-   (clobber (match_operand:HI 5 "register_operand" ""))
-   (set (match_dup 2)
-       (const_int 0))]
-  "TARGET_H8300SX && TARGET_NORMAL_MODE && reload_completed
-   && REGNO (operands[4]) != DESTINATION_REG"
-  [(const_int 0)]
-  {
-    rtx dest;
-
-    h8300_swap_into_er6 (XEXP (operands[0], 0));
-    dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
-    emit_insn (gen_movmd (dest, operands[1], operands[2], operands[3]));
-    h8300_swap_out_of_er6 (operands[4]);
-    DONE;
-  })
-
-(define_split
-  [(set (match_operand:BLK 0 "memory_operand" "")
-       (match_operand:BLK 1 "memory_operand" ""))
-   (unspec [(match_operand:HI 2 "register_operand" "")
-           (match_operand:HI 3 "const_int_operand" "")] UNSPEC_MOVMD)
-   (clobber (match_operand:SI 4 "register_operand" ""))
-   (clobber (match_operand:SI 5 "register_operand" ""))
+   (clobber (match_operand:P 4 "register_operand" ""))
+   (clobber (match_operand:P 5 "register_operand" ""))
    (set (match_dup 2)
        (const_int 0))]
-  "TARGET_H8300SX && !TARGET_NORMAL_MODE && reload_completed
+  "TARGET_H8300SX && reload_completed
+   && 0
    && REGNO (operands[4]) != DESTINATION_REG"
   [(const_int 0)]
   {
   [(use (match_operand 0 "register_operand" ""))
    (use (match_operand:BLK 1 "memory_operand" ""))
    (use (match_operand:BLK 2 "memory_operand" ""))]
-  "TARGET_H8300SX"
+  "TARGET_H8300SX && 0"
   {
     operands[1] = replace_equiv_address
       (operands[1], copy_to_mode_reg (Pmode, XEXP (operands[1], 0)));
      (clobber (match_dup 3))
      (clobber (match_dup 4))
      (clobber (match_operand 2 "register_operand" ""))])]
-  "TARGET_H8300SX"
+  "TARGET_H8300SX && 0"
   {
     operands[3] = copy_rtx (XEXP (operands[0], 0));
     operands[4] = copy_rtx (XEXP (operands[1], 0));
 
 ;; See comments above memcpy_internal().
 
-(define_insn "stpcpy_internal_normal"
-  [(set (mem:BLK (match_operand:HI 3 "register_operand" "0,r"))
-       (unspec:BLK [(mem:BLK (match_operand:HI 4 "register_operand" "1,1"))]
+(define_insn "stpcpy_internal_<mode>"
+  [(set (mem:BLK (match_operand:P 3 "register_operand" "0,r"))
+       (unspec:BLK [(mem:BLK (match_operand:P 4 "register_operand" "1,1"))]
        UNSPEC_STPCPY))
-   (clobber (match_operand:HI 0 "register_operand" "=d,??D"))
-   (clobber (match_operand:HI 1 "register_operand" "=f,f"))
-   (clobber (match_operand:HI 2 "register_operand" "=c,c"))]
-  "TARGET_H8300SX && TARGET_NORMAL_MODE"
-  "@
-    \n1:\tmovsd\t2f\;bra\t1b\n2:
-    #"
-  [(set_attr "length" "6,18")
-   (set_attr "cc" "none,clobber")])
-
-(define_insn "stpcpy_internal"
-  [(set (mem:BLK (match_operand:SI 3 "register_operand" "0,r"))
-       (unspec:BLK [(mem:BLK (match_operand:SI 4 "register_operand" "1,1"))]
-       UNSPEC_STPCPY))
-   (clobber (match_operand:SI 0 "register_operand" "=d,??D"))
-   (clobber (match_operand:SI 1 "register_operand" "=f,f"))
-   (clobber (match_operand:SI 2 "register_operand" "=c,c"))]
-  "TARGET_H8300SX && !TARGET_NORMAL_MODE"
+   (clobber (match_operand:P 0 "register_operand" "=d,??D"))
+   (clobber (match_operand:P 1 "register_operand" "=f,f"))
+   (clobber (match_operand:P 2 "register_operand" "=c,c"))]
+  "TARGET_H8300SX && 0"
   "@
     \n1:\tmovsd\t2f\;bra\t1b\n2:
     #"
 (define_split
   [(set (match_operand:BLK 0 "memory_operand" "")
        (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY))
-   (clobber (match_operand:HI 2 "register_operand" ""))
-   (clobber (match_operand:HI 3 "register_operand" ""))
-   (clobber (match_operand:HI 4 "register_operand" ""))]
-  "TARGET_H8300SX && TARGET_NORMAL_MODE && reload_completed
-   && REGNO (operands[2]) != DESTINATION_REG"
-  [(const_int 0)]
-  {
-    rtx dest;
-
-    h8300_swap_into_er6 (XEXP (operands[0], 0));
-    dest = replace_equiv_address (operands[0], hard_frame_pointer_rtx);
-    emit_insn (gen_movsd (dest, operands[1], operands[4]));
-    h8300_swap_out_of_er6 (operands[2]);
-    DONE;
-  })
-
-(define_split
-  [(set (match_operand:BLK 0 "memory_operand" "")
-       (unspec:BLK [(match_operand:BLK 1 "memory_operand" "")] UNSPEC_STPCPY))
-   (clobber (match_operand:SI 2 "register_operand" ""))
-   (clobber (match_operand:SI 3 "register_operand" ""))
-   (clobber (match_operand:SI 4 "register_operand" ""))]
-  "TARGET_H8300SX && !TARGET_NORMAL_MODE && reload_completed
+   (clobber (match_operand:P 2 "register_operand" ""))
+   (clobber (match_operand:P 3 "register_operand" ""))
+   (clobber (match_operand:P 4 "register_operand" ""))]
+  "TARGET_H8300SX &&  reload_completed
+   && 0
    && REGNO (operands[2]) != DESTINATION_REG"
   [(const_int 0)]
   {
 
 (include "mova.md")
 
-(define_expand "movsf"
-  [(set (match_operand:SF 0 "general_operand_dst" "")
-       (match_operand:SF 1 "general_operand_src" ""))]
-  ""
-  {
-    if (TARGET_H8300)
-      {
-       if (h8300_expand_movsi (operands))
-         DONE;
-      }
-    else if (!TARGET_H8300SX)
-      {
-       /* One of the ops has to be in a register.  */
-       if (!register_operand (operand1, SFmode)
-           && !register_operand (operand0, SFmode))
-         {
-           operands[1] = copy_to_mode_reg (SFmode, operand1);
-         }
-      }
-  })
-
 (define_insn "*movsf_h8300"
   [(set (match_operand:SF 0 "general_operand_dst" "=r,r,r,o,<,r")
        (match_operand:SF 1 "general_operand_src" "G,r,io,r,r,>"))]
   "mov.w\\t%T0,@-r7"
   [(set_attr "length" "2")])
 
-(define_insn "*pushqi1_h8300hs_<mode>"
-  [(set (mem:QI
+(define_insn "*push1_h8300hs_<QHI:mode>"
+  [(set (mem:QHI
        (pre_modify:P
          (reg:P SP_REG)
          (plus:P (reg:P SP_REG) (const_int -4))))
-       (match_operand:QI 0 "register_no_sp_elim_operand" "r"))]
+       (match_operand:QHI 0 "register_no_sp_elim_operand" "r"))]
   "TARGET_H8300H || TARGET_H8300S"
   "mov.l\\t%S0,@-er7"
   [(set_attr "length" "4")])
 
-(define_insn "*pushhi1_h8300hs_<mode>"
-  [(set (mem:HI
-       (pre_modify:P
-         (reg:P SP_REG)
-         (plus:P (reg:P SP_REG) (const_int -4))))
-       (match_operand:HI 0 "register_no_sp_elim_operand" "r"))]
-  "TARGET_H8300H || TARGET_H8300S"
-  "mov.l\\t%S0,@-er7"
-  [(set_attr "length" "4")])
 \f
 ;; ----------------------------------------------------------------------
 ;; TEST INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
 (define_insn ""
-  [(set (cc0) 
+  [(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"))
   [(set_attr "length" "2,4")
    (set_attr "cc" "set_zn,set_zn")])
 
-(define_insn ""
-  [(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) 
+  [(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"))
    (set_attr "cc" "set_zn,set_zn,set_zn")])
 
 (define_insn ""
-  [(set (cc0) 
-       (compare (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:HSI (match_operand:HSI 0 "register_operand" "r")
+                                  (const_int 1)
+                                  (match_operand 1 "const_int_operand" "n"))
                 (const_int 0)))]
-  "(TARGET_H8300H || TARGET_H8300S)
+  "(TARGET_H8300 || TARGET_H8300H || TARGET_H8300S)
     && INTVAL (operands[1]) <= 15"
   "btst        %Z1,%Y0"
   [(set_attr "length" "2")
    (set_attr "cc" "set_zn")])
 
 (define_insn_and_split "*tstsi_upper_bit"
-  [(set (cc0) 
+  [(set (cc0)
        (compare (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
                                  (const_int 1)
                                  (match_operand 1 "const_int_operand" "n"))
   [(set_attr "length" "2,8,10")
    (set_attr "cc" "set_zn,set_zn,set_zn")])
 
-(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"
+(define_insn "*tst<mode>"
   [(set (cc0)
-       (compare (match_operand:HI 0 "register_operand" "r")
+       (compare (match_operand:QHI 0 "register_operand" "r")
                 (const_int 0)))]
   ""
-  "mov.w       %T0,%T0"
+  {
+    if (<MODE>mode == QImode)
+      return "mov.b    %X0,%X0";
+    else if (<MODE>mode == HImode)
+      return "mov.w    %T0,%T0";
+    gcc_unreachable ();
+  }
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
                 (match_operand:QI 1 "h8300_src_operand" "rQi")))]
   ""
   "cmp.b       %X1,%X0"
-  [(set_attr "length_table" "addb")
+  [(set_attr "length_table" "add")
    (set_attr "cc" "compare")])
 
 (define_insn "*cmphi_h8300_znvc"
       gcc_unreachable ();
       }
 }
-  [(set_attr "length_table" "short_immediate,addw")
+  [(set_attr "length_table" "short_immediate,add")
    (set_attr "cc" "compare,compare")])
 
 (define_insn "cmpsi"
     }
 }
   [(set_attr "length" "2,*")
-   (set_attr "length_table" "*,addl")
+   (set_attr "length_table" "*,add")
    (set_attr "cc" "compare,compare")])
 \f
 ;; ----------------------------------------------------------------------
 ;; ADD INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_expand "addqi3"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (plus:QI (match_operand:QI 1 "register_operand" "")
-                (match_operand:QI 2 "h8300_src_operand" "")))]
+(define_expand "add<mode>3"
+  [(set (match_operand:QHSI 0 "register_operand" "")
+       (plus:QHSI (match_operand:QHSI 1 "register_operand" "")
+                  (match_operand:QHSI 2 "h8300_src_operand" "")))]
   ""
   "")
 
                 (match_operand:QI 2 "h8300_src_operand" "rQi")))]
   "h8300_operands_match_p (operands)"
   "add.b       %X2,%X0"
-  [(set_attr "length_table" "addb")
+  [(set_attr "length_table" "add")
    (set_attr "cc" "set_zn")])
 
-(define_expand "addhi3"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (plus:HI (match_operand:HI 1 "register_operand" "")
-                (match_operand:HI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
 (define_insn "*addhi3_h8300"
   [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r")
        (plus:HI (match_operand:HI 1 "register_operand" "%0,0,0,0,0")
   "TARGET_H8300 && epilogue_completed"
   [(const_int 0)]
   {
-    split_adds_subs (HImode, operands); 
+    split_adds_subs (HImode, operands);
     DONE;
   })
 
   [(set_attr "length" "2,2,2,4,2")
    (set_attr "cc" "none_0hit,none_0hit,clobber,set_zn,set_zn")])
 
-(define_insn "*addhi3_incdec"
-  [(set (match_operand:HI 0 "register_operand" "=r,r")
-       (unspec:HI [(match_operand:HI 1 "register_operand" "0,0")
-                   (match_operand:HI 2 "incdec_operand" "M,O")]
-                  UNSPEC_INCDEC))]
+(define_insn "*add<mode>3_incdec"
+  [(set (match_operand:HSI 0 "register_operand" "=r,r")
+       (unspec:HSI [(match_operand:HSI 1 "register_operand" "0,0")
+                    (match_operand:HSI 2 "incdec_operand" "M,O")]
+                   UNSPEC_INCDEC))]
   "TARGET_H8300H || TARGET_H8300S"
-  "@
-   inc.w       %2,%T0
-   dec.w       %G2,%T0"
+  {
+    if (which_alternative == 0)
+      return <MODE>mode == HImode ? "inc.w\t%2,%T0" : "inc.l\t%2,%S0";
+    else if (which_alternative == 1)
+      return <MODE>mode == HImode ? "dec.w\t%G2,%T0" : "dec.l\t%G2,%S0";
+    gcc_unreachable ();
+   }
   [(set_attr "length" "2,2")
    (set_attr "cc" "set_zn,set_zn")])
 
    sub.w       %G2:3,%T0
    add.b       %t2,%t0
    add.w       %T2,%T0"
-  [(set_attr "length_table" "short_immediate,short_immediate,*,addw")
+  [(set_attr "length_table" "short_immediate,short_immediate,*,add")
    (set_attr "length" "*,*,2,*")
    (set_attr "cc" "set_zn")])
 
   ""
   [(const_int 0)]
   {
-    split_adds_subs (HImode, operands); 
+    split_adds_subs (HImode, operands);
     DONE;
   })
 
-(define_expand "addsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (plus:SI (match_operand:SI 1 "register_operand" "")
-                (match_operand:SI 2 "h8300_src_operand" "")))]
-  ""
-  "")
 
 (define_insn "*addsi_h8300"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
        (plus:SI (match_operand:SI 1 "h8300_dst_operand" "%0,0")
                 (match_operand:SI 2 "h8300_src_operand" "i,rQ")))]
   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
-{  
+{
   return output_plussi (operands);
 }
   [(set (attr "length")
    (set (attr "cc")
        (symbol_ref "compute_plussi_cc (operands)"))])
 
-(define_insn "*addsi3_incdec"
-  [(set (match_operand:SI 0 "register_operand" "=r,r")
-       (unspec:SI [(match_operand:SI 1 "register_operand" "0,0")
-                   (match_operand:SI 2 "incdec_operand" "M,O")]
-                  UNSPEC_INCDEC))]
-  "TARGET_H8300H || TARGET_H8300S"
-  "@
-   inc.l       %2,%S0
-   dec.l       %G2,%S0"
-  [(set_attr "length" "2,2")
-   (set_attr "cc" "set_zn,set_zn")])
-
 (define_split
   [(set (match_operand:SI 0 "register_operand" "")
        (plus:SI (match_dup 0)
   "TARGET_H8300H || TARGET_H8300S"
   [(const_int 0)]
   {
-    split_adds_subs (SImode, operands); 
+    split_adds_subs (SImode, operands);
     DONE;
   })
 
 ;; SUBTRACT INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_expand "subqi3"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (minus:QI (match_operand:QI 1 "register_operand" "")
-                 (match_operand:QI 2 "h8300_src_operand" "")))]
+(define_expand "sub<mode>3"
+  [(set (match_operand:QHSI 0 "register_operand" "")
+       (minus:QHSI (match_operand:QHSI 1 "register_operand" "")
+                   (match_operand:QHSI 2 "h8300_src_operand" "")))]
   ""
-  "")
+  {
+    if (TARGET_H8300 && <MODE>mode == SImode)
+      operands[2] = force_reg (SImode, operands[2]);
+  })
 
 (define_insn "*subqi3"
   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
                  (match_operand:QI 2 "h8300_dst_operand" "rQ")))]
   "h8300_operands_match_p (operands)"
   "sub.b       %X2,%X0"
-  [(set_attr "length_table" "addb")
+  [(set_attr "length_table" "add")
    (set_attr "cc" "set_zn")])
 
-(define_expand "subhi3"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (minus:HI (match_operand:HI 1 "register_operand" "")
-                 (match_operand:HI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
 (define_insn "*subhi3_h8300"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
        (minus:HI (match_operand:HI 1 "register_operand" "0,0")
   [(set_attr "length" "2,4")
    (set_attr "cc" "set_zn,clobber")])
 
-(define_insn "*subhi3_h8300hs"
-  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ,rQ")
-       (minus:HI (match_operand:HI 1 "h8300_dst_operand" "0,0")
-                 (match_operand:HI 2 "h8300_src_operand" "rQ,i")))]
+(define_insn "*sub<mode>3_h8300hs"
+  [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ,rQ")
+       (minus:HSI (match_operand:HSI 1 "h8300_dst_operand" "0,0")
+                  (match_operand:HSI 2 "h8300_src_operand" "rQ,i")))]
   "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
-  "@
-   sub.w       %T2,%T0
-   sub.w       %T2,%T0"
-  [(set_attr "length_table" "addw")
+  { 
+    if (<MODE>mode == HImode)
+      return "sub.w    %T2,%T0";
+    else if (<MODE>mode == SImode)
+      return "sub.l    %S2,%S0";
+    gcc_unreachable ();
+  }
+  [(set_attr "length_table" "add")
    (set_attr "cc" "set_zn")])
 
-(define_expand "subsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (minus:SI (match_operand:SI 1 "register_operand" "")
-                 (match_operand:SI 2 "h8300_src_operand" "")))]
-  ""
-  {
-    if (TARGET_H8300)
-      operands[2] = force_reg (SImode, operands[2]);
-  })
-
 (define_insn "*subsi3_h8300"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (minus:SI (match_operand:SI 1 "register_operand" "0")
   "sub.w       %f2,%f0\;subx   %y2,%y0\;subx   %z2,%z0"
   [(set_attr "length" "6")])
 
-(define_insn "*subsi3_h8300hs"
-  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ,rQ")
-       (minus:SI (match_operand:SI 1 "h8300_dst_operand" "0,0")
-                 (match_operand:SI 2 "h8300_src_operand" "rQ,i")))]
-  "(TARGET_H8300H || TARGET_H8300S) && h8300_operands_match_p (operands)"
-  "@
-   sub.l       %S2,%S0
-   sub.l       %S2,%S0"
-  [(set_attr "length_table" "addl")
-   (set_attr "cc" "set_zn")])
 \f
 ;; ----------------------------------------------------------------------
 ;; MULTIPLY INSTRUCTIONS
 ;; on a H8SX with a multiplier, whereas muls.w seems to be available
 ;; on all H8SX variants.
 
-(define_insn "mulhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-        (mult:HI (match_operand:HI 1 "register_operand" "%0")
-                (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
-  "TARGET_H8300SX"
-  "muls.w\\t%T2,%T0"
-  [(set_attr "length" "2")
-   (set_attr "cc" "set_zn")])
-
-(define_insn "mulsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-        (mult:SI (match_operand:SI 1 "register_operand" "%0")
-                (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
+(define_insn "mul<mode>3"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+        (mult:HSI (match_operand:HSI 1 "register_operand" "%0")
+                 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
-  "muls.l\\t%S2,%S0"
+  { return <MODE>mode == HImode ? "muls.w\\t%T2,%T0" : "muls.l\\t%S2,%S0"; }
   [(set_attr "length" "2")
    (set_attr "cc" "set_zn")])
 
 ;; DIVIDE/MOD INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "udivhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-       (udiv:HI (match_operand:HI 1 "register_operand" "0")
-                (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
-  "TARGET_H8300SX"
-  "divu.w\\t%T2,%T0"
-  [(set_attr "length" "2")])
-  
-(define_insn "divhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-       (div:HI (match_operand:HI 1 "register_operand" "0")
-               (match_operand:HI 2 "reg_or_nibble_operand" "r IP4>X")))]
+(define_insn "udiv<mode>3"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+       (udiv:HSI (match_operand:HSI 1 "register_operand" "0")
+                 (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
-  "divs.w\\t%T2,%T0"
+  { return <MODE>mode == HImode ? "divu.w\\t%T2,%T0" : "divu.l\\t%S2,%S0"; }
   [(set_attr "length" "2")])
-  
-(define_insn "udivsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (udiv:SI (match_operand:SI 1 "register_operand" "0")
-                (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
-  "TARGET_H8300SX"
-  "divu.l\\t%S2,%S0"
-  [(set_attr "length" "2")])
-  
-(define_insn "divsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (div:SI (match_operand:SI 1 "register_operand" "0")
-               (match_operand:SI 2 "reg_or_nibble_operand" "r IP4>X")))]
+
+(define_insn "div<mode>3"
+  [(set (match_operand:HSI 0 "register_operand" "=r")
+       (div:HSI (match_operand:HSI 1 "register_operand" "0")
+                (match_operand:HSI 2 "reg_or_nibble_operand" "r IP4>X")))]
   "TARGET_H8300SX"
-  "divs.l\\t%S2,%S0"
+  { return <MODE>mode == HImode ? "divs.w\\t%T2,%T0" : "divs.l\\t%S2,%S0"; }
   [(set_attr "length" "2")])
-  
+
 (define_insn "udivmodqi4"
   [(set (match_operand:QI 0 "register_operand" "=r")
        (truncate:QI
   [(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")))]
+  [(set (match_operand:HI 0 "bit_register_indirect_operand")
+       (and:HI (match_operand:HI 1 "bit_register_indirect_operand")
+               (match_operand:HI 2 "single_zero_operand")))]
   "TARGET_H8300SX"
   [(set (match_dup 0)
        (and:QI (match_dup 1)
   [(set_attr "length" "2,8")
    (set_attr "cc" "none_0hit,set_znv")])
 
-(define_expand "andqi3"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (and:QI (match_operand:QI 1 "register_operand" "")
-               (match_operand:QI 2 "h8300_src_operand" "")))]
+(define_expand "and<mode>3"
+  [(set (match_operand:QHSI 0 "register_operand" "")
+       (and:QHSI (match_operand:QHSI 1 "register_operand" "")
+                 (match_operand:QHSI 2 "h8300_src_operand" "")))]
   ""
   "")
 
-(define_expand "andhi3"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (and:HI (match_operand:HI 1 "register_operand" "")
-               (match_operand:HI 2 "h8300_src_operand" "")))]
-  ""
-  "")
+(define_insn "*andor<mode>3"
+  [(set (match_operand:QHSI 0 "register_operand" "=r")
+       (ior:QHSI (and:QHSI (match_operand:QHSI 2 "register_operand" "r")
+                           (match_operand:QHSI 3 "single_one_operand" "n"))
+                 (match_operand:QHSI 1 "register_operand" "0")))]
+  "(<MODE>mode == QImode
+    || <MODE>mode == HImode
+    || (<MODE>mode == SImode
+       && (INTVAL (operands[3]) & 0xffff) != 0))"
+  {
+    if (<MODE>mode == QImode)
+      return "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0";
 
-(define_insn "*andorqi3"
-  [(set (match_operand:QI 0 "register_operand" "=r")
-       (ior:QI (and:QI (match_operand:QI 2 "register_operand" "r")
-                       (match_operand:QI 3 "single_one_operand" "n"))
-               (match_operand:QI 1 "register_operand" "0")))]
-  ""
-  "bld\\t%V3,%X2\;bor\\t%V3,%X0\;bst\\t%V3,%X0"
-  [(set_attr "length" "6")])
+    if (<MODE>mode == HImode)
+      {
+       operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
+       if (INTVAL (operands[3]) > 128)
+         {
+           operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
+           return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
+         }
+       return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
+      }
 
-(define_insn "*andorhi3"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-       (ior:HI (and:HI (match_operand:HI 2 "register_operand" "r")
-                       (match_operand:HI 3 "single_one_operand" "n"))
-               (match_operand:HI 1 "register_operand" "0")))]
-  ""
-{
-  operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
-  if (INTVAL (operands[3]) > 128)
-    {
-      operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
-      return "bld\\t%V3,%t2\;bor\\t%V3,%t0\;bst\\t%V3,%t0";
-    }
-  return "bld\\t%V3,%s2\;bor\\t%V3,%s0\;bst\\t%V3,%s0";
-}
-  [(set_attr "length" "6")])
+    if (<MODE>mode == SImode)
+      {
+       operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
+       if (INTVAL (operands[3]) > 128)
+         {
+           operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
+           return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
+         }
+       return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
+      }
 
-(define_insn "*andorsi3"
-  [(set (match_operand:SI 0 "register_operand" "=r")
-       (ior:SI (and:SI (match_operand:SI 2 "register_operand" "r")
-                       (match_operand:SI 3 "single_one_operand" "n"))
-               (match_operand:SI 1 "register_operand" "0")))]
-  "(INTVAL (operands[3]) & 0xffff) != 0"
-{
-  operands[3] = GEN_INT (INTVAL (operands[3]) & 0xffff);
-  if (INTVAL (operands[3]) > 128)
-    {
-      operands[3] = GEN_INT (INTVAL (operands[3]) >> 8);
-      return "bld\\t%V3,%x2\;bor\\t%V3,%x0\;bst\\t%V3,%x0";
-    }
-  return "bld\\t%V3,%w2\;bor\\t%V3,%w0\;bst\\t%V3,%w0";
-}
+    gcc_unreachable ();
+       
+  }
   [(set_attr "length" "6")])
 
 (define_insn "*andorsi3_shift_8"
   "or.b\\t%w2,%x0"
   [(set_attr "length" "2")])
 
-(define_expand "andsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (and:SI (match_operand:SI 1 "register_operand" "")
-               (match_operand:SI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
 ;; ----------------------------------------------------------------------
-;; OR INSTRUCTIONS
+;; OR/XOR INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_insn "bsetqi_msx"
+(define_insn "b<code>qi_msx"
   [(set (match_operand:QI 0 "bit_register_indirect_operand" "=WU")
-       (ior:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
+       (ors:QI (match_operand:QI 1 "bit_register_indirect_operand" "%0")
                (match_operand:QI 2 "single_one_operand" "Y2")))]
   "TARGET_H8300SX && rtx_equal_p (operands[0], operands[1])"
-  "bset\\t%V2,%0"
+  { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\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)))]
-  {
-    if (abs (INTVAL (operands[2])) > 0xFF)
-      {
-       operands[0] = adjust_address (operands[0], QImode, 0);
-       operands[1] = adjust_address (operands[1], QImode, 0);
-       operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
-      }
-    else
-      {
-       operands[0] = adjust_address (operands[0], QImode, 1);
-       operands[1] = adjust_address (operands[1], QImode, 1);
-      }
-  })
-
-(define_insn "bsethi_msx"
+(define_insn "b<code>hi_msx"
   [(set (match_operand:HI 0 "bit_register_indirect_operand" "=m")
-       (ior:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
+       (ors:HI (match_operand:HI 1 "bit_register_indirect_operand" "%0")
                (match_operand:HI 2 "single_one_operand" "Y2")))]
   "TARGET_H8300SX"
-  "bset\\t%V2,%0"
+  { return <CODE> == IOR ? "bset\\t%V2,%0" : "bnot\\t%V2,%0"; }
   [(set_attr "length" "8")])
 
-(define_insn "iorqi3_1"
+(define_insn "<code>qi3_1"
   [(set (match_operand:QI 0 "bit_operand" "=U,rQ")
-       (ior:QI (match_operand:QI 1 "bit_operand" "%0,0")
+       (ors:QI (match_operand:QI 1 "bit_operand" "%0,0")
                (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
   "TARGET_H8300SX || register_operand (operands[0], QImode)
    || single_one_operand (operands[2], QImode)"
-  "@
-   bset\\t%V2,%R0
-   or\\t%X2,%X0"
-  [(set_attr "length" "8,*")
-   (set_attr "length_table" "*,logicb")
-   (set_attr "cc" "none_0hit,set_znv")])
-
-
-(define_expand "iorqi3"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (ior:QI (match_operand:QI 1 "register_operand" "")
-               (match_operand:QI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
-(define_expand "iorhi3"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (ior:HI (match_operand:HI 1 "register_operand" "")
-               (match_operand:HI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
-(define_expand "iorsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (ior:SI (match_operand:SI 1 "register_operand" "")
-               (match_operand:SI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
-;; ----------------------------------------------------------------------
-;; 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
-   && rtx_equal_p (operands[0], operands[1])"
-  "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)))]
   {
-    if (abs (INTVAL (operands[2])) > 0xFF)
-      {
-       operands[0] = adjust_address (operands[0], QImode, 0);
-       operands[1] = adjust_address (operands[1], QImode, 0);
-       operands[2] = GEN_INT ((INTVAL (operands[2])) >> 8);
-      }
-    else
-      {
-       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" "=U,r")
-       (xor:QI (match_operand:QI 1 "bit_operand" "%0,0")
-               (match_operand:QI 2 "h8300_src_operand" "Y2,rQi")))]
-  "TARGET_H8300SX || register_operand (operands[0], QImode)
-   || single_one_operand (operands[2], QImode)"
-  "@
-   bnot\\t%V2,%R0
-   xor\\t%X2,%X0"
+    if (which_alternative == 0)
+      return <CODE> == IOR ? "bset\\t%V2,%R0" : "bnot\\t%V2,%R0"; 
+    else if (which_alternative == 1)
+      return <CODE> == IOR ? "or\\t%X2,%X0" : "xor\\t%X2,%X0";
+    gcc_unreachable ();
+  }
   [(set_attr "length" "8,*")
    (set_attr "length_table" "*,logicb")
    (set_attr "cc" "none_0hit,set_znv")])
 
-(define_expand "xorqi3"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (xor:QI (match_operand:QI 1 "register_operand" "")
-               (match_operand:QI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
-(define_expand "xorhi3"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (xor:HI (match_operand:HI 1 "register_operand" "")
-               (match_operand:HI 2 "h8300_src_operand" "")))]
-  ""
-  "")
-
-(define_expand "xorsi3"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (xor:SI (match_operand:SI 1 "register_operand" "")
-               (match_operand:SI 2 "h8300_src_operand" "")))]
+(define_expand "<code><mode>3"
+  [(set (match_operand:QHSI 0 "register_operand" "")
+       (ors:QHSI (match_operand:QHSI 1 "register_operand" "")
+                 (match_operand:QHSI 2 "h8300_src_operand" "")))]
   ""
   "")
 
 ;; {AND,IOR,XOR}{HI3,SI3} PATTERNS
 ;; ----------------------------------------------------------------------
 
-;; We need a separate pattern here because machines other than the
-;; original H8300 don't have to split the 16-bit operand into a pair
-;; of high/low instructions, so we can accept literal addresses, that
-;; have to be loaded into a register on H8300.
-
-(define_insn "*logicalhi3_sn"
-  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
-       (match_operator:HI 3 "bit_operator"
-        [(match_operand:HI 1 "h8300_dst_operand" "%0")
-         (match_operand:HI 2 "h8300_src_operand" "rQi")]))]
-  "(TARGET_H8300S || TARGET_H8300H) && h8300_operands_match_p (operands)"
-{
-  return output_logical_op (HImode, operands);
-}
-  [(set (attr "length")
-       (symbol_ref "compute_logical_op_length (HImode, operands)"))
-   (set (attr "cc")
-       (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
-
-(define_insn "*logicalsi3_sn"
-  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
-       (match_operator:SI 3 "bit_operator"
-        [(match_operand:SI 1 "h8300_dst_operand" "%0")
-         (match_operand:SI 2 "h8300_src_operand" "rQi")]))]
-  "(TARGET_H8300S || TARGET_H8300H) && h8300_operands_match_p (operands)"
-{
-  return output_logical_op (SImode, operands);
-}
-  [(set (attr "length")
-       (symbol_ref "compute_logical_op_length (SImode, operands)"))
-   (set (attr "cc")
-       (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
-
-(define_insn "*logicalhi3"
-  [(set (match_operand:HI 0 "h8300_dst_operand" "=rQ")
-       (match_operator:HI 3 "bit_operator"
-         [(match_operand:HI 1 "h8300_dst_operand" "%0")
-          (match_operand:HI 2 "h8300_src_operand" "rQi")]))]
-  "h8300_operands_match_p (operands)"
-{
-  return output_logical_op (HImode, operands);
-}
-  [(set (attr "length")
-       (symbol_ref "compute_logical_op_length (HImode, operands)"))
-   (set (attr "cc")
-       (symbol_ref "compute_logical_op_cc (HImode, operands)"))])
-
-(define_insn "*logicalsi3"
-  [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
-       (match_operator:SI 3 "bit_operator"
-        [(match_operand:SI 1 "h8300_dst_operand" "%0")
-         (match_operand:SI 2 "h8300_src_operand" "rQi")]))]
+(define_insn "*logical<mode>3"
+  [(set (match_operand:HSI 0 "h8300_dst_operand" "=rQ")
+       (match_operator:HSI 3 "bit_operator"
+         [(match_operand:HSI 1 "h8300_dst_operand" "%0")
+          (match_operand:HSI 2 "h8300_src_operand" "rQi")]))]
   "h8300_operands_match_p (operands)"
-{
-  return output_logical_op (SImode, operands);
-}
+  { return output_logical_op (<MODE>mode, operands); }
   [(set (attr "length")
-       (symbol_ref "compute_logical_op_length (SImode, operands)"))
+       (symbol_ref "compute_logical_op_length (<MODE>mode, operands)"))
    (set (attr "cc")
-       (symbol_ref "compute_logical_op_cc (SImode, operands)"))])
+       (symbol_ref "compute_logical_op_cc (<MODE>mode, operands)"))])
 \f
 ;; ----------------------------------------------------------------------
 ;; NEGATION INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_expand "negqi2"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (neg:QI (match_operand:QI 1 "register_operand" "")))]
+(define_expand "neg<mode>2"
+  [(set (match_operand:QHSIF 0 "register_operand" "")
+       (neg:QHSIF (match_operand:QHSIF 1 "register_operand" "")))]
   ""
-  "")
+  {
+    enum machine_mode mode = <MODE>mode;
+    if (TARGET_H8300)
+      {
+       if (mode == QImode || mode == SFmode)
+         ;
+       else if (mode == HImode)
+         {
+           emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
+           DONE;
+         }
+       else if (mode == SImode)
+         {
+           emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
+           DONE;
+         }
+      }
+  })
 
 (define_insn "*negqi2"
   [(set (match_operand:QI 0 "h8300_dst_operand" "=rQ")
   [(set_attr "length_table" "unary")
    (set_attr "cc" "set_zn")])
 
-(define_expand "neghi2"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (neg:HI (match_operand:HI 1 "register_operand" "")))]
-  ""
-  {
-    if (TARGET_H8300)
-      {
-       emit_insn (gen_neghi2_h8300 (operands[0], operands[1]));
-       DONE;
-      }
-  })
-
-(define_expand "neghi2_h8300"
+(define_expand "neg<mode>2_h8300"
   [(set (match_dup 2)
-       (not:HI (match_operand:HI 1 "register_operand" "")))
-   (set (match_dup 2) (plus:HI (match_dup 2) (const_int 1)))
-   (set (match_operand:HI 0 "register_operand" "")
+       (not:HSI (match_operand:HSI 1 "register_operand" "")))
+   (set (match_dup 2) (plus:HSI (match_dup 2) (const_int 1)))
+   (set (match_operand:HSI 0 "register_operand" "")
        (match_dup 2))]
   ""
   {
-    operands[2] = gen_reg_rtx (HImode);
+    operands[2] = gen_reg_rtx (<MODE>mode);
   })
 
 (define_insn "*neghi2_h8300hs"
   [(set_attr "length_table" "unary")
    (set_attr "cc" "set_zn")])
 
-(define_expand "negsi2"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (neg:SI (match_operand:SI 1 "register_operand" "")))]
-  ""
-  {
-    if (TARGET_H8300)
-      {
-       emit_insn (gen_negsi2_h8300 (operands[0], operands[1]));
-       DONE;
-      }
-  })
-
-(define_expand "negsi2_h8300"
-  [(set (match_dup 2)
-       (not:SI (match_operand:SI 1 "register_operand" "")))
-   (set (match_dup 2) (plus:SI (match_dup 2) (const_int 1)))
-   (set (match_operand:SI 0 "register_operand" "")
-       (match_dup 2))]
-  ""
-  {
-    operands[2] = gen_reg_rtx (SImode);
-  })
-
 (define_insn "*negsi2_h8300hs"
   [(set (match_operand:SI 0 "h8300_dst_operand" "=rQ")
        (neg:SI (match_operand:SI 1 "h8300_dst_operand" "0")))]
   [(set_attr "length_table" "unary")
    (set_attr "cc" "set_zn")])
 
-(define_expand "negsf2"
-  [(set (match_operand:SF 0 "register_operand" "")
-       (neg:SF (match_operand:SF 1 "register_operand" "")))]
-  ""
-  "")
-
 (define_insn "*negsf2_h8300"
   [(set (match_operand:SF 0 "register_operand" "=r")
        (neg:SF (match_operand:SF 1 "register_operand" "0")))]
 ;; NOT INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_expand "one_cmplqi2"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (not:QI (match_operand:QI 1 "register_operand" "")))]
+(define_expand "one_cmpl<mode>2"
+  [(set (match_operand:QHSI 0 "register_operand" "")
+       (not:QHSI (match_operand:QHSI 1 "register_operand" "")))]
   ""
   "")
 
   [(set_attr "length_table" "unary")
    (set_attr "cc" "set_znv")])
 
-(define_expand "one_cmplhi2"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (not:HI (match_operand:HI 1 "register_operand" "")))]
-  ""
-  "")
-
 (define_insn "*one_cmplhi2_h8300"
   [(set (match_operand:HI 0 "register_operand" "=r")
        (not:HI (match_operand:HI 1 "register_operand" "0")))]
   [(set_attr "cc" "set_znv")
    (set_attr "length_table" "unary")])
 
-(define_expand "one_cmplsi2"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (not:SI (match_operand:SI 1 "register_operand" "")))]
-  ""
-  "")
-
 (define_insn "*one_cmplsi2_h8300"
   [(set (match_operand:SI 0 "register_operand" "=r")
        (not:SI (match_operand:SI 1 "register_operand" "0")))]
     if ((GET_CODE (operands[2]) != REG && operands[2] != const0_rtx)
        && TARGET_H8300)
       operands[2] = force_reg (HImode, operands[2]);
-    h8300_expand_branch (operands); 
+    h8300_expand_branch (operands);
     DONE;
   })
 
             bytes further than previously thought.  The length-based
             test for bra vs. jump is very conservative though, so the
             branch will still be within range.  */
-         rtvec vec;
+         rtx_sequence *seq;
          int seen;
 
-         vec = XVEC (final_sequence, 0);
+         seq = final_sequence;
          final_sequence = 0;
-         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;
+         final_scan_insn (seq->insn (1), asm_out_file, optimize, 1, & seen);
+         final_scan_insn (seq->insn (0), asm_out_file, optimize, 1, & seen);
+         seq->insn (1)->set_deleted ();
          return "";
        }
     }
 
 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
 
-(define_insn "call"
-  [(call (match_operand:QI 0 "call_insn_operand" "or")
-        (match_operand:HI 1 "general_operand" "g"))]
+(define_expand "call"
+  [(call (match_operand:QI 0 "call_expander_operand" "")
+        (match_operand 1 "general_operand" ""))]
+  ""
+  {
+    if (!register_operand (XEXP (operands[0], 0), Pmode)
+       && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
+      XEXP (operands[0], 0) = force_reg (Pmode, XEXP (operands[0], 0));
+  })
+
+(define_insn "call_insn_<mode>"
+  [(call (mem:QI (match_operand 0 "call_insn_operand" "Cr"))
+                (match_operand:P 1 "general_operand" "g"))]
   ""
 {
-  if (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
-      && SYMBOL_REF_FLAG (XEXP (operands[0], 0)))
-    return "jsr\\t@%0:8";
+  rtx xoperands[1];
+  xoperands[0] = gen_rtx_MEM (QImode, operands[0]);
+  gcc_assert (GET_MODE (operands[0]) == Pmode);
+  if (GET_CODE (XEXP (xoperands[0], 0)) == SYMBOL_REF
+      && (SYMBOL_REF_FLAGS (XEXP (xoperands[0], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+    output_asm_insn ("jsr\\t@%0:8", xoperands);
   else
-    return "jsr\\t%0";
+    output_asm_insn ("jsr\\t%0", xoperands);
+  return "";
 }
   [(set_attr "type" "call")
    (set (attr "length")
 
 ;; ??? Even though we use HImode here, this works on the H8/300H and H8S.
 
-(define_insn "call_value"
+(define_expand "call_value"
+  [(set (match_operand 0 "" "")
+       (call (match_operand:QI 1 "call_expander_operand" "")
+             (match_operand 2 "general_operand" "")))]
+  ""
+  {
+    if (!register_operand (XEXP (operands[1], 0), Pmode)
+       && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
+      XEXP (operands[1], 0) = force_reg (Pmode, XEXP (operands[1], 0));
+  })
+
+(define_insn "call_value_insn_<mode>"
   [(set (match_operand 0 "" "=r")
-       (call (match_operand:QI 1 "call_insn_operand" "or")
-             (match_operand:HI 2 "general_operand" "g")))]
+       (call (mem:QI (match_operand 1 "call_insn_operand" "Cr"))
+                     (match_operand:P 2 "general_operand" "g")))]
   ""
 {
-  if (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
-      && SYMBOL_REF_FLAG (XEXP (operands[1], 0)))
-    return "jsr\\t@%1:8";
+  rtx xoperands[2];
+  gcc_assert (GET_MODE (operands[1]) == Pmode);
+  xoperands[0] = operands[0];
+  xoperands[1] = gen_rtx_MEM (QImode, operands[1]);
+  if (GET_CODE (XEXP (xoperands[1], 0)) == SYMBOL_REF
+      && (SYMBOL_REF_FLAGS (XEXP (xoperands[1], 0)) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
+    output_asm_insn ("jsr\\t@%1:8", xoperands);
   else
-    return "jsr\\t%1";
+    output_asm_insn ("jsr\\t%1", xoperands);
+  return "";
 }
   [(set_attr "type" "call")
    (set (attr "length")
   [(const_int 0)]
   ""
   {
-    h8300_expand_prologue (); 
+    h8300_expand_prologue ();
     DONE;
   })
 
   [(return)]
   ""
   {
-    h8300_expand_epilogue (); 
+    h8300_expand_epilogue ();
     DONE;
   })
 
   else if (TARGET_H8300H)
     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 && TARGET_NEXR )
-    return "mov.l\\ter0,@-er7\;stc\tccr,r0l\;mov.b\tr0l,@(4,er7)\;mov.l\\t@er7+,er0\;orc\t#128,ccr"; 
+    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 && TARGET_NEXR && TARGET_NORMAL_MODE)
     return "subs\\t#2,er7\;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 && TARGET_NORMAL_MODE)
 ;; EXTEND INSTRUCTIONS
 ;; ----------------------------------------------------------------------
 
-(define_expand "zero_extendqihi2"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (zero_extend:HI (match_operand:QI 1 "general_operand_src" "")))]
+(define_expand "zero_extendqi<mode>2"
+  [(set (match_operand:HSI 0 "register_operand" "")
+       (zero_extend:HSI (match_operand:QI 1 "general_operand_src" "")))]
   ""
-  "")
+  {
+    if (TARGET_H8300SX)
+      operands[1] = force_reg (QImode, operands[1]);
+  })
 
 (define_insn "*zero_extendqihi2_h8300"
   [(set (match_operand:HI 0 "register_operand" "=r,r")
     operands[2] = gen_rtx_REG (QImode, REGNO (operands[0]));
   })
 
-(define_expand "zero_extendqisi2"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (zero_extend:SI (match_operand:QI 1 "general_operand_src" "")))]
-  ""
-  {
-    if (TARGET_H8300SX)
-      operands[1] = force_reg (QImode, operands[1]);
-  })
 
 (define_insn "*zero_extendqisi2_h8300"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
-(define_expand "extendqihi2"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (sign_extend:HI (match_operand:QI 1 "register_operand" "")))]
+(define_expand "extendqi<mode>2"
+  [(set (match_operand:HSI 0 "register_operand" "")
+       (sign_extend:HSI (match_operand:QI 1 "register_operand" "")))]
   ""
   "")
 
   [(set_attr "length" "2")
    (set_attr "cc" "set_znv")])
 
-(define_expand "extendqisi2"
-  [(set (match_operand:SI 0 "register_operand" "")
-       (sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
-  ""
-  "")
-
 (define_insn "*extendqisi2_h8300"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
        (sign_extend:SI (match_operand:QI 1 "general_operand_src" "0,g>")))]
                   (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (QImode, ASHIFT, operands)) 
+    if (expand_a_shift (QImode, ASHIFT, operands))
     DONE;
   })
 
                     (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (QImode, ASHIFTRT, operands)) 
+    if (expand_a_shift (QImode, ASHIFTRT, operands))
     DONE;
   })
 
                     (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (QImode, LSHIFTRT, operands)) 
+    if (expand_a_shift (QImode, LSHIFTRT, operands))
     DONE;
   })
 
         [(match_operand:QI 1 "h8300_dst_operand" "0")
          (match_operand:QI 2 "const_int_operand" "")]))]
   "h8300_operands_match_p (operands)"
-{ 
-  return output_h8sx_shift (operands, 'b', 'X'); 
+{
+  return output_h8sx_shift (operands, 'b', 'X');
 }
   [(set_attr "length_table" "unary")
    (set_attr "cc" "set_znv")])
          (match_operand:QI 2 "nonmemory_operand" "r P3>X")]))]
   ""
 {
-  return output_h8sx_shift (operands, 'b', 'X'); 
+  return output_h8sx_shift (operands, 'b', 'X');
 }
   [(set_attr "length" "4")
    (set_attr "cc" "set_znv")])
                   (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (HImode, ASHIFT, operands)) 
+    if (expand_a_shift (HImode, ASHIFT, operands))
     DONE;
   })
 
                     (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (HImode, LSHIFTRT, operands)) 
+    if (expand_a_shift (HImode, LSHIFTRT, operands))
     DONE;
   })
 
                     (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (HImode, ASHIFTRT, operands)) 
+    if (expand_a_shift (HImode, ASHIFTRT, operands))
     DONE;
   })
 
         [(match_operand:HI 1 "h8300_dst_operand" "0")
          (match_operand:QI 2 "const_int_operand" "")]))]
   "h8300_operands_match_p (operands)"
-{ 
-  return output_h8sx_shift (operands, 'w', 'T'); 
+{
+  return output_h8sx_shift (operands, 'w', 'T');
 }
   [(set_attr "length_table" "unary")
    (set_attr "cc" "set_znv")])
          (match_operand:QI 2 "nonmemory_operand" "r P4>X")]))]
   ""
 {
-  return output_h8sx_shift (operands, 'w', 'T'); 
+  return output_h8sx_shift (operands, 'w', 'T');
 }
   [(set_attr "length" "4")
    (set_attr "cc" "set_znv")])
                   (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (SImode, ASHIFT, operands)) 
+    if (expand_a_shift (SImode, ASHIFT, operands))
     DONE;
   })
 
                     (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (SImode, LSHIFTRT, operands)) 
+    if (expand_a_shift (SImode, LSHIFTRT, operands))
     DONE;
   })
 
                     (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_shift (SImode, ASHIFTRT, operands)) 
+    if (expand_a_shift (SImode, ASHIFTRT, operands))
     DONE;
   })
 
          (match_operand:QI 2 "const_int_operand" "")]))]
   "h8300_operands_match_p (operands)"
 {
-  return output_h8sx_shift (operands, 'l', 'S'); 
+  return output_h8sx_shift (operands, 'l', 'S');
 }
   [(set_attr "length_table" "unary")
    (set_attr "cc" "set_znv")])
         [(match_operand:SI 1 "register_operand" "0")
          (match_operand:QI 2 "nonmemory_operand" "r P5>X")]))]
   ""
-{ 
-  return output_h8sx_shift (operands, 'l', 'S'); 
+{
+  return output_h8sx_shift (operands, 'l', 'S');
 }
   [(set_attr "length" "4")
    (set_attr "cc" "set_znv")])
 ;; ROTATIONS
 ;; ----------------------------------------------------------------------
 
-(define_expand "rotlqi3"
-  [(set (match_operand:QI 0 "register_operand" "")
-       (rotate:QI (match_operand:QI 1 "register_operand" "")
-                  (match_operand:QI 2 "nonmemory_operand" "")))]
-  ""
-  {
-    if (expand_a_rotate (operands)) 
-    DONE;
-  })
-
-(define_insn "rotlqi3_1"
-  [(set (match_operand:QI 0 "register_operand" "=r")
-       (rotate:QI (match_operand:QI 1 "register_operand" "0")
-                  (match_operand:QI 2 "immediate_operand" "")))]
-  ""
-{
-  return output_a_rotate (ROTATE, operands);
-}
-  [(set (attr "length")
-       (symbol_ref "compute_a_rotate_length (operands)"))])
-
-(define_expand "rotlhi3"
-  [(set (match_operand:HI 0 "register_operand" "")
-       (rotate:HI (match_operand:HI 1 "register_operand" "")
-                  (match_operand:QI 2 "nonmemory_operand" "")))]
+(define_expand "rotl<mode>3"
+  [(set (match_operand:QHI 0 "register_operand" "")
+       (rotate:QHI (match_operand:QHI 1 "register_operand" "")
+                   (match_operand:QI 2 "nonmemory_operand" "")))]
   ""
   {
-    if (expand_a_rotate (operands)) 
+    if (expand_a_rotate (operands))
     DONE;
   })
 
-(define_insn "rotlhi3_1"
-  [(set (match_operand:HI 0 "register_operand" "=r")
-       (rotate:HI (match_operand:HI 1 "register_operand" "0")
-                  (match_operand:QI 2 "immediate_operand" "")))]
+(define_insn "rotl<mode>3_1"
+  [(set (match_operand:QHI 0 "register_operand" "=r")
+       (rotate:QHI (match_operand:QHI 1 "register_operand" "0")
+                   (match_operand:QI 2 "immediate_operand" "")))]
   ""
 {
   return output_a_rotate (ROTATE, operands);
                   (match_operand:QI 2 "nonmemory_operand" "")))]
   "TARGET_H8300H || TARGET_H8300S"
   {
-    if (expand_a_rotate (operands)) 
+    if (expand_a_rotate (operands))
     DONE;
   })
 
    (clobber (match_operand:HI 0 "register_operand"))]
   "TARGET_H8300SX"
   {
-    h8300_expand_store (operands); 
+    h8300_expand_store (operands);
     DONE;
   })
 
    (clobber (match_operand:HI 0 "register_operand"))]
   "TARGET_H8300SX"
   {
-    h8300_expand_store (operands); 
+    h8300_expand_store (operands);
     DONE;
   })
 
    (clobber (match_operand:HI 0 "register_operand"))]
   "TARGET_H8300SX"
   {
-    h8300_expand_store (operands); 
+    h8300_expand_store (operands);
     DONE;
   })
 
   [(set_attr "cc" "clobber")])
 
 (define_insn_and_split "*cmpstz"
-  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,+WU")
+  [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU,WU")
                         (const_int 1)
                         (match_operand:QI 1 "immediate_operand" "n,n"))
        (match_operator:QI 2 "eqne_operator"
     operands[5] = gen_rtx_COMPARE (VOIDmode, operands[3], operands[4]);
   }
   [(set_attr "cc" "set_znv,compare")])
-   
+
 (define_insn "*bstz"
   [(set (zero_extract:QI (match_operand:QI 0 "bit_memory_operand" "+WU")
                         (const_int 1)
     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
   }
   [(set_attr "cc" "set_znv,compare")])
-   
+
 (define_insn "*condbset"
   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
        (if_then_else:QI (match_operator:QI 2 "eqne_operator"
     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
   }
   [(set_attr "cc" "set_znv,compare")])
-   
+
 (define_insn "*condbclr"
   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
        (if_then_else:QI (match_operator:QI 2 "eqne_operator"
     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
   }
   [(set_attr "cc" "set_znv,compare")])
-   
+
 (define_insn "*condbsetreg"
   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
        (if_then_else:QI (match_operator:QI 2 "eqne_operator"
     operands[6] = gen_rtx_COMPARE (VOIDmode, operands[2], operands[3]);
   }
   [(set_attr "cc" "set_znv,compare")])
-   
+
 (define_insn "*condbclrreg"
   [(set (match_operand:QI 0 "bit_memory_operand" "=WU")
        (if_then_else:QI (match_operator:QI 2 "eqne_operator"
    (clobber (match_scratch:QI 4 "=X,&r"))]
   "(TARGET_H8300H || TARGET_H8300S)
     && INTVAL (operands[2]) <= 15
-    && INTVAL (operands[3]) == ((-1 << INTVAL (operands[2])) & 0xffff)"
+    && UINTVAL (operands[3]) == ((HOST_WIDE_INT_M1U << INTVAL (operands[2]))
+                                & 0xffff)"
   "#"
   "&& reload_completed"
   [(parallel [(set (match_dup 5)
                   (ashiftrt:SI (match_dup 0)
                                (const_int 1)))
              (clobber (scratch:QI))])]
-  { 
+  {
     operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
   })
 
   "TARGET_H8300S && !TARGET_NORMAL_MODE && REGNO (operands[0]) != SP_REG"
   [(set (mem:SI (pre_dec:SI (reg:SI SP_REG)))
        (match_dup 0))]
-  { 
+  {
     operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
   })
 
 
 (define_peephole2
   [(set (match_operand:SI 0 "register_operand" "")
-       (match_operand:SI 1 "general_operand" ""))
+       (match_operand:SI 1 "nonimmediate_operand" ""))
    (set (match_dup 0)
        (and:SI (match_dup 0)
                (const_int 255)))]
 
 (define_peephole2
   [(set (match_operand 0 "register_operand" "")
-       (match_operand 1 "general_operand" ""))
+       (match_operand 1 "nonimmediate_operand" ""))
    (set (match_operand:SI 2 "register_operand" "")
        (and:SI (match_dup 2)
                (match_operand:SI 3 "const_int_qi_operand" "")))]
                      (pc)))]
   "(TARGET_H8300H || TARGET_H8300S)
     && peep2_reg_dead_p (1, operands[0])
-    && ((TARGET_H8300H && INTVAL (operands[1]) == 3)
+    && (INTVAL (operands[1]) == 3
         || INTVAL (operands[1]) == 7
         || INTVAL (operands[1]) == 15
         || INTVAL (operands[1]) == 31
        (if_then_else (match_dup 3)
                      (label_ref (match_dup 2))
                      (pc)))]
-  {  
+  {
     operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[1]) == GTU ? NE : EQ,
                                  VOIDmode, cc0_rtx, const0_rtx);
   })
    && !reg_overlap_mentioned_p (operands[0], operands[2])"
   [(set (match_dup 2)
        (match_dup 1))])
-       
+