]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/config/h8300/h8300.c
Update copyright years.
[thirdparty/gcc.git] / gcc / config / h8300 / h8300.c
index 38a922898e2aa23f628d463d19af044a314821ef..6c84b0abea7eca52904a17aca1d57114e61c304d 100644 (file)
@@ -1,7 +1,5 @@
 /* Subroutines for insn-output.c for Renesas H8/300.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-   2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-   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).
 
@@ -21,31 +19,40 @@ You should have received a copy of the GNU General Public License
 along with GCC; see the file COPYING3.  If not see
 <http://www.gnu.org/licenses/>.  */
 
+#define IN_TARGET_CODE 1
+
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
+#include "backend.h"
+#include "target.h"
 #include "rtl.h"
 #include "tree.h"
+#include "df.h"
+#include "memmodel.h"
+#include "tm_p.h"
+#include "stringpool.h"
+#include "attribs.h"
+#include "optabs.h"
 #include "regs.h"
-#include "hard-reg-set.h"
-#include "insn-config.h"
+#include "emit-rtl.h"
+#include "recog.h"
+#include "diagnostic-core.h"
+#include "alias.h"
+#include "stor-layout.h"
+#include "varasm.h"
+#include "calls.h"
 #include "conditions.h"
 #include "output.h"
 #include "insn-attr.h"
 #include "flags.h"
-#include "recog.h"
+#include "explow.h"
 #include "expr.h"
-#include "function.h"
-#include "optabs.h"
-#include "diagnostic-core.h"
-#include "c-family/c-pragma.h" /* ??? */
-#include "tm_p.h"
 #include "tm-constrs.h"
-#include "ggc.h"
-#include "target.h"
+#include "builtins.h"
+
+/* This file should be included last.  */
 #include "target-def.h"
-#include "df.h"
 
 /* Classifies a h8300_src_operand or h8300_dst_operand.
 
@@ -92,13 +99,13 @@ static unsigned int h8300_asm_insn_count (const char *);
 static tree h8300_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
 static tree h8300_handle_eightbit_data_attribute (tree *, tree, tree, int, bool *);
 static tree h8300_handle_tiny_data_attribute (tree *, tree, tree, int, bool *);
-static void h8300_print_operand_address (FILE *, rtx);
+static void h8300_print_operand_address (FILE *, machine_mode, rtx);
 static void h8300_print_operand (FILE *, rtx, int);
 static bool h8300_print_operand_punct_valid_p (unsigned char code);
 #ifndef OBJECT_FORMAT_ELF
 static void h8300_asm_named_section (const char *, unsigned int, tree);
 #endif
-static int h8300_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
+static int h8300_register_move_cost (machine_mode, reg_class_t, reg_class_t);
 static int h8300_and_costs (rtx);
 static int h8300_shift_costs (rtx);
 static void          h8300_push_pop               (int, int, bool, bool);
@@ -112,11 +119,11 @@ static unsigned int  h8300_length_from_table      (rtx, rtx, const h8300_length_
 static unsigned int  h8300_unary_length           (rtx);
 static unsigned int  h8300_short_immediate_length (rtx);
 static unsigned int  h8300_bitfield_length        (rtx, rtx);
-static unsigned int  h8300_binary_length          (rtx, const h8300_length_table *);
+static unsigned int  h8300_binary_length          (rtx_insn *, const h8300_length_table *);
 static bool          h8300_short_move_mem_p       (rtx, enum rtx_code);
 static unsigned int  h8300_move_length            (rtx *, const h8300_length_table *);
 static bool         h8300_hard_regno_scratch_ok  (unsigned int);
-static rtx          h8300_get_index (rtx, enum machine_mode mode, int *);
+static rtx          h8300_get_index (rtx, machine_mode mode, int *);
 
 /* CPU_TYPE, says what cpu we're compiling for.  */
 int cpu_type;
@@ -319,7 +326,7 @@ h8300_option_override (void)
 #ifndef OBJECT_FORMAT_ELF
   if (TARGET_H8300SX)
     {
-      error ("-msx is not supported in coff");
+      error ("%<-msx%> is not supported in coff");
       target_flags |= MASK_H8300S;
     }
 #endif
@@ -341,40 +348,48 @@ h8300_option_override (void)
 
   if (!TARGET_H8300S && TARGET_MAC)
     {
-      error ("-ms2600 is used without -ms");
+      error ("%<-ms2600%> is used without %<-ms%>");
       target_flags |= MASK_H8300S_1;
     }
 
   if (TARGET_H8300 && TARGET_NORMAL_MODE)
     {
-      error ("-mn is used without -mh or -ms or -msx");
+      error ("%<-mn%> is used without %<-mh%> or %<-ms%> or %<-msx%>");
       target_flags ^= MASK_NORMAL_MODE;
     }
 
   if (! TARGET_H8300S &&  TARGET_EXR)
     {
-      error ("-mexr is used without -ms");
+      error ("%<-mexr%> is used without %<-ms%>");
       target_flags |= MASK_H8300S_1;
     }
 
   if (TARGET_H8300 && TARGET_INT32)
    {
-      error ("-mint32 is not supported for H8300 and H8300L targets");
+      error ("%<-mint32%> is not supported for H8300 and H8300L targets");
       target_flags ^= MASK_INT32;
    }
 
  if ((!TARGET_H8300S  &&  TARGET_EXR) && (!TARGET_H8300SX && TARGET_EXR))
    {
-      error ("-mexr is used without -ms or -msx");
+      error ("%<-mexr%> is used without %<-ms%> or %<-msx%>");
       target_flags |= MASK_H8300S_1;
    }
 
  if ((!TARGET_H8300S  &&  TARGET_NEXR) && (!TARGET_H8300SX && TARGET_NEXR))
    {
-      warning (OPT_mno_exr, "-mno-exr valid only with -ms or -msx    \
-               - Option ignored!");
+      warning (OPT_mno_exr, "%<-mno-exr%> valid only with %<-ms%> or "
+              "%<-msx%> - Option ignored!");
    }
 
+#ifdef H8300_LINUX 
+ if ((TARGET_NORMAL_MODE))
+   {
+      error ("%<-mn%> is not supported for linux targets");
+      target_flags ^= MASK_NORMAL_MODE;
+   }
+#endif
+
   /* Some of the shifts are optimized for speed by default.
      See http://gcc.gnu.org/ml/gcc-patches/2002-07/msg01858.html
      If optimizing for size, change shift_alg for those shift to
@@ -470,7 +485,8 @@ byte_reg (rtx x, int b)
    && ! TREE_THIS_VOLATILE (current_function_decl)                     \
    && (h8300_saveall_function_p (current_function_decl)                        \
        /* Save any call saved register that was used.  */              \
-       || (df_regs_ever_live_p (regno) && !call_used_regs[regno])      \
+       || (df_regs_ever_live_p (regno)                                 \
+          && !call_used_or_fixed_reg_p (regno))                        \
        /* Save the frame pointer if it was used.  */                   \
        || (regno == HARD_FRAME_POINTER_REGNUM && df_regs_ever_live_p (regno)) \
        /* Save any register used in an interrupt handler.  */          \
@@ -479,12 +495,12 @@ byte_reg (rtx x, int b)
        /* Save call clobbered registers in non-leaf interrupt          \
          handlers.  */                                                 \
        || (h8300_current_function_interrupt_function_p ()              \
-          && call_used_regs[regno]                                     \
+          && call_used_or_fixed_reg_p (regno)                          \
           && !crtl->is_leaf)))
 
 /* We use this to wrap all emitted insns in the prologue.  */
-static rtx
-F (rtx x, bool set_it)
+static rtx_insn *
+F (rtx_insn *x, bool set_it)
 {
   if (set_it)
     RTX_FRAME_RELATED_P (x) = 1;
@@ -504,7 +520,7 @@ Fpa (rtx par)
   int i;
 
   for (i = 0; i < len; i++)
-    F (XVECEXP (par, 0, i), true);
+    RTX_FRAME_RELATED_P (XVECEXP (par, 0, i)) = 1;
 
   return par;
 }
@@ -541,8 +557,9 @@ h8300_emit_stack_adjustment (int sign, HOST_WIDE_INT size, bool in_prologue)
         the splitter will do.  */
       if (Pmode == HImode)
        {
-         rtx x = emit_insn (gen_addhi3 (stack_pointer_rtx,
-                                        stack_pointer_rtx, GEN_INT (sign * size)));
+         rtx_insn *x = emit_insn (gen_addhi3 (stack_pointer_rtx,
+                                              stack_pointer_rtx,
+                                              GEN_INT (sign * size)));
          if (size < 4)
            F (x, in_prologue);
        }
@@ -587,7 +604,7 @@ compute_saved_regs (void)
 /* Emit an insn to push register RN.  */
 
 static rtx
-push (int rn)
+push (int rn, bool in_prologue)
 {
   rtx reg = gen_rtx_REG (word_mode, rn);
   rtx x;
@@ -598,7 +615,7 @@ push (int rn)
     x = gen_push_h8300hs_advanced (reg);
   else
     x = gen_push_h8300hs_normal (reg);
-  x = F (emit_insn (x), true);
+  x = F (emit_insn (x), in_prologue);
   add_reg_note (x, REG_INC, stack_pointer_rtx);
   return x;
 }
@@ -651,7 +668,7 @@ h8300_push_pop (int regno, int nregs, bool pop_p, bool return_p)
       if (pop_p)
        pop (regno);
       else
-       push (regno);
+       push (regno, false);
       return;
     }
 
@@ -687,13 +704,12 @@ h8300_push_pop (int regno, int nregs, bool pop_p, bool return_p)
          lhs = gen_rtx_MEM (SImode, plus_constant (Pmode, sp, (j + 1) * -4));
          rhs = gen_rtx_REG (SImode, regno + j);
        }
-      RTVEC_ELT (vec, i + j) = gen_rtx_SET (VOIDmode, lhs, rhs);
+      RTVEC_ELT (vec, i + j) = gen_rtx_SET (lhs, rhs);
     }
 
   /* Add the stack adjustment.  */
   offset = GEN_INT ((pop_p ? nregs : -nregs) * 4);
-  RTVEC_ELT (vec, i + j) = gen_rtx_SET (VOIDmode, sp,
-                                       gen_rtx_PLUS (Pmode, sp, offset));
+  RTVEC_ELT (vec, i + j) = gen_rtx_SET (sp, gen_rtx_PLUS (Pmode, sp, offset));
 
   x = gen_rtx_PARALLEL (VOIDmode, vec);
   if (!pop_p)
@@ -836,7 +852,7 @@ h8300_expand_prologue (void)
   if (frame_pointer_needed)
     {
       /* Push fp.  */
-      push (HARD_FRAME_POINTER_REGNUM);
+      push (HARD_FRAME_POINTER_REGNUM, true);
       F (emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx), true);
     }
 
@@ -850,15 +866,15 @@ h8300_expand_prologue (void)
          if (TARGET_H8300S)
            {
              /* See how many registers we can push at the same time.  */
-             if ((!TARGET_H8300SX || (regno & 3) == 0)
+             if ((TARGET_H8300SX || (regno & 3) == 0)
                  && ((saved_regs >> regno) & 0x0f) == 0x0f)
                n_regs = 4;
 
-             else if ((!TARGET_H8300SX || (regno & 3) == 0)
+             else if ((TARGET_H8300SX || (regno & 3) == 0)
                       && ((saved_regs >> regno) & 0x07) == 0x07)
                n_regs = 3;
 
-             else if ((!TARGET_H8300SX || (regno & 1) == 0)
+             else if ((TARGET_H8300SX || (regno & 1) == 0)
                       && ((saved_regs >> regno) & 0x03) == 0x03)
                n_regs = 2;
            }
@@ -869,6 +885,12 @@ h8300_expand_prologue (void)
 
   /* Leave room for locals.  */
   h8300_emit_stack_adjustment (-1, round_frame_size (get_frame_size ()), true);
+
+  if (flag_stack_usage_info)
+    current_function_static_stack_size
+      = round_frame_size (get_frame_size ())
+      + (__builtin_popcount (saved_regs) * UNITS_PER_WORD)
+      + (frame_pointer_needed ? UNITS_PER_WORD : 0);
 }
 
 /* Return nonzero if we can use "rts" for the function currently being
@@ -974,12 +996,12 @@ h8300_file_start (void)
 {
   default_file_start ();
 
-  if (TARGET_H8300H)
-    fputs (TARGET_NORMAL_MODE ? "\t.h8300hn\n" : "\t.h8300h\n", asm_out_file);
-  else if (TARGET_H8300SX)
+  if (TARGET_H8300SX)
     fputs (TARGET_NORMAL_MODE ? "\t.h8300sxn\n" : "\t.h8300sx\n", asm_out_file);
   else if (TARGET_H8300S)
     fputs (TARGET_NORMAL_MODE ? "\t.h8300sn\n" : "\t.h8300s\n", asm_out_file);
+  else if (TARGET_H8300H)
+    fputs (TARGET_NORMAL_MODE ? "\t.h8300hn\n" : "\t.h8300h\n", asm_out_file);
 }
 
 /* Output assembly language code for the end of file.  */
@@ -996,7 +1018,7 @@ h8300_file_end (void)
    instead of adds/subs.  */
 
 void
-split_adds_subs (enum machine_mode mode, rtx *operands)
+split_adds_subs (machine_mode mode, rtx *operands)
 {
   HOST_WIDE_INT val = INTVAL (operands[1]);
   rtx reg = operands[0];
@@ -1014,11 +1036,11 @@ split_adds_subs (enum machine_mode mode, rtx *operands)
 
   switch (mode)
     {
-    case HImode:
+    case E_HImode:
       gen_add = gen_addhi3;
       break;
 
-    case SImode:
+    case E_SImode:
       gen_add = gen_addsi3;
       break;
 
@@ -1060,17 +1082,16 @@ h8300_pr_saveall (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
   pragma_saveall = 1;
 }
 
-/* If the next function argument with MODE and TYPE is to be passed in
-   a register, return a reg RTX for the hard register in which to pass
-   the argument.  CUM represents the state after the last argument.
-   If the argument is to be pushed, NULL_RTX is returned.
+/* If the next function argument ARG is to be passed in a register, return
+   a reg RTX for the hard register in which to pass the argument.  CUM
+   represents the state after the last argument.  If the argument is to
+   be pushed, NULL_RTX is returned.
 
    On the H8/300 all normal args are pushed, unless -mquickcall in which
    case the first 3 arguments are passed in registers.  */
 
 static rtx
-h8300_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
-                   const_tree type, bool named)
+h8300_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
@@ -1098,7 +1119,7 @@ h8300_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
   int regpass = 0;
 
   /* Never pass unnamed arguments in registers.  */
-  if (!named)
+  if (!arg.named)
     return NULL_RTX;
 
   /* Pass 3 regs worth of data in regs when user asked on the command line.  */
@@ -1122,34 +1143,25 @@ h8300_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
 
   if (regpass)
     {
-      int size;
-
-      if (mode == BLKmode)
-       size = int_size_in_bytes (type);
-      else
-       size = GET_MODE_SIZE (mode);
-
+      int size = arg.promoted_size_in_bytes ();
       if (size + cum->nbytes <= regpass * UNITS_PER_WORD
          && cum->nbytes / UNITS_PER_WORD <= 3)
-       result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
+       result = gen_rtx_REG (arg.mode, cum->nbytes / UNITS_PER_WORD);
     }
 
   return result;
 }
 
-/* Update the data in CUM to advance over an argument
-   of mode MODE and data type TYPE.
-   (TYPE is null for libcalls where that information may not be available.)  */
+/* Update the data in CUM to advance over argument ARG.  */
 
 static void
-h8300_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
-                           const_tree type, bool named ATTRIBUTE_UNUSED)
+h8300_function_arg_advance (cumulative_args_t cum_v,
+                           const function_arg_info &arg)
 {
   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
 
-  cum->nbytes += (mode != BLKmode
-                 ? (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD
-                 : (int_size_in_bytes (type) + UNITS_PER_WORD - 1) & -UNITS_PER_WORD);
+  cum->nbytes += ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
+                 & -UNITS_PER_WORD);
 }
 
 \f
@@ -1160,7 +1172,7 @@ h8300_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
    shortcuts.  */
 
 static int
-h8300_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
+h8300_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
                          reg_class_t from, reg_class_t to)
 {
   if (from == MAC_REGS || to == MAC_REG)
@@ -1212,9 +1224,11 @@ h8300_shift_costs (rtx x)
 /* Worker function for TARGET_RTX_COSTS.  */
 
 static bool
-h8300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
-                int *total, bool speed)
+h8300_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
+                int opno ATTRIBUTE_UNUSED, int *total, bool speed)
 {
+  int code = GET_CODE (x);
+
   if (TARGET_H8300SX && outer_code == MEM)
     {
       /* Estimate the number of execution states needed to calculate
@@ -1244,7 +1258,7 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
            *total = 0;
            return true;
          }
-       if (-4 <= n || n <= 4)
+       if (n >= -4 && n <= 4)
          {
            switch ((int) n)
              {
@@ -1307,12 +1321,12 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
       if (TARGET_H8300SX)
        switch (GET_MODE (x))
          {
-         case QImode:
-         case HImode:
+         case E_QImode:
+         case E_HImode:
            *total = COSTS_N_INSNS (!speed ? 4 : 10);
            return false;
 
-         case SImode:
+         case E_SImode:
            *total = COSTS_N_INSNS (!speed ? 4 : 18);
            return false;
 
@@ -1326,12 +1340,12 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
       if (TARGET_H8300SX)
        switch (GET_MODE (x))
          {
-         case QImode:
-         case HImode:
+         case E_QImode:
+         case E_HImode:
            *total = COSTS_N_INSNS (2);
            return false;
 
-         case SImode:
+         case E_SImode:
            *total = COSTS_N_INSNS (5);
            return false;
 
@@ -1565,9 +1579,7 @@ h8300_print_operand (FILE *file, rtx x, int code)
        case CONST_DOUBLE:
          {
            long val;
-           REAL_VALUE_TYPE rv;
-           REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-           REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+           REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
            fprintf (file, "#%ld", ((val >> 16) & 0xffff));
            break;
          }
@@ -1595,9 +1607,7 @@ h8300_print_operand (FILE *file, rtx x, int code)
        case CONST_DOUBLE:
          {
            long val;
-           REAL_VALUE_TYPE rv;
-           REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-           REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+           REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
            fprintf (file, "#%ld", (val & 0xffff));
            break;
          }
@@ -1632,7 +1642,7 @@ h8300_print_operand (FILE *file, rtx x, int code)
        }
       break;
     case 'o':
-      h8300_print_operand_address (file, x);
+      h8300_print_operand_address (file, VOIDmode, x);
       break;
     case 's':
       if (GET_CODE (x) == CONST_INT)
@@ -1680,18 +1690,18 @@ h8300_print_operand (FILE *file, rtx x, int code)
        case REG:
          switch (GET_MODE (x))
            {
-           case QImode:
+           case E_QImode:
 #if 0 /* Is it asm ("mov.b %0,r2l", ...) */
              fprintf (file, "%s", byte_reg (x, 0));
 #else /* ... or is it asm ("mov.b %0l,r2l", ...) */
              fprintf (file, "%s", names_big[REGNO (x)]);
 #endif
              break;
-           case HImode:
+           case E_HImode:
              fprintf (file, "%s", names_big[REGNO (x)]);
              break;
-           case SImode:
-           case SFmode:
+           case E_SImode:
+           case E_SFmode:
              fprintf (file, "%s", names_extended[REGNO (x)]);
              break;
            default:
@@ -1704,7 +1714,7 @@ h8300_print_operand (FILE *file, rtx x, int code)
            rtx addr = XEXP (x, 0);
 
            fprintf (file, "@");
-           output_address (addr);
+           output_address (GET_MODE (x), addr);
 
            /* Add a length suffix to constant addresses.  Although this
               is often unnecessary, it helps to avoid ambiguity in the
@@ -1725,10 +1735,12 @@ h8300_print_operand (FILE *file, rtx x, int code)
                      break;
                    }
 
-                 /* Fall through.  We should not get here if we are
-                    processing bit operations on H8/300 or H8/300H
-                    because 'U' constraint does not allow bit
-                    operations on the tiny area on these machines.  */
+                 /* FALLTHRU */
+
+                 /* We should not get here if we are processing bit
+                    operations on H8/300 or H8/300H because 'U'
+                    constraint does not allow bit operations on the
+                    tiny area on these machines.  */
 
                case 'X':
                case 'T':
@@ -1749,14 +1761,12 @@ h8300_print_operand (FILE *file, rtx x, int code)
        case CONST:
        case LABEL_REF:
          fprintf (file, "#");
-         h8300_print_operand_address (file, x);
+         h8300_print_operand_address (file, VOIDmode, x);
          break;
        case CONST_DOUBLE:
          {
            long val;
-           REAL_VALUE_TYPE rv;
-           REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
-           REAL_VALUE_TO_TARGET_SINGLE (rv, val);
+           REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
            fprintf (file, "#%ld", val);
            break;
          }
@@ -1777,7 +1787,7 @@ h8300_print_operand_punct_valid_p (unsigned char code)
 /* Output assembly language output for the address ADDR to FILE.  */
 
 static void
-h8300_print_operand_address (FILE *file, rtx addr)
+h8300_print_operand_address (FILE *file, machine_mode mode, rtx addr)
 {
   rtx index;
   int size;
@@ -1811,12 +1821,12 @@ h8300_print_operand_address (FILE *file, rtx addr)
       if (GET_CODE (index) == REG)
        {
          /* reg,foo */
-         h8300_print_operand_address (file, XEXP (addr, 1));
+         h8300_print_operand_address (file, mode, XEXP (addr, 1));
          fprintf (file, ",");
          switch (size)
            {
            case 0:
-             h8300_print_operand_address (file, index);
+             h8300_print_operand_address (file, mode, index);
              break;
 
            case 1:
@@ -1839,9 +1849,9 @@ h8300_print_operand_address (FILE *file, rtx addr)
       else
        {
          /* foo+k */
-         h8300_print_operand_address (file, XEXP (addr, 0));
+         h8300_print_operand_address (file, mode, XEXP (addr, 0));
          fprintf (file, "+");
-         h8300_print_operand_address (file, XEXP (addr, 1));
+         h8300_print_operand_address (file, mode, XEXP (addr, 1));
        }
       fprintf (file, ")");
       break;
@@ -1872,7 +1882,7 @@ h8300_print_operand_address (FILE *file, rtx addr)
    option.  */
 
 void
-final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
+final_prescan_insn (rtx_insn *insn, rtx *operand ATTRIBUTE_UNUSED,
                    int num_operands ATTRIBUTE_UNUSED)
 {
   /* This holds the last insn address.  */
@@ -2018,7 +2028,7 @@ h8300_return_addr_rtx (int count, rtx frame)
 /* Update the condition code from the insn.  */
 
 void
-notice_update_cc (rtx body, rtx insn)
+notice_update_cc (rtx body, rtx_insn *insn)
 {
   rtx set;
 
@@ -2099,7 +2109,7 @@ notice_update_cc (rtx body, rtx insn)
    if the address is known to be valid, but its mode is unknown.  */
 
 static rtx
-h8300_get_index (rtx x, enum machine_mode mode, int *size)
+h8300_get_index (rtx x, machine_mode mode, int *size)
 {
   int dummy, factor;
 
@@ -2436,7 +2446,7 @@ h8300_bitfield_length (rtx op, rtx op2)
 /* Calculate the length of general binary instruction INSN using TABLE.  */
 
 static unsigned int
-h8300_binary_length (rtx insn, const h8300_length_table *table)
+h8300_binary_length (rtx_insn *insn, const h8300_length_table *table)
 {
   rtx set;
 
@@ -2525,21 +2535,21 @@ h8300_mova_length (rtx dest, rtx src, rtx offset)
    OPERANDS is the array of its operands.  */
 
 unsigned int
-h8300_insn_length_from_table (rtx insn, rtx * operands)
+h8300_insn_length_from_table (rtx_insn *insn, rtx * operands)
 {
   switch (get_attr_length_table (insn))
     {
     case LENGTH_TABLE_NONE:
       gcc_unreachable ();
 
-    case LENGTH_TABLE_ADDB:
-      return h8300_binary_length (insn, &addb_length_table);
-
-    case LENGTH_TABLE_ADDW:
-      return h8300_binary_length (insn, &addw_length_table);
-
-    case LENGTH_TABLE_ADDL:
-      return h8300_binary_length (insn, &addl_length_table);
+    case LENGTH_TABLE_ADD:
+      if (GET_MODE (operands[0]) == QImode)
+        return h8300_binary_length (insn, &addb_length_table);
+      else if (GET_MODE (operands[0]) == HImode)
+        return h8300_binary_length (insn, &addw_length_table);
+      else if (GET_MODE (operands[0]) == SImode)
+        return h8300_binary_length (insn, &addl_length_table);
+      gcc_unreachable ();
 
     case LENGTH_TABLE_LOGICB:
       return h8300_binary_length (insn, &logicb_length_table);
@@ -2725,14 +2735,14 @@ h8sx_emit_movmd (rtx dest, rtx src, rtx length,
 void
 h8300_swap_into_er6 (rtx addr)
 {
-  rtx insn = push (HARD_FRAME_POINTER_REGNUM);
+  rtx insn = push (HARD_FRAME_POINTER_REGNUM, false);
   if (frame_pointer_needed)
     add_reg_note (insn, REG_CFA_DEF_CFA,
                  plus_constant (Pmode, gen_rtx_MEM (Pmode, stack_pointer_rtx),
                                 2 * UNITS_PER_WORD));
   else
     add_reg_note (insn, REG_CFA_ADJUST_CFA,
-                 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+                 gen_rtx_SET (stack_pointer_rtx,
                               plus_constant (Pmode, stack_pointer_rtx, 4)));
 
   emit_move_insn (hard_frame_pointer_rtx, addr);
@@ -2754,14 +2764,13 @@ h8300_swap_out_of_er6 (rtx addr)
     emit_move_insn (addr, hard_frame_pointer_rtx);
 
   insn = pop (HARD_FRAME_POINTER_REGNUM);
-  RTX_FRAME_RELATED_P (insn) = 1;
   if (frame_pointer_needed)
     add_reg_note (insn, REG_CFA_DEF_CFA,
                  plus_constant (Pmode, hard_frame_pointer_rtx,
                                 2 * UNITS_PER_WORD));
   else
     add_reg_note (insn, REG_CFA_ADJUST_CFA,
-                 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+                 gen_rtx_SET (stack_pointer_rtx,
                               plus_constant (Pmode, stack_pointer_rtx, -4)));
 }
 \f
@@ -2774,7 +2783,7 @@ compute_mov_length (rtx *operands)
      length, assuming the largest addressing mode is used, and then
      adjust later in the function.  Otherwise, we compute and return
      the exact length in one step.  */
-  enum machine_mode mode = GET_MODE (operands[0]);
+  machine_mode mode = GET_MODE (operands[0]);
   rtx dest = operands[0];
   rtx src = operands[1];
   rtx addr;
@@ -2792,7 +2801,7 @@ compute_mov_length (rtx *operands)
 
       switch (mode)
        {
-       case QImode:
+       case E_QImode:
          if (addr == NULL_RTX)
            return 2;
 
@@ -2804,7 +2813,7 @@ compute_mov_length (rtx *operands)
          base_length = 4;
          break;
 
-       case HImode:
+       case E_HImode:
          if (addr == NULL_RTX)
            {
              if (REG_P (src))
@@ -2819,7 +2828,7 @@ compute_mov_length (rtx *operands)
          base_length = 4;
          break;
 
-       case SImode:
+       case E_SImode:
          if (addr == NULL_RTX)
            {
              if (REG_P (src))
@@ -2846,7 +2855,7 @@ compute_mov_length (rtx *operands)
          base_length = 8;
          break;
 
-       case SFmode:
+       case E_SFmode:
          if (addr == NULL_RTX)
            {
              if (REG_P (src))
@@ -2898,7 +2907,7 @@ compute_mov_length (rtx *operands)
 
       switch (mode)
        {
-       case QImode:
+       case E_QImode:
          if (addr == NULL_RTX)
            return 2;
 
@@ -2910,7 +2919,7 @@ compute_mov_length (rtx *operands)
          base_length = 8;
          break;
 
-       case HImode:
+       case E_HImode:
          if (addr == NULL_RTX)
            {
              if (REG_P (src))
@@ -2925,7 +2934,7 @@ compute_mov_length (rtx *operands)
          base_length = 8;
          break;
 
-       case SImode:
+       case E_SImode:
          if (addr == NULL_RTX)
            {
              if (REG_P (src))
@@ -2966,7 +2975,7 @@ compute_mov_length (rtx *operands)
          base_length = 10;
          break;
 
-       case SFmode:
+       case E_SFmode:
          if (addr == NULL_RTX)
            {
              if (REG_P (src))
@@ -3024,7 +3033,7 @@ compute_mov_length (rtx *operands)
 const char *
 output_plussi (rtx *operands)
 {
-  enum machine_mode mode = GET_MODE (operands[0]);
+  machine_mode mode = GET_MODE (operands[0]);
 
   gcc_assert (mode == SImode);
 
@@ -3108,7 +3117,7 @@ output_plussi (rtx *operands)
 unsigned int
 compute_plussi_length (rtx *operands)
 {
-  enum machine_mode mode = GET_MODE (operands[0]);
+  machine_mode mode = GET_MODE (operands[0]);
 
   gcc_assert (mode == SImode);
 
@@ -3187,7 +3196,7 @@ compute_plussi_length (rtx *operands)
 enum attr_cc
 compute_plussi_cc (rtx *operands)
 {
-  enum machine_mode mode = GET_MODE (operands[0]);
+  machine_mode mode = GET_MODE (operands[0]);
 
   gcc_assert (mode == SImode);
 
@@ -3242,7 +3251,7 @@ compute_plussi_cc (rtx *operands)
 /* Output a logical insn.  */
 
 const char *
-output_logical_op (enum machine_mode mode, rtx *operands)
+output_logical_op (machine_mode mode, rtx *operands)
 {
   /* Figure out the logical op that we need to perform.  */
   enum rtx_code code = GET_CODE (operands[3]);
@@ -3288,7 +3297,7 @@ output_logical_op (enum machine_mode mode, rtx *operands)
 
   switch (mode)
     {
-    case HImode:
+    case E_HImode:
       /* First, see if we can finish with one insn.  */
       if ((TARGET_H8300H || TARGET_H8300S)
          && b0 != 0
@@ -3313,7 +3322,7 @@ output_logical_op (enum machine_mode mode, rtx *operands)
            }
        }
       break;
-    case SImode:
+    case E_SImode:
       if (TARGET_H8300H || TARGET_H8300S)
        {
          /* Determine if the lower half can be taken care of in no more
@@ -3423,7 +3432,7 @@ output_logical_op (enum machine_mode mode, rtx *operands)
 /* Compute the length of a logical insn.  */
 
 unsigned int
-compute_logical_op_length (enum machine_mode mode, rtx *operands)
+compute_logical_op_length (machine_mode mode, rtx *operands)
 {
   /* Figure out the logical op that we need to perform.  */
   enum rtx_code code = GET_CODE (operands[3]);
@@ -3453,7 +3462,7 @@ compute_logical_op_length (enum machine_mode mode, rtx *operands)
 
   switch (mode)
     {
-    case HImode:
+    case E_HImode:
       /* First, see if we can finish with one insn.  */
       if ((TARGET_H8300H || TARGET_H8300S)
          && b0 != 0
@@ -3473,7 +3482,7 @@ compute_logical_op_length (enum machine_mode mode, rtx *operands)
            length += 2;
        }
       break;
-    case SImode:
+    case E_SImode:
       if (TARGET_H8300H || TARGET_H8300S)
        {
          /* Determine if the lower half can be taken care of in no more
@@ -3569,7 +3578,7 @@ compute_logical_op_length (enum machine_mode mode, rtx *operands)
 /* Compute which flag bits are valid after a logical insn.  */
 
 enum attr_cc
-compute_logical_op_cc (enum machine_mode mode, rtx *operands)
+compute_logical_op_cc (machine_mode mode, rtx *operands)
 {
   /* Figure out the logical op that we need to perform.  */
   enum rtx_code code = GET_CODE (operands[3]);
@@ -3597,7 +3606,7 @@ compute_logical_op_cc (enum machine_mode mode, rtx *operands)
 
   switch (mode)
     {
-    case HImode:
+    case E_HImode:
       /* First, see if we can finish with one insn.  */
       if ((TARGET_H8300H || TARGET_H8300S)
          && b0 != 0
@@ -3606,7 +3615,7 @@ compute_logical_op_cc (enum machine_mode mode, rtx *operands)
          cc = CC_SET_ZNV;
        }
       break;
-    case SImode:
+    case E_SImode:
       if (TARGET_H8300H || TARGET_H8300S)
        {
          /* Determine if the lower half can be taken care of in no more
@@ -3660,13 +3669,13 @@ h8300_expand_branch (rtx operands[])
   rtx tmp;
 
   tmp = gen_rtx_COMPARE (VOIDmode, op0, op1);
-  emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, tmp));
+  emit_insn (gen_rtx_SET (cc0_rtx, tmp));
 
   tmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
                              gen_rtx_LABEL_REF (VOIDmode, label),
                              pc_rtx);
-  emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
+  emit_jump_insn (gen_rtx_SET (pc_rtx, tmp));
 }
 
 
@@ -3682,10 +3691,10 @@ h8300_expand_store (rtx operands[])
   rtx tmp;
 
   tmp = gen_rtx_COMPARE (VOIDmode, op0, op1);
-  emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, tmp));
+  emit_insn (gen_rtx_SET (cc0_rtx, tmp));
 
   tmp = gen_rtx_fmt_ee (code, GET_MODE (dest), cc0_rtx, const0_rtx);
-  emit_insn (gen_rtx_SET (VOIDmode, dest, tmp));
+  emit_insn (gen_rtx_SET (dest, tmp));
 }
 \f
 /* Shifts.
@@ -3727,7 +3736,7 @@ h8300_expand_store (rtx operands[])
 /* Classify a shift with the given mode and code.  OP is the shift amount.  */
 
 enum h8sx_shift_type
-h8sx_classify_shift (enum machine_mode mode, enum rtx_code code, rtx op)
+h8sx_classify_shift (machine_mode mode, enum rtx_code code, rtx op)
 {
   if (!TARGET_H8300SX)
     return H8SX_SHIFT_NONE;
@@ -3819,7 +3828,7 @@ output_h8sx_shift (rtx *operands, int suffix, int optype)
 /* Emit code to do shifts.  */
 
 bool
-expand_a_shift (enum machine_mode mode, enum rtx_code code, rtx operands[])
+expand_a_shift (machine_mode mode, enum rtx_code code, rtx operands[])
 {
   switch (h8sx_classify_shift (mode, code, operands[2]))
     {
@@ -3842,7 +3851,7 @@ expand_a_shift (enum machine_mode mode, enum rtx_code code, rtx operands[])
   emit_insn (gen_rtx_PARALLEL
             (VOIDmode,
              gen_rtvec (2,
-                        gen_rtx_SET (VOIDmode, copy_rtx (operands[0]),
+                        gen_rtx_SET (copy_rtx (operands[0]),
                                      gen_rtx_fmt_ee (code, mode,
                                                      copy_rtx (operands[0]), operands[2])),
                         gen_rtx_CLOBBER (VOIDmode,
@@ -4063,10 +4072,10 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
   /* Find the target CPU.  */
   if (TARGET_H8300)
     cpu = H8_300;
-  else if (TARGET_H8300H)
-    cpu = H8_300H;
-  else
+  else if (TARGET_H8300S)
     cpu = H8_S;
+  else
+    cpu = H8_300H;
 
   /* Find the shift algorithm.  */
   info->alg = SHIFT_LOOP;
@@ -4153,7 +4162,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              goto end;
            }
        }
-      else if ((8 <= count && count <= 13)
+      else if ((count >= 8 && count <= 13)
               || (TARGET_H8300S && count == 14))
        {
          info->remainder = count - 8;
@@ -4233,7 +4242,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
       gcc_unreachable ();
 
     case SIshift:
-      if (TARGET_H8300 && 8 <= count && count <= 9)
+      if (TARGET_H8300 && count >= 8 && count <= 9)
        {
          info->remainder = count - 8;
 
@@ -4296,9 +4305,9 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              gcc_unreachable ();
            }
        }
-      else if ((TARGET_H8300 && 16 <= count && count <= 20)
-              || (TARGET_H8300H && 16 <= count && count <= 19)
-              || (TARGET_H8300S && 16 <= count && count <= 21))
+      else if ((TARGET_H8300 && count >= 16 && count <= 20)
+              || (TARGET_H8300H && count >= 16 && count <= 19)
+              || (TARGET_H8300S && count >= 16 && count <= 21))
        {
          info->remainder = count - 16;
 
@@ -4335,7 +4344,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              goto end;
            }
        }
-      else if (TARGET_H8300 && 24 <= count && count <= 28)
+      else if (TARGET_H8300 && count >= 24 && count <= 28)
        {
          info->remainder = count - 24;
 
@@ -4352,14 +4361,14 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
              info->cc_inline = CC_SET_ZNV;
              goto end;
            case SHIFT_ASHIFTRT:
-             info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0\n\tsubx\t%x0,%x0";
+             info->special = "mov.b\t%z0,%w0\n\tbld\t#7,%w0\n\tsubx\t%x0,%x0\n\tsubx\t%y0,%y0\n\tsubx\t%z0,%z0";
              info->shift1  = "shar.b\t%w0";
              info->cc_inline = CC_SET_ZNV;
              goto end;
            }
        }
       else if ((TARGET_H8300H && count == 24)
-              || (TARGET_H8300S && 24 <= count && count <= 25))
+              || (TARGET_H8300S && count >= 24 && count <= 25))
        {
          info->remainder = count - 24;
 
@@ -4498,7 +4507,7 @@ get_shift_alg (enum shift_type shift_type, enum shift_mode shift_mode,
    needed for some shift with COUNT and MODE.  Return 0 otherwise.  */
 
 int
-h8300_shift_needs_scratch_p (int count, enum machine_mode mode)
+h8300_shift_needs_scratch_p (int count, machine_mode mode)
 {
   enum h8_cpu cpu;
   int a, lr, ar;
@@ -4509,27 +4518,27 @@ h8300_shift_needs_scratch_p (int count, enum machine_mode mode)
   /* Find out the target CPU.  */
   if (TARGET_H8300)
     cpu = H8_300;
-  else if (TARGET_H8300H)
-    cpu = H8_300H;
-  else
+  else if (TARGET_H8300S)
     cpu = H8_S;
+  else
+    cpu = H8_300H;
 
   /* Find the shift algorithm.  */
   switch (mode)
     {
-    case QImode:
+    case E_QImode:
       a  = shift_alg_qi[cpu][SHIFT_ASHIFT][count];
       lr = shift_alg_qi[cpu][SHIFT_LSHIFTRT][count];
       ar = shift_alg_qi[cpu][SHIFT_ASHIFTRT][count];
       break;
 
-    case HImode:
+    case E_HImode:
       a  = shift_alg_hi[cpu][SHIFT_ASHIFT][count];
       lr = shift_alg_hi[cpu][SHIFT_LSHIFTRT][count];
       ar = shift_alg_hi[cpu][SHIFT_ASHIFTRT][count];
       break;
 
-    case SImode:
+    case E_SImode:
       a  = shift_alg_si[cpu][SHIFT_ASHIFT][count];
       lr = shift_alg_si[cpu][SHIFT_LSHIFTRT][count];
       ar = shift_alg_si[cpu][SHIFT_ASHIFTRT][count];
@@ -4551,7 +4560,7 @@ output_a_shift (rtx *operands)
 {
   static int loopend_lab;
   rtx shift = operands[3];
-  enum machine_mode mode = GET_MODE (shift);
+  machine_mode mode = GET_MODE (shift);
   enum rtx_code code = GET_CODE (shift);
   enum shift_type shift_type;
   enum shift_mode shift_mode;
@@ -4562,13 +4571,13 @@ output_a_shift (rtx *operands)
 
   switch (mode)
     {
-    case QImode:
+    case E_QImode:
       shift_mode = QIshift;
       break;
-    case HImode:
+    case E_HImode:
       shift_mode = HIshift;
       break;
-    case SImode:
+    case E_SImode:
       shift_mode = SIshift;
       break;
     default:
@@ -4654,11 +4663,11 @@ output_a_shift (rtx *operands)
        /* Now mask off the high bits.  */
        switch (mode)
          {
-         case QImode:
+         case E_QImode:
            sprintf (insn_buf, "and\t#%d,%%X0", mask);
            break;
 
-         case HImode:
+         case E_HImode:
            gcc_assert (TARGET_H8300H || TARGET_H8300S);
            sprintf (insn_buf, "and.w\t#%d,%%T0", mask);
            break;
@@ -4721,7 +4730,7 @@ unsigned int
 compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
 {
   rtx shift = operands[3];
-  enum machine_mode mode = GET_MODE (shift);
+  machine_mode mode = GET_MODE (shift);
   enum rtx_code code = GET_CODE (shift);
   enum shift_type shift_type;
   enum shift_mode shift_mode;
@@ -4730,13 +4739,13 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
 
   switch (mode)
     {
-    case QImode:
+    case E_QImode:
       shift_mode = QIshift;
       break;
-    case HImode:
+    case E_HImode:
       shift_mode = HIshift;
       break;
-    case SImode:
+    case E_SImode:
       shift_mode = SIshift;
       break;
     default:
@@ -4826,13 +4835,13 @@ compute_a_shift_length (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
            /* Now mask off the high bits.  */
            switch (mode)
              {
-             case QImode:
+             case E_QImode:
                wlength += 1;
                break;
-             case HImode:
+             case E_HImode:
                wlength += 2;
                break;
-             case SImode:
+             case E_SImode:
                gcc_assert (!TARGET_H8300);
                wlength += 3;
                break;
@@ -4869,7 +4878,7 @@ enum attr_cc
 compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
 {
   rtx shift = operands[3];
-  enum machine_mode mode = GET_MODE (shift);
+  machine_mode mode = GET_MODE (shift);
   enum rtx_code code = GET_CODE (shift);
   enum shift_type shift_type;
   enum shift_mode shift_mode;
@@ -4878,13 +4887,13 @@ compute_a_shift_cc (rtx insn ATTRIBUTE_UNUSED, rtx *operands)
   
   switch (mode)
     {
-    case QImode:
+    case E_QImode:
       shift_mode = QIshift;
       break;
-    case HImode:
+    case E_HImode:
       shift_mode = HIshift;
       break;
-    case SImode:
+    case E_SImode:
       shift_mode = SIshift;
       break;
     default:
@@ -4964,7 +4973,7 @@ expand_a_rotate (rtx operands[])
   rtx dst = operands[0];
   rtx src = operands[1];
   rtx rotate_amount = operands[2];
-  enum machine_mode mode = GET_MODE (dst);
+  machine_mode mode = GET_MODE (dst);
 
   if (h8sx_classify_shift (mode, ROTATE, rotate_amount) == H8SX_SHIFT_UNARY)
     return false;
@@ -4975,8 +4984,8 @@ expand_a_rotate (rtx operands[])
   if (GET_CODE (rotate_amount) != CONST_INT)
     {
       rtx counter = gen_reg_rtx (QImode);
-      rtx start_label = gen_label_rtx ();
-      rtx end_label = gen_label_rtx ();
+      rtx_code_label *start_label = gen_label_rtx ();
+      rtx_code_label *end_label = gen_label_rtx ();
 
       /* If the rotate amount is less than or equal to 0,
         we go out of the loop.  */
@@ -4991,13 +5000,13 @@ expand_a_rotate (rtx operands[])
       /* Rotate by one bit.  */
       switch (mode)
        {
-       case QImode:
+       case E_QImode:
          emit_insn (gen_rotlqi3_1 (dst, dst, const1_rtx));
          break;
-       case HImode:
+       case E_HImode:
          emit_insn (gen_rotlhi3_1 (dst, dst, const1_rtx));
          break;
-       case SImode:
+       case E_SImode:
          emit_insn (gen_rotlsi3_1 (dst, dst, const1_rtx));
          break;
        default:
@@ -5019,13 +5028,13 @@ expand_a_rotate (rtx operands[])
       /* Rotate by AMOUNT bits.  */
       switch (mode)
        {
-       case QImode:
+       case E_QImode:
          emit_insn (gen_rotlqi3_1 (dst, dst, rotate_amount));
          break;
-       case HImode:
+       case E_HImode:
          emit_insn (gen_rotlhi3_1 (dst, dst, rotate_amount));
          break;
-       case SImode:
+       case E_SImode:
          emit_insn (gen_rotlsi3_1 (dst, dst, rotate_amount));
          break;
        default:
@@ -5048,19 +5057,19 @@ output_a_rotate (enum rtx_code code, rtx *operands)
   const char *insn_buf;
   int bits;
   int amount;
-  enum machine_mode mode = GET_MODE (dst);
+  machine_mode mode = GET_MODE (dst);
 
   gcc_assert (GET_CODE (rotate_amount) == CONST_INT);
 
   switch (mode)
     {
-    case QImode:
+    case E_QImode:
       rotate_mode = QIshift;
       break;
-    case HImode:
+    case E_HImode:
       rotate_mode = HIshift;
       break;
-    case SImode:
+    case E_SImode:
       rotate_mode = SIshift;
       break;
     default:
@@ -5107,13 +5116,13 @@ output_a_rotate (enum rtx_code code, rtx *operands)
     {
       switch (mode)
        {
-       case HImode:
+       case E_HImode:
          /* This code works on any family.  */
          insn_buf = "xor.b\t%s0,%t0\n\txor.b\t%t0,%s0\n\txor.b\t%s0,%t0";
          output_asm_insn (insn_buf, operands);
          break;
 
-       case SImode:
+       case E_SImode:
          /* This code works on the H8/300H and H8S.  */
          insn_buf = "xor.w\t%e0,%f0\n\txor.w\t%f0,%e0\n\txor.w\t%e0,%f0";
          output_asm_insn (insn_buf, operands);
@@ -5151,7 +5160,7 @@ compute_a_rotate_length (rtx *operands)
 {
   rtx src = operands[1];
   rtx amount_rtx = operands[2];
-  enum machine_mode mode = GET_MODE (src);
+  machine_mode mode = GET_MODE (src);
   int amount;
   unsigned int length = 0;
 
@@ -5408,23 +5417,23 @@ h8300_insert_attributes (tree node, tree *attributes)
 
 static const struct attribute_spec h8300_attribute_table[] =
 {
-  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
-       affects_type_identity } */
-  { "interrupt_handler", 0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false },
-  { "saveall",           0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false },
-  { "OS_Task",           0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false },
-  { "monitor",           0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false },
-  { "function_vector",   0, 0, true,  false, false,
-    h8300_handle_fndecl_attribute, false },
-  { "eightbit_data",     0, 0, true,  false, false,
-    h8300_handle_eightbit_data_attribute, false },
-  { "tiny_data",         0, 0, true,  false, false,
-    h8300_handle_tiny_data_attribute, false },
-  { NULL,                0, 0, false, false, false, NULL, false }
+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+       affects_type_identity, handler, exclude } */
+  { "interrupt_handler", 0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "saveall",           0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "OS_Task",           0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "monitor",           0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "function_vector",   0, 0, true,  false, false, false,
+    h8300_handle_fndecl_attribute, NULL },
+  { "eightbit_data",     0, 0, true,  false, false, false,
+    h8300_handle_eightbit_data_attribute, NULL },
+  { "tiny_data",         0, 0, true,  false, false, false,
+    h8300_handle_tiny_data_attribute, NULL },
+  { NULL,                0, 0, false, false, false, false, NULL, NULL }
 };
 
 
@@ -5458,7 +5467,7 @@ h8300_handle_eightbit_data_attribute (tree *node, tree name,
 
   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
     {
-      DECL_SECTION_NAME (decl) = build_string (7, ".eight");
+      set_decl_section_name (decl, ".eight");
     }
   else
     {
@@ -5482,7 +5491,7 @@ h8300_handle_tiny_data_attribute (tree *node, tree name,
 
   if (TREE_STATIC (decl) || DECL_EXTERNAL (decl))
     {
-      DECL_SECTION_NAME (decl) = build_string (6, ".tiny");
+      set_decl_section_name (decl, ".tiny");
     }
   else
     {
@@ -5605,6 +5614,12 @@ h8300_eightbit_constant_address_p (rtx x)
   if (GET_CODE (x) == SYMBOL_REF)
     return (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0;
 
+  if (GET_CODE (x) == CONST
+      && GET_CODE (XEXP (x, 0)) == PLUS
+      && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
+      && (SYMBOL_REF_FLAGS (XEXP (XEXP (x, 0), 0)) & SYMBOL_FLAG_EIGHTBIT_DATA) != 0)
+    return 1;
+
   if (GET_CODE (x) != CONST_INT)
     return 0;
 
@@ -5712,16 +5727,16 @@ byte_accesses_mergeable_p (rtx addr1, rtx addr2)
    before I3.  I3 is assumed to be a comparison insn.  */
 
 int
-same_cmp_preceding_p (rtx i3)
+same_cmp_preceding_p (rtx_insn *i3)
 {
-  rtx i1, i2;
+  rtx_insn *i1, *i2;
 
   /* Make sure we have a sequence of three insns.  */
   i2 = prev_nonnote_insn (i3);
-  if (i2 == NULL_RTX)
+  if (i2 == NULL)
     return 0;
   i1 = prev_nonnote_insn (i2);
-  if (i1 == NULL_RTX)
+  if (i1 == NULL)
     return 0;
 
   return (INSN_P (i1) && rtx_equal_p (PATTERN (i1), PATTERN (i3))
@@ -5732,16 +5747,16 @@ same_cmp_preceding_p (rtx i3)
    after I1.  I1 is assumed to be a comparison insn.  */
 
 int
-same_cmp_following_p (rtx i1)
+same_cmp_following_p (rtx_insn *i1)
 {
-  rtx i2, i3;
+  rtx_insn *i2, *i3;
 
   /* Make sure we have a sequence of three insns.  */
   i2 = next_nonnote_insn (i1);
-  if (i2 == NULL_RTX)
+  if (i2 == NULL)
     return 0;
   i3 = next_nonnote_insn (i2);
-  if (i3 == NULL_RTX)
+  if (i3 == NULL)
     return 0;
 
   return (INSN_P (i3) && rtx_equal_p (PATTERN (i1), PATTERN (i3))
@@ -5830,7 +5845,7 @@ h8300_rtx_ok_for_base_p (rtx x, int strict)
    CONSTANT_ADDRESS.  */
 
 static bool
-h8300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
+h8300_legitimate_address_p (machine_mode mode, rtx x, bool strict)
 {
   /* The register indirect addresses like @er0 is always valid.  */
   if (h8300_rtx_ok_for_base_p (x, strict))
@@ -5856,21 +5871,10 @@ h8300_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
   return 0;
 }
 
-/* Worker function for HARD_REGNO_NREGS.
-
-   We pretend the MAC register is 32bits -- we don't have any data
-   types on the H8 series to handle more than 32bits.  */
-
-int
-h8300_hard_regno_nregs (int regno ATTRIBUTE_UNUSED, enum machine_mode mode)
-{
-  return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
-}
-
-/* Worker function for HARD_REGNO_MODE_OK.  */
+/* Implement TARGET_HARD_REGNO_MODE_OK.  */
 
-int
-h8300_hard_regno_mode_ok (int regno, enum machine_mode mode)
+static bool
+h8300_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
 {
   if (TARGET_H8300)
     /* If an even reg, then anything goes.  Otherwise the mode must be
@@ -5882,6 +5886,20 @@ h8300_hard_regno_mode_ok (int regno, enum machine_mode mode)
     return regno == MAC_REG ? mode == SImode : 1;
 }
 
+/* Implement TARGET_MODES_TIEABLE_P.  */
+
+static bool
+h8300_modes_tieable_p (machine_mode mode1, machine_mode mode2)
+{
+  return (mode1 == mode2
+         || ((mode1 == QImode
+              || mode1 == HImode
+              || ((TARGET_H8300H || TARGET_H8300S) && mode1 == SImode))
+             && (mode2 == QImode
+                 || mode2 == HImode
+                 || ((TARGET_H8300H || TARGET_H8300S) && mode2 == SImode))));
+}
+
 /* Helper function for the move patterns.  Make sure a move is legitimate.  */
 
 bool
@@ -5944,7 +5962,7 @@ h8300_function_value (const_tree ret_type,
    On the H8 the return value is in R0/R1.  */
 
 static rtx
-h8300_libcall_value (enum machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
+h8300_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
 {
   return gen_rtx_REG (mode, R0_REG);
 }
@@ -6017,6 +6035,21 @@ h8300_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
       emit_move_insn (mem, tem);
     }
 }
+
+/* Implement PUSH_ROUNDING.
+
+   On the H8/300, @-sp really pushes a byte if you ask it to - but that's
+   dangerous, so we claim that it always pushes a word, then we catch
+   the mov.b rx,@-sp and turn it into a mov.w rx,@-sp on output.
+
+   On the H8/300H, we simplify TARGET_QUICKCALL by setting this to 4
+   and doing a similar thing.  */
+
+poly_int64
+h8300_push_rounding (poly_int64 bytes)
+{
+  return ((bytes + PARM_BOUNDARY / 8 - 1) & (-PARM_BOUNDARY / 8));
+}
 \f
 /* Initialize the GCC target structure.  */
 #undef TARGET_ATTRIBUTE_TABLE
@@ -6079,6 +6112,15 @@ h8300_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
 #undef TARGET_HARD_REGNO_SCRATCH_OK
 #define TARGET_HARD_REGNO_SCRATCH_OK h8300_hard_regno_scratch_ok
 
+#undef TARGET_HARD_REGNO_MODE_OK
+#define TARGET_HARD_REGNO_MODE_OK h8300_hard_regno_mode_ok
+
+#undef TARGET_MODES_TIEABLE_P
+#define TARGET_MODES_TIEABLE_P h8300_modes_tieable_p
+
+#undef TARGET_LRA_P
+#define TARGET_LRA_P hook_bool_void_false
+
 #undef TARGET_LEGITIMATE_ADDRESS_P
 #define TARGET_LEGITIMATE_ADDRESS_P    h8300_legitimate_address_p
 
@@ -6097,4 +6139,7 @@ h8300_trampoline_init (rtx m_tramp, tree fndecl, rtx cxt)
 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
 #define TARGET_MODE_DEPENDENT_ADDRESS_P h8300_mode_dependent_address_p
 
+#undef TARGET_HAVE_SPECULATION_SAFE_VALUE
+#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
+
 struct gcc_target targetm = TARGET_INITIALIZER;