move many gc hashtab to hash_table
[platform/upstream/gcc.git] / gcc / config / mips / mips.c
index 83fe55b..af72da5 100644 (file)
@@ -54,7 +54,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "common/common-target.h"
 #include "langhooks.h"
 #include "sched-int.h"
-#include "pointer-set.h"
 #include "vec.h"
 #include "basic-block.h"
 #include "tree-ssa-alias.h"
@@ -71,6 +70,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "opts.h"
 #include "tree-pass.h"
 #include "context.h"
+#include "cgraph.h"
+#include "builtins.h"
 
 /* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF.  */
 #define UNSPEC_ADDRESS_P(X)                                    \
@@ -122,13 +123,15 @@ along with GCC; see the file COPYING3.  If not see
    in the sequence, otherwise return INSN itself.  */
 #define SEQ_BEGIN(INSN)                                                        \
   (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE              \
-   ? XVECEXP (PATTERN (INSN), 0, 0)                                    \
+   ? as_a <rtx_insn *> (XVECEXP (PATTERN (INSN), 0, 0))                        \
    : (INSN))
 
 /* Likewise for the last instruction in a delayed branch sequence.  */
 #define SEQ_END(INSN)                                                  \
   (INSN_P (INSN) && GET_CODE (PATTERN (INSN)) == SEQUENCE              \
-   ? XVECEXP (PATTERN (INSN), 0, XVECLEN (PATTERN (INSN), 0) - 1)      \
+   ? as_a <rtx_insn *> (XVECEXP (PATTERN (INSN),                       \
+                                0,                                     \
+                                XVECLEN (PATTERN (INSN), 0) - 1))      \
    : (INSN))
 
 /* Execute the following loop body with SUBINSN set to each instruction
@@ -585,6 +588,10 @@ const struct mips_cpu_info *mips_tune_info;
 /* The ISA level associated with mips_arch.  */
 int mips_isa;
 
+/* The ISA revision level.  This is 0 for MIPS I to V and N for
+   MIPS{32,64}rN.  */
+int mips_isa_rev;
+
 /* The architecture selected by -mipsN, or null if -mipsN wasn't used.  */
 static const struct mips_cpu_info *mips_isa_option_info;
 
@@ -655,7 +662,7 @@ const enum reg_class mips_regno_to_class[FIRST_PSEUDO_REGISTER] = {
   M16_REGS,        M16_STORE_REGS,  LEA_REGS,        LEA_REGS,
   LEA_REGS,        LEA_REGS,        LEA_REGS,        LEA_REGS,
   T_REG,           PIC_FN_ADDR_REG, LEA_REGS,        LEA_REGS,
-  LEA_REGS,        LEA_REGS,        LEA_REGS,        LEA_REGS,
+  LEA_REGS,        M16_SP_REGS,     LEA_REGS,        LEA_REGS,
 
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
   FP_REGS,     FP_REGS,        FP_REGS,        FP_REGS,
@@ -1174,36 +1181,41 @@ static const struct mips_rtx_cost_data
     COSTS_N_INSNS (68),           /* int_div_di */
                     1,           /* branch_cost */
                     4            /* memory_latency */
+  },
+  { /* P5600 */
+    COSTS_N_INSNS (4),            /* fp_add */
+    COSTS_N_INSNS (5),            /* fp_mult_sf */
+    COSTS_N_INSNS (5),            /* fp_mult_df */
+    COSTS_N_INSNS (17),           /* fp_div_sf */
+    COSTS_N_INSNS (17),           /* fp_div_df */
+    COSTS_N_INSNS (5),            /* int_mult_si */
+    COSTS_N_INSNS (5),            /* int_mult_di */
+    COSTS_N_INSNS (8),            /* int_div_si */
+    COSTS_N_INSNS (8),            /* int_div_di */
+                   2,            /* branch_cost */
+                  10             /* memory_latency */
   }
 };
 \f
-static rtx mips_find_pic_call_symbol (rtx, rtx, bool);
+static rtx mips_find_pic_call_symbol (rtx_insn *, rtx, bool);
 static int mips_register_move_cost (enum machine_mode, reg_class_t,
                                    reg_class_t);
 static unsigned int mips_function_arg_boundary (enum machine_mode, const_tree);
 \f
-/* This hash table keeps track of implicit "mips16" and "nomips16" attributes
-   for -mflip_mips16.  It maps decl names onto a boolean mode setting.  */
-struct GTY (())  mflip_mips16_entry {
-  const char *name;
-  bool mips16_p;
-};
-static GTY ((param_is (struct mflip_mips16_entry))) htab_t mflip_mips16_htab;
-
-/* Hash table callbacks for mflip_mips16_htab.  */
-
-static hashval_t
-mflip_mips16_htab_hash (const void *entry)
+struct mips16_flip_traits : default_hashmap_traits
 {
-  return htab_hash_string (((const struct mflip_mips16_entry *) entry)->name);
-}
+  static hashval_t hash (const char *s) { return htab_hash_string (s); }
+  static bool
+  equal_keys (const char *a, const char *b)
+  {
+    return !strcmp (a, b);
+  }
+};
 
-static int
-mflip_mips16_htab_eq (const void *entry, const void *name)
-{
-  return strcmp (((const struct mflip_mips16_entry *) entry)->name,
-                (const char *) name) == 0;
-}
+/* This hash table keeps track of implicit "mips16" and "nomips16" attributes
+   for -mflip_mips16.  It maps decl names onto a boolean mode setting.  */
+static GTY (()) hash_map<const char *, bool, mips16_flip_traits> *
+  mflip_mips16_htab;
 
 /* True if -mflip-mips16 should next add an attribute for the default MIPS16
    mode, false if it should next add an attribute for the opposite mode.  */
@@ -1216,10 +1228,7 @@ static GTY(()) bool mips16_flipper;
 static bool
 mflip_mips16_use_mips16_p (tree decl)
 {
-  struct mflip_mips16_entry *entry;
   const char *name;
-  hashval_t hash;
-  void **slot;
   bool base_is_mips16 = (mips_base_compression_flags & MASK_MIPS16) != 0;
 
   /* Use the opposite of the command-line setting for anonymous decls.  */
@@ -1227,22 +1236,19 @@ mflip_mips16_use_mips16_p (tree decl)
     return !base_is_mips16;
 
   if (!mflip_mips16_htab)
-    mflip_mips16_htab = htab_create_ggc (37, mflip_mips16_htab_hash,
-                                        mflip_mips16_htab_eq, NULL);
+    mflip_mips16_htab
+      = hash_map<const char *, bool, mips16_flip_traits>::create_ggc (37);
 
   name = IDENTIFIER_POINTER (DECL_NAME (decl));
-  hash = htab_hash_string (name);
-  slot = htab_find_slot_with_hash (mflip_mips16_htab, name, hash, INSERT);
-  entry = (struct mflip_mips16_entry *) *slot;
-  if (!entry)
+
+  bool existed;
+  bool *slot = &mflip_mips16_htab->get_or_insert (name, &existed);
+  if (!existed)
     {
       mips16_flipper = !mips16_flipper;
-      entry = ggc_alloc_mflip_mips16_entry ();
-      entry->name = name;
-      entry->mips16_p = mips16_flipper ? !base_is_mips16 : base_is_mips16;
-      *slot = entry;
+      *slot = mips16_flipper ? !base_is_mips16 : base_is_mips16;
     }
-  return entry->mips16_p;
+  return *slot;
 }
 \f
 /* Predicates to test for presence of "near" and "far"/"long_call"
@@ -2152,15 +2158,6 @@ mips_symbol_insns (enum mips_symbol_type type, enum machine_mode mode)
   return mips_symbol_insns_1 (type, mode) * (TARGET_MIPS16 ? 2 : 1);
 }
 \f
-/* A for_each_rtx callback.  Stop the search if *X references a
-   thread-local symbol.  */
-
-static int
-mips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
-{
-  return mips_tls_symbol_p (*x);
-}
-
 /* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */
 
 static bool
@@ -2204,7 +2201,7 @@ mips_cannot_force_const_mem (enum machine_mode mode, rtx x)
     }
 
   /* TLS symbols must be computed by mips_legitimize_move.  */
-  if (for_each_rtx (&x, &mips_tls_symbol_ref_1, NULL))
+  if (tls_referenced_p (x))
     return true;
 
   return false;
@@ -2241,22 +2238,9 @@ mips_regno_mode_ok_for_base_p (int regno, enum machine_mode mode,
     return true;
 
   /* In MIPS16 mode, the stack pointer can only address word and doubleword
-     values, nothing smaller.  There are two problems here:
-
-       (a) Instantiating virtual registers can introduce new uses of the
-          stack pointer.  If these virtual registers are valid addresses,
-          the stack pointer should be too.
-
-       (b) Most uses of the stack pointer are not made explicit until
-          FRAME_POINTER_REGNUM and ARG_POINTER_REGNUM have been eliminated.
-          We don't know until that stage whether we'll be eliminating to the
-          stack pointer (which needs the restriction) or the hard frame
-          pointer (which doesn't).
-
-     All in all, it seems more consistent to only enforce this restriction
-     during and after reload.  */
+     values, nothing smaller.  */
   if (TARGET_MIPS16 && regno == STACK_POINTER_REGNUM)
-    return !strict_p || GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
+    return GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8;
 
   return TARGET_MIPS16 ? M16_REG_P (regno) : GP_REG_P (regno);
 }
@@ -2680,7 +2664,7 @@ mips_split_const_insns (rtx x)
    BASE_INSN_LENGTH is the length of one instruction.  */
 
 int
-mips_load_store_insns (rtx mem, rtx insn)
+mips_load_store_insns (rtx mem, rtx_insn *insn)
 {
   enum machine_mode mode;
   bool might_split_p;
@@ -2729,7 +2713,7 @@ mips_idiv_insns (void)
    how to force Pmode objects into the constant pool even when the
    constant pool address is not itself legitimate.  */
 
-rtx
+rtx_insn *
 mips_emit_move (rtx dest, rtx src)
 {
   return (can_create_pseudo_p ()
@@ -2814,10 +2798,11 @@ mips_force_temporary (rtx dest, rtx value)
    ADDR is the legitimized form, and LAZY_P is true if the call
    address is lazily-bound.  */
 
-static rtx
+static rtx_insn *
 mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
 {
-  rtx insn, reg;
+  rtx_insn *insn;
+  rtx reg;
 
   insn = emit_call_insn (pattern);
 
@@ -2843,6 +2828,15 @@ mips_emit_call_insn (rtx pattern, rtx orig_addr, rtx addr, bool lazy_p)
               gen_rtx_REG (Pmode, GOT_VERSION_REGNUM));
       emit_insn (gen_update_got_version ());
     }
+
+  if (TARGET_MIPS16
+      && TARGET_EXPLICIT_RELOCS
+      && TARGET_CALL_CLOBBERED_GP)
+    {
+      rtx post_call_tmp_reg = gen_rtx_REG (word_mode, POST_CALL_TMP_REG);
+      clobber_reg (&CALL_INSN_FUNCTION_USAGE (insn), post_call_tmp_reg);
+    }
+
   return insn;
 }
 \f
@@ -2924,7 +2918,7 @@ mips16_gp_pseudo_reg (void)
 {
   if (cfun->machine->mips16_gp_pseudo_rtx == NULL_RTX)
     {
-      rtx insn, scan;
+      rtx_insn *scan;
 
       cfun->machine->mips16_gp_pseudo_rtx = gen_reg_rtx (Pmode);
 
@@ -2934,8 +2928,8 @@ mips16_gp_pseudo_reg (void)
       while (NEXT_INSN (scan) && !INSN_P (NEXT_INSN (scan)))
        scan = NEXT_INSN (scan);
 
-      insn = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx);
-      insn = emit_insn_after (insn, scan);
+      rtx set = gen_load_const_gp (cfun->machine->mips16_gp_pseudo_rtx);
+      rtx_insn *insn = emit_insn_after (set, scan);
       INSN_LOCATION (insn) = 0;
 
       pop_topmost_sequence ();
@@ -6271,7 +6265,7 @@ mips_start_unique_function (const char *name)
   TREE_PUBLIC (decl) = 1;
   TREE_STATIC (decl) = 1;
 
-  DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
+  cgraph_node::create (decl)->set_comdat_group (DECL_ASSEMBLER_NAME (decl));
 
   targetm.asm_out.unique_section (decl, 0);
   switch_to_section (get_named_section (decl, NULL, 0));
@@ -6383,34 +6377,29 @@ mips_load_call_address (enum mips_call_type type, rtx dest, rtx addr)
     }
 }
 \f
+struct local_alias_traits : default_hashmap_traits
+{
+  static hashval_t hash (rtx);
+  static bool equal_keys (rtx, rtx);
+};
+
 /* Each locally-defined hard-float MIPS16 function has a local symbol
    associated with it.  This hash table maps the function symbol (FUNC)
    to the local symbol (LOCAL). */
-struct GTY(()) mips16_local_alias {
-  rtx func;
-  rtx local;
-};
-static GTY ((param_is (struct mips16_local_alias))) htab_t mips16_local_aliases;
+static GTY (()) hash_map<rtx, rtx, local_alias_traits> *mips16_local_aliases;
 
 /* Hash table callbacks for mips16_local_aliases.  */
 
-static hashval_t
-mips16_local_aliases_hash (const void *entry)
+hashval_t
+local_alias_traits::hash (rtx func)
 {
-  const struct mips16_local_alias *alias;
-
-  alias = (const struct mips16_local_alias *) entry;
-  return htab_hash_string (XSTR (alias->func, 0));
+  return htab_hash_string (XSTR (func, 0));
 }
 
-static int
-mips16_local_aliases_eq (const void *entry1, const void *entry2)
+bool
+local_alias_traits::equal_keys (rtx func1, rtx func2)
 {
-  const struct mips16_local_alias *alias1, *alias2;
-
-  alias1 = (const struct mips16_local_alias *) entry1;
-  alias2 = (const struct mips16_local_alias *) entry2;
-  return rtx_equal_p (alias1->func, alias2->func);
+  return rtx_equal_p (func1, func2);
 }
 
 /* FUNC is the symbol for a locally-defined hard-float MIPS16 function.
@@ -6419,21 +6408,17 @@ mips16_local_aliases_eq (const void *entry1, const void *entry2)
 static rtx
 mips16_local_alias (rtx func)
 {
-  struct mips16_local_alias *alias, tmp_alias;
-  void **slot;
-
   /* Create the hash table if this is the first call.  */
   if (mips16_local_aliases == NULL)
-    mips16_local_aliases = htab_create_ggc (37, mips16_local_aliases_hash,
-                                           mips16_local_aliases_eq, NULL);
+    mips16_local_aliases
+      = hash_map<rtx, rtx, local_alias_traits>::create_ggc (37);
 
   /* Look up the function symbol, creating a new entry if need be.  */
-  tmp_alias.func = func;
-  slot = htab_find_slot (mips16_local_aliases, &tmp_alias, INSERT);
+  bool existed;
+  rtx *slot = &mips16_local_aliases->get_or_insert (func, &existed);
   gcc_assert (slot != NULL);
 
-  alias = (struct mips16_local_alias *) *slot;
-  if (alias == NULL)
+  if (!existed)
     {
       const char *func_name, *local_name;
       rtx local;
@@ -6447,12 +6432,9 @@ mips16_local_alias (rtx func)
       SYMBOL_REF_FLAGS (local) = SYMBOL_REF_FLAGS (func) | SYMBOL_FLAG_LOCAL;
 
       /* Create a new structure to represent the mapping.  */
-      alias = ggc_alloc_mips16_local_alias ();
-      alias->func = func;
-      alias->local = local;
-      *slot = alias;
+      *slot = local;
     }
-  return alias->local;
+  return *slot;
 }
 \f
 /* A chained list of functions for which mips16_build_call_stub has already
@@ -6590,7 +6572,7 @@ mips16_build_function_stub (void)
   stubdecl = build_decl (BUILTINS_LOCATION,
                         FUNCTION_DECL, get_identifier (stubname),
                         build_function_type_list (void_type_node, NULL_TREE));
-  DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
+  set_decl_section_name (stubdecl, secname);
   DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
                                       RESULT_DECL, NULL_TREE, void_type_node);
 
@@ -6716,18 +6698,19 @@ mips16_copy_fpr_return_value (void)
    automatically redirects the JAL to the stub, otherwise the JAL
    continues to call FN directly.  */
 
-static rtx
+static rtx_insn *
 mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
 {
   const char *fnname;
   bool fp_ret_p;
   struct mips16_stub *l;
-  rtx insn, fn;
+  rtx_insn *insn;
+  rtx pattern, fn;
 
   /* We don't need to do anything if we aren't in MIPS16 mode, or if
      we were invoked with the -msoft-float option.  */
   if (!TARGET_MIPS16 || TARGET_SOFT_FLOAT_ABI)
-    return NULL_RTX;
+    return NULL;
 
   /* Figure out whether the value might come back in a floating-point
      register.  */
@@ -6737,20 +6720,20 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
      arguments and the value will not be returned in a floating-point
      register.  */
   if (fp_code == 0 && !fp_ret_p)
-    return NULL_RTX;
+    return NULL;
 
   /* We don't need to do anything if this is a call to a special
      MIPS16 support function.  */
   fn = *fn_ptr;
   if (mips16_stub_function_p (fn))
-    return NULL_RTX;
+    return NULL;
 
   /* If we're calling a locally-defined MIPS16 function, we know that
      it will return values in both the "soft-float" and "hard-float"
      registers.  There is no need to use a stub to move the latter
      to the former.  */
   if (fp_code == 0 && mips16_local_function_p (fn))
-    return NULL_RTX;
+    return NULL;
 
   /* This code will only work for o32 and o64 abis.  The other ABI's
      require more sophisticated support.  */
@@ -6763,7 +6746,8 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
       || !call_insn_operand (fn, VOIDmode))
     {
       char buf[30];
-      rtx stub_fn, insn, addr;
+      rtx stub_fn, addr;
+      rtx_insn *insn;
       bool lazy_p;
 
       /* If this is a locally-defined and locally-binding function,
@@ -6771,7 +6755,7 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
       if (mips16_local_function_p (fn))
        {
          *fn_ptr = mips16_local_alias (fn);
-         return NULL_RTX;
+         return NULL;
        }
 
       /* Create a SYMBOL_REF for the libgcc.a function.  */
@@ -6844,7 +6828,7 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
                             FUNCTION_DECL, stubid,
                             build_function_type_list (void_type_node,
                                                       NULL_TREE));
-      DECL_SECTION_NAME (stubdecl) = build_string (strlen (secname), secname);
+      set_decl_section_name (stubdecl, secname);
       DECL_RESULT (stubdecl) = build_decl (BUILTINS_LOCATION,
                                           RESULT_DECL, NULL_TREE,
                                           void_type_node);
@@ -6993,10 +6977,10 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
     error ("cannot handle inconsistent calls to %qs", fnname);
 
   if (retval == NULL_RTX)
-    insn = gen_call_internal_direct (fn, args_size);
+    pattern = gen_call_internal_direct (fn, args_size);
   else
-    insn = gen_call_value_internal_direct (retval, fn, args_size);
-  insn = mips_emit_call_insn (insn, fn, fn, false);
+    pattern = gen_call_value_internal_direct (retval, fn, args_size);
+  insn = mips_emit_call_insn (pattern, fn, fn, false);
 
   /* If we are calling a stub which handles a floating-point return
      value, we need to arrange to save $18 in the prologue.  We do this
@@ -7021,11 +7005,12 @@ mips16_build_call_stub (rtx retval, rtx *fn_ptr, rtx args_size, int fp_code)
 
    Return the call itself.  */
 
-rtx
+rtx_insn *
 mips_expand_call (enum mips_call_type type, rtx result, rtx addr,
                  rtx args_size, rtx aux, bool lazy_p)
 {
-  rtx orig_addr, pattern, insn;
+  rtx orig_addr, pattern;
+  rtx_insn *insn;
   int fp_code;
 
   fp_code = aux == 0 ? 0 : (int) GET_MODE (aux);
@@ -7099,10 +7084,8 @@ mips_split_call (rtx insn, rtx call_pattern)
 {
   emit_call_insn (call_pattern);
   if (!find_reg_note (insn, REG_NORETURN, 0))
-    /* Pick a temporary register that is suitable for both MIPS16 and
-       non-MIPS16 code.  $4 and $5 are used for returning complex double
-       values in soft-float code, so $6 is the first suitable candidate.  */
-    mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode, GP_ARG_FIRST + 2));
+    mips_restore_gp_from_cprestore_slot (gen_rtx_REG (Pmode,
+                                                     POST_CALL_TMP_REG));
 }
 
 /* Return true if a call to DECL may need to use JALX.  */
@@ -7169,35 +7152,6 @@ mips_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
   return true;
 }
 \f
-/* Emit code to move general operand SRC into condition-code
-   register DEST given that SCRATCH is a scratch TFmode FPR.
-   The sequence is:
-
-       FP1 = SRC
-       FP2 = 0.0f
-       DEST = FP2 < FP1
-
-   where FP1 and FP2 are single-precision FPRs taken from SCRATCH.  */
-
-void
-mips_expand_fcc_reload (rtx dest, rtx src, rtx scratch)
-{
-  rtx fp1, fp2;
-
-  /* Change the source to SFmode.  */
-  if (MEM_P (src))
-    src = adjust_address (src, SFmode, 0);
-  else if (REG_P (src) || GET_CODE (src) == SUBREG)
-    src = gen_rtx_REG (SFmode, true_regnum (src));
-
-  fp1 = gen_rtx_REG (SFmode, REGNO (scratch));
-  fp2 = gen_rtx_REG (SFmode, REGNO (scratch) + MAX_FPRS_PER_FMT);
-
-  mips_emit_move (copy_rtx (fp1), src);
-  mips_emit_move (copy_rtx (fp2), CONST0_RTX (SFmode));
-  emit_insn (gen_slt_sf (dest, fp2, fp1));
-}
-\f
 /* Implement MOVE_BY_PIECES_P.  */
 
 bool
@@ -7379,7 +7333,8 @@ static void
 mips_block_move_loop (rtx dest, rtx src, HOST_WIDE_INT length,
                      HOST_WIDE_INT bytes_per_iter)
 {
-  rtx label, src_reg, dest_reg, final_src, test;
+  rtx_code_label *label;
+  rtx src_reg, dest_reg, final_src, test;
   HOST_WIDE_INT leftover;
 
   leftover = length % bytes_per_iter;
@@ -7445,7 +7400,8 @@ mips_expand_block_move (rtx dest, rtx src, rtx length)
 void
 mips_expand_synci_loop (rtx begin, rtx end)
 {
-  rtx inc, label, end_label, cmp_result, mask, length;
+  rtx inc, cmp_result, mask, length;
+  rtx_code_label *label, *end_label;
 
   /* Create end_label.  */
   end_label = gen_label_rtx ();
@@ -7472,7 +7428,7 @@ mips_expand_synci_loop (rtx begin, rtx end)
   length = mips_force_binary (Pmode, MINUS, end, begin);
 
   /* Loop back to here.  */
-  label = gen_label_rtx ();
+    label = gen_label_rtx ();
   emit_label (label);
 
   emit_insn (gen_synci (begin));
@@ -8125,7 +8081,7 @@ mips_print_operand_punctuation (FILE *file, int ch)
       /* If the delay slot instruction is short, then use the
         compact version.  */
       if (final_sequence == 0
-         || get_attr_length (XVECEXP (final_sequence, 0, 1)) == 2)
+         || get_attr_length (final_sequence->insn (1)) == 2)
        putc ('s', file);
       break;
 
@@ -8464,8 +8420,8 @@ mips_function_rodata_section (tree decl)
 
   if (decl && DECL_SECTION_NAME (decl))
     {
-      const char *name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
-      if (DECL_ONE_ONLY (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
+      const char *name = DECL_SECTION_NAME (decl);
+      if (DECL_COMDAT_GROUP (decl) && strncmp (name, ".gnu.linkonce.t.", 16) == 0)
        {
          char *rname = ASTRDUP (name);
          rname[14] = 'd';
@@ -8504,7 +8460,7 @@ mips_in_small_data_p (const_tree decl)
       const char *name;
 
       /* Reject anything that isn't in a known small-data section.  */
-      name = TREE_STRING_POINTER (DECL_SECTION_NAME (decl));
+      name = DECL_SECTION_NAME (decl);
       if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
        return false;
 
@@ -9038,7 +8994,7 @@ mips_code_end (void)
 static void
 mips_set_frame_expr (rtx frame_pattern)
 {
-  rtx insn;
+  rtx_insn *insn;
 
   insn = get_last_insn ();
   RTX_FRAME_RELATED_P (insn) = 1;
@@ -9206,7 +9162,8 @@ static unsigned int
 mips16e_collect_argument_saves (void)
 {
   rtx reg_values[FIRST_PSEUDO_REGISTER];
-  rtx insn, next, set, dest, src;
+  rtx_insn *insn, *next;
+  rtx set, dest, src;
   unsigned int nargs, regno;
 
   push_topmost_sequence ();
@@ -9542,9 +9499,9 @@ mips16_cfun_returns_in_fpr_p (void)
    if *CACHE is already true.  */
 
 static bool
-mips_find_gp_ref (bool *cache, bool (*pred) (rtx))
+mips_find_gp_ref (bool *cache, bool (*pred) (rtx_insn *))
 {
-  rtx insn;
+  rtx_insn *insn;
 
   if (!*cache)
     {
@@ -9564,7 +9521,7 @@ mips_find_gp_ref (bool *cache, bool (*pred) (rtx))
    See mips_cfun_has_inflexible_gp_ref_p for details.  */
 
 static bool
-mips_insn_has_inflexible_gp_ref_p (rtx insn)
+mips_insn_has_inflexible_gp_ref_p (rtx_insn *insn)
 {
   /* Uses of pic_offset_table_rtx in CALL_INSN_FUNCTION_USAGE
      indicate that the target could be a traditional MIPS
@@ -9617,7 +9574,7 @@ mips_cfun_has_inflexible_gp_ref_p (void)
    See mips_cfun_has_flexible_gp_ref_p for details.  */
 
 static bool
-mips_insn_has_flexible_gp_ref_p (rtx insn)
+mips_insn_has_flexible_gp_ref_p (rtx_insn *insn)
 {
   return (get_attr_got (insn) != GOT_UNSET
          || mips_small_data_pattern_p (PATTERN (insn))
@@ -10017,8 +9974,8 @@ mips_compute_frame_info (void)
   /* Set this function's interrupt properties.  */
   if (mips_interrupt_type_p (TREE_TYPE (current_function_decl)))
     {
-      if (!ISA_MIPS32R2)
-       error ("the %<interrupt%> attribute requires a MIPS32r2 processor");
+      if (mips_isa_rev < 2)
+       error ("the %<interrupt%> attribute requires a MIPS32r2 processor or greater");
       else if (TARGET_HARD_FLOAT)
        error ("the %<interrupt%> attribute requires %<-msoft-float%>");
       else if (TARGET_MIPS16)
@@ -11095,7 +11052,6 @@ mips_expand_prologue (void)
   const struct mips_frame_info *frame;
   HOST_WIDE_INT size;
   unsigned int nargs;
-  rtx insn;
 
   if (cfun->machine->global_pointer != INVALID_REGNUM)
     {
@@ -11149,8 +11105,8 @@ mips_expand_prologue (void)
 
          /* Build the save instruction.  */
          mask = frame->mask;
-         insn = mips16e_build_save_restore (false, &mask, &offset,
-                                            nargs, step1);
+         rtx insn = mips16e_build_save_restore (false, &mask, &offset,
+                                                nargs, step1);
          RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
          mips_frame_barrier ();
          size -= step1;
@@ -11190,8 +11146,8 @@ mips_expand_prologue (void)
                }
 
              /* Allocate the first part of the frame.  */
-             insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
-                                   GEN_INT (-step1));
+             rtx insn = gen_add3_insn (stack_pointer_rtx, stack_pointer_rtx,
+                                       GEN_INT (-step1));
              RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
              mips_frame_barrier ();
              size -= step1;
@@ -11251,9 +11207,9 @@ mips_expand_prologue (void)
            }
          else
            {
-             insn = gen_add3_insn (stack_pointer_rtx,
-                                   stack_pointer_rtx,
-                                   GEN_INT (-step1));
+             rtx insn = gen_add3_insn (stack_pointer_rtx,
+                                       stack_pointer_rtx,
+                                       GEN_INT (-step1));
              RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
              mips_frame_barrier ();
              size -= step1;
@@ -11307,13 +11263,13 @@ mips_expand_prologue (void)
       offset = frame->hard_frame_pointer_offset;
       if (offset == 0)
        {
-         insn = mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
+         rtx insn = mips_emit_move (hard_frame_pointer_rtx, stack_pointer_rtx);
          RTX_FRAME_RELATED_P (insn) = 1;
        }
       else if (SMALL_OPERAND (offset))
        {
-         insn = gen_add3_insn (hard_frame_pointer_rtx,
-                               stack_pointer_rtx, GEN_INT (offset));
+         rtx insn = gen_add3_insn (hard_frame_pointer_rtx,
+                                   stack_pointer_rtx, GEN_INT (offset));
          RTX_FRAME_RELATED_P (emit_insn (insn)) = 1;
        }
       else
@@ -11354,6 +11310,7 @@ mips_expand_prologue (void)
   /* We need to search back to the last use of K0 or K1.  */
   if (cfun->machine->interrupt_handler_p)
     {
+      rtx_insn *insn;
       for (insn = get_last_insn (); insn != NULL_RTX; insn = PREV_INSN (insn))
        if (INSN_P (insn)
            && for_each_rtx (&PATTERN (insn), mips_kernel_reg_p, NULL))
@@ -11374,10 +11331,10 @@ mips_expand_prologue (void)
 /* Attach all pending register saves to the previous instruction.
    Return that instruction.  */
 
-static rtx
+static rtx_insn *
 mips_epilogue_emit_cfa_restores (void)
 {
-  rtx insn;
+  rtx_insn *insn;
 
   insn = get_last_insn ();
   gcc_assert (insn && !REG_NOTES (insn));
@@ -11396,7 +11353,7 @@ mips_epilogue_emit_cfa_restores (void)
 static void
 mips_epilogue_set_cfa (rtx reg, HOST_WIDE_INT offset)
 {
-  rtx insn;
+  rtx_insn *insn;
 
   insn = mips_epilogue_emit_cfa_restores ();
   if (reg != mips_epilogue.cfa_reg || offset != mips_epilogue.cfa_offset)
@@ -11492,7 +11449,8 @@ mips_expand_epilogue (bool sibcall_p)
 {
   const struct mips_frame_info *frame;
   HOST_WIDE_INT step1, step2;
-  rtx base, adjust, insn;
+  rtx base, adjust;
+  rtx_insn *insn;
   bool use_jraddiusp_p = false;
 
   if (!sibcall_p && mips_can_use_return_insn ())
@@ -11995,13 +11953,12 @@ mips_canonicalize_move_class (reg_class_t rclass)
   return rclass;
 }
 
-/* Return the cost of moving a value of mode MODE from a register of
-   class FROM to a GPR.  Return 0 for classes that are unions of other
-   classes handled by this function.  */
+/* Return the cost of moving a value from a register of class FROM to a GPR.
+   Return 0 for classes that are unions of other classes handled by this
+   function.  */
 
 static int
-mips_move_to_gpr_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
-                      reg_class_t from)
+mips_move_to_gpr_cost (reg_class_t from)
 {
   switch (from)
     {
@@ -12018,10 +11975,6 @@ mips_move_to_gpr_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
       /* MFC1, etc.  */
       return 4;
 
-    case ST_REGS:
-      /* LUI followed by MOVF.  */
-      return 4;
-
     case COP0_REGS:
     case COP2_REGS:
     case COP3_REGS:
@@ -12033,12 +11986,12 @@ mips_move_to_gpr_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
     }
 }
 
-/* Return the cost of moving a value of mode MODE from a GPR to a
-   register of class TO.  Return 0 for classes that are unions of
-   other classes handled by this function.  */
+/* Return the cost of moving a value from a GPR to a register of class TO.
+   Return 0 for classes that are unions of other classes handled by this
+   function.  */
 
 static int
-mips_move_from_gpr_cost (enum machine_mode mode, reg_class_t to)
+mips_move_from_gpr_cost (reg_class_t to)
 {
   switch (to)
     {
@@ -12055,11 +12008,6 @@ mips_move_from_gpr_cost (enum machine_mode mode, reg_class_t to)
       /* MTC1, etc.  */
       return 4;
 
-    case ST_REGS:
-      /* A secondary reload through an FPR scratch.  */
-      return (mips_register_move_cost (mode, GENERAL_REGS, FP_REGS)
-             + mips_register_move_cost (mode, FP_REGS, ST_REGS));
-
     case COP0_REGS:
     case COP2_REGS:
     case COP3_REGS:
@@ -12091,23 +12039,20 @@ mips_register_move_cost (enum machine_mode mode,
       if (to == FP_REGS && mips_mode_ok_for_mov_fmt_p (mode))
        /* MOV.FMT.  */
        return 4;
-      if (to == ST_REGS)
-       /* The sequence generated by mips_expand_fcc_reload.  */
-       return 8;
     }
 
   /* Handle cases in which only one class deviates from the ideal.  */
   dregs = TARGET_MIPS16 ? M16_REGS : GENERAL_REGS;
   if (from == dregs)
-    return mips_move_from_gpr_cost (mode, to);
+    return mips_move_from_gpr_cost (to);
   if (to == dregs)
-    return mips_move_to_gpr_cost (mode, from);
+    return mips_move_to_gpr_cost (from);
 
   /* Handles cases that require a GPR temporary.  */
-  cost1 = mips_move_to_gpr_cost (mode, from);
+  cost1 = mips_move_to_gpr_cost (from);
   if (cost1 != 0)
     {
-      cost2 = mips_move_from_gpr_cost (mode, to);
+      cost2 = mips_move_from_gpr_cost (to);
       if (cost2 != 0)
        return cost1 + cost2;
     }
@@ -12115,6 +12060,18 @@ mips_register_move_cost (enum machine_mode mode,
   return 0;
 }
 
+/* Implement TARGET_REGISTER_PRIORITY.  */
+
+static int
+mips_register_priority (int hard_regno)
+{
+  /* Treat MIPS16 registers with higher priority than other regs.  */
+  if (TARGET_MIPS16
+      && TEST_HARD_REG_BIT (reg_class_contents[M16_REGS], hard_regno))
+    return 1;
+  return 0;
+}
+
 /* Implement TARGET_MEMORY_MOVE_COST.  */
 
 static int
@@ -12132,7 +12089,7 @@ mips_memory_move_cost (enum machine_mode mode, reg_class_t rclass, bool in)
 
 enum reg_class
 mips_secondary_reload_class (enum reg_class rclass,
-                            enum machine_mode mode, rtx x, bool in_p)
+                            enum machine_mode mode, rtx x, bool)
 {
   int regno;
 
@@ -12158,27 +12115,11 @@ mips_secondary_reload_class (enum reg_class rclass,
   if (ACC_REG_P (regno))
     return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS;
 
-  /* We can only copy a value to a condition code register from a
-     floating-point register, and even then we require a scratch
-     floating-point register.  We can only copy a value out of a
-     condition-code register into a general register.  */
-  if (reg_class_subset_p (rclass, ST_REGS))
-    {
-      if (in_p)
-       return FP_REGS;
-      return GP_REG_P (regno) ? NO_REGS : GR_REGS;
-    }
-  if (ST_REG_P (regno))
-    {
-      if (!in_p)
-       return FP_REGS;
-      return reg_class_subset_p (rclass, GR_REGS) ? NO_REGS : GR_REGS;
-    }
-
   if (reg_class_subset_p (rclass, FP_REGS))
     {
-      if (MEM_P (x)
-         && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8))
+      if (regno < 0
+         || (MEM_P (x)
+             && (GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)))
        /* In this case we can use lwc1, swc1, ldc1 or sdc1.  We'll use
           pairs of lwc1s and swc1s if ldc1 and sdc1 are not supported.  */
        return NO_REGS;
@@ -12439,7 +12380,7 @@ mips_output_load_label (rtx target)
    attributes in the machine-description file.  */
 
 int
-mips_adjust_insn_length (rtx insn, int length)
+mips_adjust_insn_length (rtx_insn *insn, int length)
 {
   /* mips.md uses MAX_PIC_BRANCH_LENGTH as a placeholder for the length
      of a PIC long-branch sequence.  Substitute the correct value.  */
@@ -12493,12 +12434,12 @@ mips_adjust_insn_length (rtx insn, int length)
    version of BRANCH_IF_TRUE.  */
 
 const char *
-mips_output_conditional_branch (rtx insn, rtx *operands,
+mips_output_conditional_branch (rtx_insn *insn, rtx *operands,
                                const char *branch_if_true,
                                const char *branch_if_false)
 {
   unsigned int length;
-  rtx taken, not_taken;
+  rtx taken;
 
   gcc_assert (LABEL_P (operands[0]));
 
@@ -12513,7 +12454,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands,
   /* Generate a reversed branch around a direct jump.  This fallback does
      not use branch-likely instructions.  */
   mips_branch_likely = false;
-  not_taken = gen_label_rtx ();
+  rtx_code_label *not_taken = gen_label_rtx ();
   taken = operands[0];
 
   /* Generate the reversed branch to NOT_TAKEN.  */
@@ -12529,9 +12470,9 @@ mips_output_conditional_branch (rtx insn, rtx *operands,
         delay slot if is not annulled.  */
       if (!INSN_ANNULLED_BRANCH_P (insn))
        {
-         final_scan_insn (XVECEXP (final_sequence, 0, 1),
+         final_scan_insn (final_sequence->insn (1),
                           asm_out_file, optimize, 1, NULL);
-         INSN_DELETED_P (XVECEXP (final_sequence, 0, 1)) = 1;
+         final_sequence->insn (1)->set_deleted ();
        }
       else
        output_asm_insn ("nop", 0);
@@ -12554,9 +12495,9 @@ mips_output_conditional_branch (rtx insn, rtx *operands,
         Use INSN's delay slot if is annulled.  */
       if (INSN_ANNULLED_BRANCH_P (insn))
        {
-         final_scan_insn (XVECEXP (final_sequence, 0, 1),
+         final_scan_insn (final_sequence->insn (1),
                           asm_out_file, optimize, 1, NULL);
-         INSN_DELETED_P (XVECEXP (final_sequence, 0, 1)) = 1;
+         final_sequence->insn (1)->set_deleted ();
        }
       else
        output_asm_insn ("nop", 0);
@@ -12576,7 +12517,7 @@ mips_output_conditional_branch (rtx insn, rtx *operands,
    its second is always zero.  */
 
 const char *
-mips_output_order_conditional_branch (rtx insn, rtx *operands, bool inverted_p)
+mips_output_order_conditional_branch (rtx_insn *insn, rtx *operands, bool inverted_p)
 {
   const char *branch[2];
 
@@ -12716,7 +12657,7 @@ mips_get_sync_operand (rtx *operands, int index, rtx default_value)
    sequence for it.  */
 
 static void
-mips_process_sync_loop (rtx insn, rtx *operands)
+mips_process_sync_loop (rtx_insn *insn, rtx *operands)
 {
   rtx at, mem, oldval, newval, inclusive_mask, exclusive_mask;
   rtx required_oldval, insn1_op2, tmp1, tmp2, tmp3, cmp;
@@ -12898,7 +12839,7 @@ mips_process_sync_loop (rtx insn, rtx *operands)
    the operands given by OPERANDS.  */
 
 const char *
-mips_output_sync_loop (rtx insn, rtx *operands)
+mips_output_sync_loop (rtx_insn *insn, rtx *operands)
 {
   mips_process_sync_loop (insn, operands);
 
@@ -12925,7 +12866,7 @@ mips_output_sync_loop (rtx insn, rtx *operands)
    which has the operands given by OPERANDS.  */
 
 unsigned int
-mips_sync_loop_insns (rtx insn, rtx *operands)
+mips_sync_loop_insns (rtx_insn *insn, rtx *operands)
 {
   mips_process_sync_loop (insn, operands);
   return mips_multi_num_insns;
@@ -13060,11 +13001,36 @@ mips_output_division (const char *division, rtx *operands)
   return s;
 }
 \f
+/* Return true if destination of IN_INSN is used as add source in
+   OUT_INSN. Both IN_INSN and OUT_INSN are of type fmadd. Example:
+   madd.s dst, x, y, z
+   madd.s a, dst, b, c  */
+
+bool
+mips_fmadd_bypass (rtx_insn *out_insn, rtx_insn *in_insn)
+{
+  int dst_reg, src_reg;
+  
+  gcc_assert (get_attr_type (in_insn) == TYPE_FMADD);
+  gcc_assert (get_attr_type (out_insn) == TYPE_FMADD);
+
+  extract_insn (in_insn);
+  dst_reg = REG_P (recog_data.operand[0]);
+
+  extract_insn (out_insn);
+  src_reg = REG_P (recog_data.operand[1]);
+
+  if (dst_reg == src_reg)
+    return true;
+
+  return false;
+}
+
 /* Return true if IN_INSN is a multiply-add or multiply-subtract
    instruction and if OUT_INSN assigns to the accumulator operand.  */
 
 bool
-mips_linked_madd_p (rtx out_insn, rtx in_insn)
+mips_linked_madd_p (rtx_insn *out_insn, rtx_insn *in_insn)
 {
   enum attr_accum_in accum_in;
   int accum_in_opnum;
@@ -13093,7 +13059,7 @@ mips_linked_madd_p (rtx out_insn, rtx in_insn)
    for that case.  */
 
 bool
-mips_store_data_bypass_p (rtx out_insn, rtx in_insn)
+mips_store_data_bypass_p (rtx_insn *out_insn, rtx_insn *in_insn)
 {
   if (GET_CODE (PATTERN (in_insn)) == UNSPEC_VOLATILE)
     return false;
@@ -13130,10 +13096,10 @@ static struct
      DFA state.
      E.g., when alu1_turn_enabled_insn is issued it makes next ALU1/2
      instruction to go ALU1.  */
-  rtx alu1_turn_enabled_insn;
-  rtx alu2_turn_enabled_insn;
-  rtx falu1_turn_enabled_insn;
-  rtx falu2_turn_enabled_insn;
+  rtx_insn *alu1_turn_enabled_insn;
+  rtx_insn *alu2_turn_enabled_insn;
+  rtx_insn *falu1_turn_enabled_insn;
+  rtx_insn *falu2_turn_enabled_insn;
 } mips_ls2;
 
 /* Implement TARGET_SCHED_ADJUST_COST.  We assume that anti and output
@@ -13141,8 +13107,8 @@ static struct
    is treated like input-dependence.  */
 
 static int
-mips_adjust_cost (rtx insn ATTRIBUTE_UNUSED, rtx link,
-                 rtx dep ATTRIBUTE_UNUSED, int cost)
+mips_adjust_cost (rtx_insn *insn ATTRIBUTE_UNUSED, rtx link,
+                 rtx_insn *dep ATTRIBUTE_UNUSED, int cost)
 {
   if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT
       && TUNE_20KC)
@@ -13195,6 +13161,7 @@ mips_issue_rate (void)
     case PROCESSOR_LOONGSON_2E:
     case PROCESSOR_LOONGSON_2F:
     case PROCESSOR_LOONGSON_3A:
+    case PROCESSOR_P5600:
       return 4;
 
     case PROCESSOR_XLP:
@@ -13330,6 +13297,9 @@ mips_multipass_dfa_lookahead (void)
   if (TUNE_OCTEON)
     return 2;
 
+  if (TUNE_P5600)
+    return 4;
+
   return 0;
 }
 \f
@@ -13338,9 +13308,9 @@ mips_multipass_dfa_lookahead (void)
    be <= HIGHER.  */
 
 static void
-mips_promote_ready (rtx *ready, int lower, int higher)
+mips_promote_ready (rtx_insn **ready, int lower, int higher)
 {
-  rtx new_head;
+  rtx_insn *new_head;
   int i;
 
   new_head = ready[lower];
@@ -13354,12 +13324,12 @@ mips_promote_ready (rtx *ready, int lower, int higher)
    instructions if POS2 is not already less than POS1.  */
 
 static void
-mips_maybe_swap_ready (rtx *ready, int pos1, int pos2, int limit)
+mips_maybe_swap_ready (rtx_insn **ready, int pos1, int pos2, int limit)
 {
   if (pos1 < pos2
       && INSN_PRIORITY (ready[pos1]) + limit >= INSN_PRIORITY (ready[pos2]))
     {
-      rtx temp;
+      rtx_insn *temp;
 
       temp = ready[pos1];
       ready[pos1] = ready[pos2];
@@ -13369,13 +13339,13 @@ mips_maybe_swap_ready (rtx *ready, int pos1, int pos2, int limit)
 \f
 /* Used by TUNE_MACC_CHAINS to record the last scheduled instruction
    that may clobber hi or lo.  */
-static rtx mips_macc_chains_last_hilo;
+static rtx_insn *mips_macc_chains_last_hilo;
 
 /* A TUNE_MACC_CHAINS helper function.  Record that instruction INSN has
    been scheduled, updating mips_macc_chains_last_hilo appropriately.  */
 
 static void
-mips_macc_chains_record (rtx insn)
+mips_macc_chains_record (rtx_insn *insn)
 {
   if (get_attr_may_clobber_hilo (insn))
     mips_macc_chains_last_hilo = insn;
@@ -13388,7 +13358,7 @@ mips_macc_chains_record (rtx insn)
    clobber hi or lo.  */
 
 static void
-mips_macc_chains_reorder (rtx *ready, int nready)
+mips_macc_chains_reorder (rtx_insn **ready, int nready)
 {
   int i, j;
 
@@ -13408,7 +13378,7 @@ mips_macc_chains_reorder (rtx *ready, int nready)
 }
 \f
 /* The last instruction to be scheduled.  */
-static rtx vr4130_last_insn;
+static rtx_insn *vr4130_last_insn;
 
 /* A note_stores callback used by vr4130_true_reg_dependence_p.  DATA
    points to an rtx that is initially an instruction.  Nullify the rtx
@@ -13446,7 +13416,7 @@ vr4130_true_reg_dependence_p (rtx insn)
    alignment than (INSN1, INSN2).  See 4130.md for more details.  */
 
 static bool
-vr4130_swap_insns_p (rtx insn1, rtx insn2)
+vr4130_swap_insns_p (rtx_insn *insn1, rtx_insn *insn2)
 {
   sd_iterator_def sd_it;
   dep_t dep;
@@ -13502,7 +13472,7 @@ vr4130_swap_insns_p (rtx insn1, rtx insn2)
    vr4130_swap_insns_p says that it could be worthwhile.  */
 
 static void
-vr4130_reorder (rtx *ready, int nready)
+vr4130_reorder (rtx_insn **ready, int nready)
 {
   if (vr4130_swap_insns_p (ready[nready - 1], ready[nready - 2]))
     mips_promote_ready (ready, nready - 2, nready - 1);
@@ -13515,7 +13485,7 @@ static enum attr_type mips_last_74k_agen_insn = TYPE_UNKNOWN;
    resets to TYPE_UNKNOWN state.  */
 
 static void
-mips_74k_agen_init (rtx insn)
+mips_74k_agen_init (rtx_insn *insn)
 {
   if (!insn || CALL_P (insn) || JUMP_P (insn))
     mips_last_74k_agen_insn = TYPE_UNKNOWN;
@@ -13532,7 +13502,7 @@ mips_74k_agen_init (rtx insn)
    together.  Swap things around in the ready queue to make this happen.  */
 
 static void
-mips_74k_agen_reorder (rtx *ready, int nready)
+mips_74k_agen_reorder (rtx_insn **ready, int nready)
 {
   int i;
   int store_pos, load_pos;
@@ -13542,7 +13512,7 @@ mips_74k_agen_reorder (rtx *ready, int nready)
 
   for (i = nready - 1; i >= 0; i--)
     {
-      rtx insn = ready[i];
+      rtx_insn *insn = ready[i];
       if (USEFUL_INSN_P (insn))
        switch (get_attr_type (insn))
          {
@@ -13589,7 +13559,7 @@ mips_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
 {
   mips_macc_chains_last_hilo = 0;
   vr4130_last_insn = 0;
-  mips_74k_agen_init (NULL_RTX);
+  mips_74k_agen_init (NULL);
 
   /* When scheduling for Loongson2, branch instructions go to ALU1,
      therefore basic block is most likely to start with round-robin counter
@@ -13602,7 +13572,7 @@ mips_sched_init (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
 
 static void
 mips_sched_reorder_1 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
-                     rtx *ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
+                     rtx_insn **ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
 {
   if (!reload_completed
       && TUNE_MACC_CHAINS
@@ -13623,7 +13593,7 @@ mips_sched_reorder_1 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
 
 static int
 mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
-                   rtx *ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
+                   rtx_insn **ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
 {
   mips_sched_reorder_1 (file, verbose, ready, nreadyp, cycle);
   return mips_issue_rate ();
@@ -13633,7 +13603,7 @@ mips_sched_reorder (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
 
 static int
 mips_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
-                    rtx *ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
+                    rtx_insn **ready, int *nreadyp, int cycle ATTRIBUTE_UNUSED)
 {
   mips_sched_reorder_1 (file, verbose, ready, nreadyp, cycle);
   return cached_can_issue_more;
@@ -13642,7 +13612,7 @@ mips_sched_reorder2 (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
 /* Update round-robin counters for ALU1/2 and FALU1/2.  */
 
 static void
-mips_ls2_variable_issue (rtx insn)
+mips_ls2_variable_issue (rtx_insn *insn)
 {
   if (mips_ls2.alu1_turn_p)
     {
@@ -13674,7 +13644,7 @@ mips_ls2_variable_issue (rtx insn)
 
 static int
 mips_variable_issue (FILE *file ATTRIBUTE_UNUSED, int verbose ATTRIBUTE_UNUSED,
-                    rtx insn, int more)
+                    rtx_insn *insn, int more)
 {
   /* Ignore USEs and CLOBBERs; don't count them against the issue rate.  */
   if (USEFUL_INSN_P (insn))
@@ -14490,7 +14460,7 @@ static rtx
 mips_builtin_branch_and_move (rtx condition, rtx target,
                              rtx value_if_true, rtx value_if_false)
 {
-  rtx true_label, done_label;
+  rtx_code_label *true_label, *done_label;
 
   true_label = gen_label_rtx ();
   done_label = gen_label_rtx ();
@@ -14630,7 +14600,7 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
 struct mips16_constant {
   struct mips16_constant *next;
   rtx value;
-  rtx label;
+  rtx_code_label *label;
   enum machine_mode mode;
 };
 
@@ -14647,7 +14617,7 @@ struct mips16_constant_pool {
 /* Add constant VALUE to POOL and return its label.  MODE is the
    value's mode (used for CONST_INTs, etc.).  */
 
-static rtx
+static rtx_code_label *
 mips16_add_constant (struct mips16_constant_pool *pool,
                     rtx value, enum machine_mode mode)
 {
@@ -14704,8 +14674,8 @@ mips16_add_constant (struct mips16_constant_pool *pool,
 /* Output constant VALUE after instruction INSN and return the last
    instruction emitted.  MODE is the mode of the constant.  */
 
-static rtx
-mips16_emit_constants_1 (enum machine_mode mode, rtx value, rtx insn)
+static rtx_insn *
+mips16_emit_constants_1 (enum machine_mode mode, rtx value, rtx_insn *insn)
 {
   if (SCALAR_INT_MODE_P (mode) || ALL_SCALAR_FIXED_POINT_MODE_P (mode))
     {
@@ -14732,7 +14702,7 @@ mips16_emit_constants_1 (enum machine_mode mode, rtx value, rtx insn)
 /* Dump out the constants in CONSTANTS after INSN.  */
 
 static void
-mips16_emit_constants (struct mips16_constant *constants, rtx insn)
+mips16_emit_constants (struct mips16_constant *constants, rtx_insn *insn)
 {
   struct mips16_constant *c, *next;
   int align;
@@ -14761,7 +14731,7 @@ mips16_emit_constants (struct mips16_constant *constants, rtx insn)
 /* Return the length of instruction INSN.  */
 
 static int
-mips16_insn_length (rtx insn)
+mips16_insn_length (rtx_insn *insn)
 {
   if (JUMP_TABLE_DATA_P (insn))
     {
@@ -14782,7 +14752,8 @@ mips16_insn_length (rtx insn)
 static void
 mips16_rewrite_pool_constant (struct mips16_constant_pool *pool, rtx *x)
 {
-  rtx base, offset, label;
+  rtx base, offset;
+  rtx_code_label *label;
 
   split_const (*x, &base, &offset);
   if (GET_CODE (base) == SYMBOL_REF && CONSTANT_POOL_ADDRESS_P (base))
@@ -14798,7 +14769,7 @@ mips16_rewrite_pool_constant (struct mips16_constant_pool *pool, rtx *x)
    INSN is the instruction we're rewriting and POOL points to the current
    constant pool.  */
 struct mips16_rewrite_pool_refs_info {
-  rtx insn;
+  rtx_insn *insn;
   struct mips16_constant_pool *pool;
 };
 
@@ -14851,7 +14822,7 @@ mips16_lay_out_constants (bool split_p)
 {
   struct mips16_constant_pool pool;
   struct mips16_rewrite_pool_refs_info info;
-  rtx insn, barrier;
+  rtx_insn *insn, *barrier;
 
   if (!TARGET_MIPS16_PCREL_LOADS)
     return;
@@ -14888,7 +14859,8 @@ mips16_lay_out_constants (bool split_p)
             do it immediately before INSN.  */
          if (barrier == 0 && pool.insn_address + 4 > pool.highest_address)
            {
-             rtx label, jump;
+             rtx_code_label *label;
+             rtx_insn *jump;
 
              label = gen_label_rtx ();
 
@@ -14936,9 +14908,10 @@ r10k_simplified_address_p (rtx x)
    virtual_incoming_args_rtx (which should never occur in X otherwise).  */
 
 static rtx
-r10k_simplify_address (rtx x, rtx insn)
+r10k_simplify_address (rtx x, rtx_insn *insn)
 {
-  rtx newx, op0, op1, set, def_insn, note;
+  rtx newx, op0, op1, set, note;
+  rtx_insn *def_insn;
   df_ref use, def;
   struct df_link *defs;
 
@@ -15040,7 +15013,7 @@ r10k_uncached_address_p (unsigned HOST_WIDE_INT address)
    expression; it might not be a legitimate address.  */
 
 static bool
-r10k_safe_address_p (rtx x, rtx insn)
+r10k_safe_address_p (rtx x, rtx_insn *insn)
 {
   rtx base, offset;
   HOST_WIDE_INT offset_val;
@@ -15105,7 +15078,7 @@ r10k_needs_protection_p_1 (rtx *loc, void *data)
       && r10k_safe_mem_expr_p (MEM_EXPR (mem), MEM_OFFSET (mem)))
     return -1;
 
-  if (r10k_safe_address_p (XEXP (mem, 0), (rtx) data))
+  if (r10k_safe_address_p (XEXP (mem, 0), (rtx_insn *) data))
     return -1;
 
   return 1;
@@ -15119,11 +15092,11 @@ static void
 r10k_needs_protection_p_store (rtx x, const_rtx pat ATTRIBUTE_UNUSED,
                               void *data)
 {
-  rtx *insn_ptr;
+  rtx_insn **insn_ptr;
 
-  insn_ptr = (rtx *) data;
+  insn_ptr = (rtx_insn **) data;
   if (*insn_ptr && for_each_rtx (&x, r10k_needs_protection_p_1, *insn_ptr))
-    *insn_ptr = NULL_RTX;
+    *insn_ptr = NULL;
 }
 
 /* A for_each_rtx callback that iterates over the pattern of a CALL_INSN.
@@ -15149,7 +15122,7 @@ r10k_needs_protection_p_call (rtx *loc, void *data ATTRIBUTE_UNUSED)
    cache barrier.  */
 
 static bool
-r10k_needs_protection_p (rtx insn)
+r10k_needs_protection_p (rtx_insn *insn)
 {
   if (CALL_P (insn))
     return for_each_rtx (&PATTERN (insn), r10k_needs_protection_p_call, NULL);
@@ -15189,7 +15162,8 @@ r10k_insert_cache_barriers (void)
   unsigned int i, n;
   basic_block bb;
   sbitmap protected_bbs;
-  rtx insn, end, unprotected_region;
+  rtx_insn *insn, *end;
+  rtx unprotected_region;
 
   if (TARGET_MIPS16)
     {
@@ -15282,7 +15256,7 @@ r10k_insert_cache_barriers (void)
    SECOND_CALL.  */
 
 static rtx
-mips_call_expr_from_insn (rtx insn, rtx *second_call)
+mips_call_expr_from_insn (rtx_insn *insn, rtx *second_call)
 {
   rtx x;
   rtx x2;
@@ -15322,7 +15296,8 @@ mips_call_expr_from_insn (rtx insn, rtx *second_call)
 static rtx
 mips_pic_call_symbol_from_set (df_ref def, rtx reg, bool recurse_p)
 {
-  rtx def_insn, set;
+  rtx_insn *def_insn;
+  rtx set;
 
   if (DF_REF_IS_ARTIFICIAL (def))
     return NULL_RTX;
@@ -15385,7 +15360,7 @@ mips_pic_call_symbol_from_set (df_ref def, rtx reg, bool recurse_p)
    mips_pic_call_symbol_from_set.  */
 
 static rtx
-mips_find_pic_call_symbol (rtx insn, rtx reg, bool recurse_p)
+mips_find_pic_call_symbol (rtx_insn *insn, rtx reg, bool recurse_p)
 {
   df_ref use;
   struct df_link *defs;
@@ -15461,7 +15436,7 @@ static void
 mips_annotate_pic_calls (void)
 {
   basic_block bb;
-  rtx insn;
+  rtx_insn *insn;
 
   FOR_EACH_BB_FN (bb, cfun)
     FOR_BB_INSNS (bb, insn)
@@ -15488,7 +15463,7 @@ mips_annotate_pic_calls (void)
 }
 \f
 /* A temporary variable used by for_each_rtx callbacks, etc.  */
-static rtx mips_sim_insn;
+static rtx_insn *mips_sim_insn;
 
 /* A structure representing the state of the processor pipeline.
    Used by the mips_sim_* family of functions.  */
@@ -15507,7 +15482,7 @@ struct mips_sim {
      LAST_SET[X].TIME is the time at which that instruction was issued.
      INSN is null if no instruction has yet set register X.  */
   struct {
-    rtx insn;
+    rtx_insn *insn;
     unsigned int time;
   } last_set[FIRST_PSEUDO_REGISTER];
 
@@ -15564,7 +15539,7 @@ mips_sim_next_cycle (struct mips_sim *state)
    register REG.  */
 
 static void
-mips_sim_wait_reg (struct mips_sim *state, rtx insn, rtx reg)
+mips_sim_wait_reg (struct mips_sim *state, rtx_insn *insn, rtx reg)
 {
   unsigned int regno, end_regno;
 
@@ -15604,7 +15579,7 @@ mips_sim_wait_regs_1 (rtx *x, void *data)
    dependencies are satisfied.  */
 
 static void
-mips_sim_wait_regs (struct mips_sim *state, rtx insn)
+mips_sim_wait_regs (struct mips_sim *state, rtx_insn *insn)
 {
   mips_sim_insn = insn;
   note_uses (&PATTERN (insn), mips_sim_wait_regs_1, state);
@@ -15614,7 +15589,7 @@ mips_sim_wait_regs (struct mips_sim *state, rtx insn)
    instruction INSN are available.  */
 
 static void
-mips_sim_wait_units (struct mips_sim *state, rtx insn)
+mips_sim_wait_units (struct mips_sim *state, rtx_insn *insn)
 {
   state_t tmp_state;
 
@@ -15628,7 +15603,7 @@ mips_sim_wait_units (struct mips_sim *state, rtx insn)
 /* Advance simulation state STATE until INSN is ready to issue.  */
 
 static void
-mips_sim_wait_insn (struct mips_sim *state, rtx insn)
+mips_sim_wait_insn (struct mips_sim *state, rtx_insn *insn)
 {
   mips_sim_wait_regs (state, insn);
   mips_sim_wait_units (state, insn);
@@ -15661,7 +15636,7 @@ mips_sim_record_set (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
    been called).  */
 
 static void
-mips_sim_issue_insn (struct mips_sim *state, rtx insn)
+mips_sim_issue_insn (struct mips_sim *state, rtx_insn *insn)
 {
   curr_state = state->dfa_state;
 
@@ -15688,7 +15663,7 @@ mips_sim_issue_nop (struct mips_sim *state)
    SEQUENCE.  */
 
 static void
-mips_sim_finish_insn (struct mips_sim *state, rtx insn)
+mips_sim_finish_insn (struct mips_sim *state, rtx_insn *insn)
 {
   /* If INSN is a jump with an implicit delay slot, simulate a nop.  */
   if (JUMP_P (insn))
@@ -15723,10 +15698,10 @@ mips_sim_finish_insn (struct mips_sim *state, rtx insn)
    instruction sequence SEQ.  */
 
 static unsigned int
-mips_seq_time (struct mips_sim *state, rtx seq)
+mips_seq_time (struct mips_sim *state, rtx_insn *seq)
 {
   mips_sim_reset (state);
-  for (rtx insn = seq; insn; insn = NEXT_INSN (insn))
+  for (rtx_insn *insn = seq; insn; insn = NEXT_INSN (insn))
     {
       mips_sim_wait_insn (state, insn);
       mips_sim_issue_insn (state, insn);
@@ -15835,9 +15810,9 @@ mips_expand_to_rtl_hook (void)
    try to avoid it by swapping rs and rt.  */
 
 static void
-vr4130_avoid_branch_rt_conflict (rtx insn)
+vr4130_avoid_branch_rt_conflict (rtx_insn *insn)
 {
-  rtx first, second;
+  rtx_insn *first, *second;
 
   first = SEQ_BEGIN (insn);
   second = SEQ_END (insn);
@@ -15872,7 +15847,7 @@ static void
 vr4130_align_insns (void)
 {
   struct mips_sim state;
-  rtx insn, subinsn, last, last2, next;
+  rtx_insn *insn, *subinsn, *last, *last2, *next;
   bool aligned_p;
 
   dfa_start ();
@@ -16023,14 +15998,14 @@ mips_lo_sum_offset_hasher::equal (const value_type *entry,
   return rtx_equal_p (entry->base, value);
 }
 
-typedef hash_table <mips_lo_sum_offset_hasher> mips_offset_table;
+typedef hash_table<mips_lo_sum_offset_hasher> mips_offset_table;
 
 /* Look up symbolic constant X in HTAB, which is a hash table of
    mips_lo_sum_offsets.  If OPTION is NO_INSERT, return true if X can be
    paired with a recorded LO_SUM, otherwise record X in the table.  */
 
 static bool
-mips_lo_sum_offset_lookup (mips_offset_table htab, rtx x,
+mips_lo_sum_offset_lookup (mips_offset_table *htab, rtx x,
                           enum insert_option option)
 {
   rtx base, offset;
@@ -16043,7 +16018,7 @@ mips_lo_sum_offset_lookup (mips_offset_table htab, rtx x,
     base = UNSPEC_ADDRESS (base);
 
   /* Look up the base in the hash table.  */
-  slot = htab.find_slot_with_hash (base, mips_hash_base (base), option);
+  slot = htab->find_slot_with_hash (base, mips_hash_base (base), option);
   if (slot == NULL)
     return false;
 
@@ -16073,7 +16048,7 @@ static int
 mips_record_lo_sum (rtx *loc, void *data)
 {
   if (GET_CODE (*loc) == LO_SUM)
-    mips_lo_sum_offset_lookup (*(mips_offset_table*) data,
+    mips_lo_sum_offset_lookup ((mips_offset_table*) data,
                               XEXP (*loc, 1), INSERT);
   return 0;
 }
@@ -16083,7 +16058,7 @@ mips_record_lo_sum (rtx *loc, void *data)
    LO_SUMs in the current function.  */
 
 static bool
-mips_orphaned_high_part_p (mips_offset_table htab, rtx insn)
+mips_orphaned_high_part_p (mips_offset_table *htab, rtx_insn *insn)
 {
   enum mips_symbol_type type;
   rtx x, set;
@@ -16124,7 +16099,7 @@ mips_orphaned_high_part_p (mips_offset_table htab, rtx insn)
    LO_REG is an rtx for the LO register, used in dependence checking.  */
 
 static void
-mips_avoid_hazard (rtx after, rtx insn, int *hilo_delay,
+mips_avoid_hazard (rtx_insn *after, rtx_insn *insn, int *hilo_delay,
                   rtx *delayed_reg, rtx lo_reg)
 {
   rtx pattern, set;
@@ -16189,9 +16164,9 @@ mips_avoid_hazard (rtx after, rtx insn, int *hilo_delay,
 static void
 mips_reorg_process_insns (void)
 {
-  rtx insn, last_insn, subinsn, next_insn, lo_reg, delayed_reg;
+  rtx_insn *insn, *last_insn, *subinsn, *next_insn;
+  rtx lo_reg, delayed_reg;
   int hilo_delay;
-  mips_offset_table htab;
 
   /* Force all instructions to be split into their final form.  */
   split_all_insns_noflow ();
@@ -16232,7 +16207,7 @@ mips_reorg_process_insns (void)
   if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
     cfun->machine->all_noreorder_p = false;
 
-  htab.create (37);
+  mips_offset_table htab (37);
 
   /* Make a first pass over the instructions, recording all the LO_SUMs.  */
   for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
@@ -16277,7 +16252,7 @@ mips_reorg_process_insns (void)
              FOR_EACH_SUBINSN (subinsn, insn)
                if (INSN_P (subinsn))
                  {
-                   if (mips_orphaned_high_part_p (htab, subinsn))
+                   if (mips_orphaned_high_part_p (&htab, subinsn))
                      {
                        PATTERN (subinsn) = gen_nop ();
                        INSN_CODE (subinsn) = CODE_FOR_nop;
@@ -16291,7 +16266,7 @@ mips_reorg_process_insns (void)
            {
              /* INSN is a single instruction.  Delete it if it's an
                 orphaned high-part relocation.  */
-             if (mips_orphaned_high_part_p (htab, insn))
+             if (mips_orphaned_high_part_p (&htab, insn))
                delete_insn (insn);
              /* Also delete cache barriers if the last instruction
                 was an annulled branch.  INSN will not be speculatively
@@ -16310,8 +16285,6 @@ mips_reorg_process_insns (void)
            }
        }
     }
-
-  htab.dispose ();
 }
 
 /* Return true if the function has a long branch instruction.  */
@@ -16319,7 +16292,7 @@ mips_reorg_process_insns (void)
 static bool
 mips_has_long_branch_p (void)
 {
-  rtx insn, subinsn;
+  rtx_insn *insn, *subinsn;
   int normal_length;
 
   /* We need up-to-date instruction lengths.  */
@@ -16428,7 +16401,7 @@ mips16_split_long_branches (void)
   /* Loop until the alignments for all targets are sufficient.  */
   do
     {
-      rtx insn;
+      rtx_insn *insn;
 
       shorten_branches (get_insns ());
       something_changed = false;
@@ -16437,8 +16410,10 @@ mips16_split_long_branches (void)
            && get_attr_length (insn) > 4
            && (any_condjump_p (insn) || any_uncondjump_p (insn)))
          {
-           rtx old_label, new_label, temp, saved_temp;
-           rtx target, jump, jump_sequence;
+           rtx old_label, temp, saved_temp;
+           rtx_code_label *new_label;
+           rtx target;
+           rtx_insn *jump, *jump_sequence;
 
            start_sequence ();
 
@@ -16465,7 +16440,7 @@ mips16_split_long_branches (void)
 
            if (simplejump_p (insn))
              /* We're going to replace INSN with a longer form.  */
-             new_label = NULL_RTX;
+             new_label = NULL;
            else
              {
                /* Create a branch-around label for the original
@@ -16533,14 +16508,12 @@ const pass_data pass_data_mips_machine_reorg2 =
   RTL_PASS, /* type */
   "mach2", /* name */
   OPTGROUP_NONE, /* optinfo_flags */
-  false, /* has_gate */
-  true, /* has_execute */
   TV_MACH_DEP, /* tv_id */
   0, /* properties_required */
   0, /* properties_provided */
   0, /* properties_destroyed */
   0, /* todo_flags_start */
-  TODO_verify_rtl_sharing, /* todo_flags_finish */
+  0, /* todo_flags_finish */
 };
 
 class pass_mips_machine_reorg2 : public rtl_opt_pass
@@ -16551,7 +16524,7 @@ public:
   {}
 
   /* opt_pass methods: */
-  unsigned int execute () { return mips_machine_reorg2 (); }
+  virtual unsigned int execute (function *) { return mips_machine_reorg2 (); }
 
 }; // class pass_mips_machine_reorg2
 
@@ -16572,7 +16545,8 @@ mips_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED,
                      HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
                      tree function)
 {
-  rtx this_rtx, temp1, temp2, insn, fnaddr;
+  rtx this_rtx, temp1, temp2, fnaddr;
+  rtx_insn *insn;
   bool use_sibcall_p;
 
   /* Pretend to be a post-reload pass while generating rtl.  */
@@ -16826,7 +16800,7 @@ mips_set_current_function (tree fndecl)
 static struct machine_function *
 mips_init_machine_status (void)
 {
-  return ggc_alloc_cleared_machine_function ();
+  return ggc_cleared_alloc<machine_function> ();
 }
 
 /* Return the processor associated with the given ISA level, or null
@@ -16901,6 +16875,10 @@ mips_set_architecture (const struct mips_cpu_info *info)
       mips_arch_info = info;
       mips_arch = info->cpu;
       mips_isa = info->isa;
+      if (mips_isa < 32)
+       mips_isa_rev = 0;
+      else
+       mips_isa_rev = (mips_isa & 31) + 1;
     }
 }
 
@@ -17502,28 +17480,6 @@ mips_conditional_register_usage (void)
     }
 }
 
-/* When generating MIPS16 code, we want to allocate $24 (T_REG) before
-   other registers for instructions for which it is possible.  This
-   encourages the compiler to use CMP in cases where an XOR would
-   require some register shuffling.  */
-
-void
-mips_order_regs_for_local_alloc (void)
-{
-  int i;
-
-  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    reg_alloc_order[i] = i;
-
-  if (TARGET_MIPS16)
-    {
-      /* It really doesn't matter where we put register 0, since it is
-         a fixed register anyhow.  */
-      reg_alloc_order[0] = 24;
-      reg_alloc_order[24] = 0;
-    }
-}
-
 /* Implement EH_USES.  */
 
 bool
@@ -17586,7 +17542,7 @@ mips_at_reg_p (rtx *x, void *data ATTRIBUTE_UNUSED)
    INSN has NOPERANDS operands, stored in OPVEC.  */
 
 static bool
-mips_need_noat_wrapper_p (rtx insn, rtx *opvec, int noperands)
+mips_need_noat_wrapper_p (rtx_insn *insn, rtx *opvec, int noperands)
 {
   int i;
 
@@ -17600,7 +17556,7 @@ mips_need_noat_wrapper_p (rtx insn, rtx *opvec, int noperands)
 /* Implement FINAL_PRESCAN_INSN.  */
 
 void
-mips_final_prescan_insn (rtx insn, rtx *opvec, int noperands)
+mips_final_prescan_insn (rtx_insn *insn, rtx *opvec, int noperands)
 {
   if (mips_need_noat_wrapper_p (insn, opvec, noperands))
     mips_push_asm_switch (&mips_noat);
@@ -17609,7 +17565,7 @@ mips_final_prescan_insn (rtx insn, rtx *opvec, int noperands)
 /* Implement TARGET_ASM_FINAL_POSTSCAN_INSN.  */
 
 static void
-mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED, rtx insn,
+mips_final_postscan_insn (FILE *file ATTRIBUTE_UNUSED, rtx_insn *insn,
                          rtx *opvec, int noperands)
 {
   if (mips_need_noat_wrapper_p (insn, opvec, noperands))
@@ -18205,6 +18161,7 @@ mips_expand_vselect (rtx target, rtx op0,
                     const unsigned char *perm, unsigned nelt)
 {
   rtx rperm[MAX_VECT_LEN], x;
+  rtx_insn *insn;
   unsigned i;
 
   for (i = 0; i < nelt; ++i)
@@ -18214,10 +18171,10 @@ mips_expand_vselect (rtx target, rtx op0,
   x = gen_rtx_VEC_SELECT (GET_MODE (target), op0, x);
   x = gen_rtx_SET (VOIDmode, target, x);
 
-  x = emit_insn (x);
-  if (recog_memoized (x) < 0)
+  insn = emit_insn (x);
+  if (recog_memoized (insn) < 0)
     {
-      remove_insn (x);
+      remove_insn (insn);
       return false;
     }
   return true;
@@ -18898,6 +18855,25 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
   *update = build2 (COMPOUND_EXPR, void_type_node, *update,
                    atomic_feraiseexcept_call);
 }
+
+/* Implement TARGET_SPILL_CLASS.  */
+
+static reg_class_t
+mips_spill_class (reg_class_t rclass ATTRIBUTE_UNUSED,
+                 enum machine_mode mode ATTRIBUTE_UNUSED)
+{
+  if (TARGET_MIPS16)
+    return SPILL_REGS;
+  return NO_REGS;
+}
+
+/* Implement TARGET_LRA_P.  */
+
+static bool
+mips_lra_p (void)
+{
+  return mips_lra_flag;
+}
 \f
 /* Initialize the GCC target structure.  */
 #undef TARGET_ASM_ALIGNED_HI_OP
@@ -18961,6 +18937,8 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
 #define TARGET_VALID_POINTER_MODE mips_valid_pointer_mode
 #undef TARGET_REGISTER_MOVE_COST
 #define TARGET_REGISTER_MOVE_COST mips_register_move_cost
+#undef TARGET_REGISTER_PRIORITY
+#define TARGET_REGISTER_PRIORITY mips_register_priority
 #undef TARGET_MEMORY_MOVE_COST
 #define TARGET_MEMORY_MOVE_COST mips_memory_move_cost
 #undef TARGET_RTX_COSTS
@@ -19135,6 +19113,14 @@ mips_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
 #undef TARGET_ATOMIC_ASSIGN_EXPAND_FENV
 #define TARGET_ATOMIC_ASSIGN_EXPAND_FENV mips_atomic_assign_expand_fenv
 
+#undef TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS
+#define TARGET_CALL_FUSAGE_CONTAINS_NON_CALLEE_CLOBBERS true
+
+#undef TARGET_SPILL_CLASS
+#define TARGET_SPILL_CLASS mips_spill_class
+#undef TARGET_LRA_P
+#define TARGET_LRA_P mips_lra_p
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 \f
 #include "gt-mips.h"