* mips-tdep.c (mips_next_pc): Use is_mips16_addr() instead of
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index b27bc20708272e38c7a2f3d923b5f5f3915dd9ac..b4153fd0fdf3f7898e1877dc2ff6bcf1f0f3af1d 100644 (file)
@@ -1,8 +1,8 @@
 /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
 
-   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software
-   Foundation, Inc.
+   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
 
    Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
    and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
@@ -21,8 +21,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 #include "defs.h"
 #include "gdb_string.h"
 #include "trad-frame.h"
 #include "infcall.h"
 #include "floatformat.h"
+#include "remote.h"
+#include "target-descriptions.h"
+#include "dwarf2-frame.h"
+#include "user-regs.h"
 
 static const struct objfile_data *mips_pdr_data;
 
 static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum);
 
-/* A useful bit in the CP0 status register (PS_REGNUM).  */
+/* A useful bit in the CP0 status register (MIPS_PS_REGNUM).  */
 /* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip.  */
 #define ST0_FR (1 << 26)
 
@@ -72,6 +76,11 @@ enum
   MIPS_FPU_DOUBLE_REGSIZE = 8
 };
 
+enum
+{
+  MIPS32_REGSIZE = 4,
+  MIPS64_REGSIZE = 8
+};
 
 static const char *mips_abi_string;
 
@@ -86,25 +95,53 @@ static const char *mips_abi_strings[] = {
   NULL
 };
 
-struct frame_extra_info
+/* The standard register names, and all the valid aliases for them.  */
+struct register_alias
 {
-  mips_extra_func_info_t proc_desc;
-  int num_args;
+  const char *name;
+  int regnum;
 };
 
-/* Various MIPS ISA options (related to stack analysis) can be
-   overridden dynamically.  Establish an enum/array for managing
-   them. */
+/* Aliases for o32 and most other ABIs.  */
+const struct register_alias mips_o32_aliases[] = {
+  { "ta0", 12 },
+  { "ta1", 13 },
+  { "ta2", 14 },
+  { "ta3", 15 }
+};
 
-static const char size_auto[] = "auto";
-static const char size_32[] = "32";
-static const char size_64[] = "64";
+/* Aliases for n32 and n64.  */
+const struct register_alias mips_n32_n64_aliases[] = {
+  { "ta0", 8 },
+  { "ta1", 9 },
+  { "ta2", 10 },
+  { "ta3", 11 }
+};
 
-static const char *size_enums[] = {
-  size_auto,
-  size_32,
-  size_64,
-  0
+/* Aliases for ABI-independent registers.  */
+const struct register_alias mips_register_aliases[] = {
+  /* The architecture manuals specify these ABI-independent names for
+     the GPRs.  */
+#define R(n) { "r" #n, n }
+  R(0), R(1), R(2), R(3), R(4), R(5), R(6), R(7),
+  R(8), R(9), R(10), R(11), R(12), R(13), R(14), R(15),
+  R(16), R(17), R(18), R(19), R(20), R(21), R(22), R(23),
+  R(24), R(25), R(26), R(27), R(28), R(29), R(30), R(31),
+#undef R
+
+  /* k0 and k1 are sometimes called these instead (for "kernel
+     temp").  */
+  { "kt0", 26 },
+  { "kt1", 27 },
+
+  /* This is the traditional GDB name for the CP0 status register.  */
+  { "sr", MIPS_PS_REGNUM },
+
+  /* This is the traditional GDB name for the CP0 BadVAddr register.  */
+  { "bad", MIPS_EMBED_BADVADDR_REGNUM },
+
+  /* This is the traditional GDB name for the FCSR.  */
+  { "fsr", MIPS_EMBED_FP0_REGNUM + 32 }
 };
 
 /* Some MIPS boards don't support floating point while others only
@@ -125,6 +162,11 @@ static enum mips_fpu_type mips_fpu_type = MIPS_DEFAULT_FPU_TYPE;
 
 static int mips_debug = 0;
 
+/* Properties (for struct target_desc) describing the g/G packet
+   layout.  */
+#define PROPERTY_GP32 "internal: transfers-32bit-registers"
+#define PROPERTY_GP64 "internal: transfers-64bit-registers"
+
 /* MIPS specific per-architecture information */
 struct gdbarch_tdep
 {
@@ -147,11 +189,18 @@ struct gdbarch_tdep
   const struct mips_regnum *regnum;
   /* Register names table for the current register set.  */
   const char **mips_processor_reg_names;
+
+  /* The size of register data available from the target, if known.
+     This doesn't quite obsolete the manual
+     mips64_transfers_32bit_regs_p, since that is documented to force
+     left alignment even for big endian (very strange).  */
+  int register_size_valid_p;
+  int register_size;
 };
 
 static int
 n32n64_floatformat_always_valid (const struct floatformat *fmt,
-                                 const char *from)
+                                 const void *from)
 {
   return 1;
 }
@@ -171,10 +220,16 @@ static const struct floatformat floatformat_n32n64_long_double_big =
 {
   floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
   floatformat_intbit_no,
-  "floatformat_ieee_double_big",
+  "floatformat_n32n64_long_double_big",
   n32n64_floatformat_always_valid
 };
 
+static const struct floatformat *floatformats_n32n64_long[BFD_ENDIAN_UNKNOWN] =
+{
+  &floatformat_n32n64_long_double_big,
+  &floatformat_n32n64_long_double_big
+};
+
 const struct mips_regnum *
 mips_regnum (struct gdbarch *gdbarch)
 {
@@ -208,37 +263,7 @@ is_mips16_addr (CORE_ADDR addr)
 static CORE_ADDR
 unmake_mips16_addr (CORE_ADDR addr)
 {
-  return ((addr) & ~1);
-}
-
-/* Return the contents of register REGNUM as a signed integer.  */
-
-static LONGEST
-read_signed_register (int regnum)
-{
-  LONGEST val;
-  regcache_cooked_read_signed (current_regcache, regnum, &val);
-  return val;
-}
-
-static LONGEST
-read_signed_register_pid (int regnum, ptid_t ptid)
-{
-  ptid_t save_ptid;
-  LONGEST retval;
-
-  if (ptid_equal (ptid, inferior_ptid))
-    return read_signed_register (regnum);
-
-  save_ptid = inferior_ptid;
-
-  inferior_ptid = ptid;
-
-  retval = read_signed_register (regnum);
-
-  inferior_ptid = save_ptid;
-
-  return retval;
+  return ((addr) & ~(CORE_ADDR) 1);
 }
 
 /* Return the MIPS ABI associated with GDBARCH.  */
@@ -251,44 +276,44 @@ mips_abi (struct gdbarch *gdbarch)
 int
 mips_isa_regsize (struct gdbarch *gdbarch)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  /* If we know how big the registers are, use that size.  */
+  if (tdep->register_size_valid_p)
+    return tdep->register_size;
+
+  /* Fall back to the previous behavior.  */
   return (gdbarch_bfd_arch_info (gdbarch)->bits_per_word
          / gdbarch_bfd_arch_info (gdbarch)->bits_per_byte);
 }
 
 /* Return the currently configured (or set) saved register size. */
 
-static const char *mips_abi_regsize_string = size_auto;
-
 unsigned int
 mips_abi_regsize (struct gdbarch *gdbarch)
 {
-  if (mips_abi_regsize_string == size_auto)
-    switch (mips_abi (gdbarch))
-      {
-      case MIPS_ABI_EABI32:
-      case MIPS_ABI_O32:
-       return 4;
-      case MIPS_ABI_N32:
-      case MIPS_ABI_N64:
-      case MIPS_ABI_O64:
-      case MIPS_ABI_EABI64:
-       return 8;
-      case MIPS_ABI_UNKNOWN:
-      case MIPS_ABI_LAST:
-      default:
-       internal_error (__FILE__, __LINE__, "bad switch");
-      }
-  else if (mips_abi_regsize_string == size_64)
-    return 8;
-  else                         /* if (mips_abi_regsize_string == size_32) */
-    return 4;
+  switch (mips_abi (gdbarch))
+    {
+    case MIPS_ABI_EABI32:
+    case MIPS_ABI_O32:
+      return 4;
+    case MIPS_ABI_N32:
+    case MIPS_ABI_N64:
+    case MIPS_ABI_O64:
+    case MIPS_ABI_EABI64:
+      return 8;
+    case MIPS_ABI_UNKNOWN:
+    case MIPS_ABI_LAST:
+    default:
+      internal_error (__FILE__, __LINE__, _("bad switch"));
+    }
 }
 
 /* Functions for setting and testing a bit in a minimal symbol that
    marks it as 16-bit function.  The MSB of the minimal symbol's
    "info" field is used for this purpose.
 
-   ELF_MAKE_MSYMBOL_SPECIAL tests whether an ELF symbol is "special",
+   gdbarch_elf_make_msymbol_special tests whether an ELF symbol is "special",
    i.e. refers to a 16-bit function, and sets a "special" bit in a
    minimal symbol to mark it as a 16-bit function
 
@@ -318,11 +343,11 @@ msymbol_is_special (struct minimal_symbol *msym)
 
 static void
 mips_xfer_register (struct regcache *regcache, int reg_num, int length,
-                   enum bfd_endian endian, bfd_byte * in,
-                   const bfd_byte * out, int buf_offset)
+                   enum bfd_endian endian, gdb_byte *in,
+                   const gdb_byte *out, int buf_offset)
 {
   int reg_offset = 0;
-  gdb_assert (reg_num >= NUM_REGS);
+  gdb_assert (reg_num >= gdbarch_num_regs (current_gdbarch));
   /* Need to transfer the left or right part of the register, based on
      the targets byte order.  */
   switch (endian)
@@ -337,7 +362,7 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length,
       reg_offset = 0;
       break;
     default:
-      internal_error (__FILE__, __LINE__, "bad switch");
+      internal_error (__FILE__, __LINE__, _("bad switch"));
     }
   if (mips_debug)
     fprintf_unfiltered (gdb_stderr,
@@ -372,7 +397,7 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length,
    physical 64-bit registers, but should treat them as 32-bit registers.  */
 
 static int
-mips2_fp_compat (void)
+mips2_fp_compat (struct frame_info *frame)
 {
   /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
      meaningful.  */
@@ -386,36 +411,17 @@ mips2_fp_compat (void)
   /* Otherwise check the FR bit in the status register - it controls
      the FP compatiblity mode.  If it is clear we are in compatibility
      mode.  */
-  if ((read_register (PS_REGNUM) & ST0_FR) == 0)
+  if ((get_frame_register_unsigned (frame, MIPS_PS_REGNUM) & ST0_FR) == 0)
     return 1;
 #endif
 
   return 0;
 }
 
-/* The amount of space reserved on the stack for registers. This is
-   different to MIPS_ABI_REGSIZE as it determines the alignment of
-   data allocated after the registers have run out. */
-
-static const char *mips_stack_argsize_string = size_auto;
-
-static unsigned int
-mips_stack_argsize (struct gdbarch *gdbarch)
-{
-  if (mips_stack_argsize_string == size_auto)
-    return mips_abi_regsize (gdbarch);
-  else if (mips_stack_argsize_string == size_64)
-    return 8;
-  else                         /* if (mips_stack_argsize_string == size_32) */
-    return 4;
-}
-
 #define VM_MIN_ADDRESS (CORE_ADDR)0x400000
 
 static CORE_ADDR heuristic_proc_start (CORE_ADDR);
 
-static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
-
 static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
 
 static struct type *mips_float_register_type (void);
@@ -428,7 +434,7 @@ static struct cmd_list_element *showmipscmdlist = NULL;
 
 /* Integer registers 0 thru 31 are handled explicitly by
    mips_register_name().  Processor specific registers 32 and above
-   are listed in the followign tables.  */
+   are listed in the following tables.  */
 
 enum
 { NUM_MIPS_PROCESSOR_REGS = (90 - 32) };
@@ -505,10 +511,10 @@ mips_register_name (int regno)
 
   enum mips_abi abi = mips_abi (current_gdbarch);
 
-  /* Map [NUM_REGS .. 2*NUM_REGS) onto the raw registers, but then
-     don't make the raw register names visible.  */
-  int rawnum = regno % NUM_REGS;
-  if (regno < NUM_REGS)
+  /* Map [gdbarch_num_regs .. 2*gdbarch_num_regs) onto the raw registers, 
+     but then don't make the raw register names visible.  */
+  int rawnum = regno % gdbarch_num_regs (current_gdbarch);
+  if (regno < gdbarch_num_regs (current_gdbarch))
     return "";
 
   /* The MIPS integer registers are always mapped from 0 to 31.  The
@@ -521,14 +527,16 @@ mips_register_name (int regno)
       else
        return mips_gpr_names[rawnum];
     }
-  else if (32 <= rawnum && rawnum < NUM_REGS)
+  else if (tdesc_has_registers (gdbarch_target_desc (current_gdbarch)))
+    return tdesc_register_name (rawnum);
+  else if (32 <= rawnum && rawnum < gdbarch_num_regs (current_gdbarch))
     {
       gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS);
       return tdep->mips_processor_reg_names[rawnum - 32];
     }
   else
     internal_error (__FILE__, __LINE__,
-                   "mips_register_name: bad register number %d", rawnum);
+                   _("mips_register_name: bad register number %d"), rawnum);
 }
 
 /* Return the groups that a MIPS register can be categorised into.  */
@@ -540,16 +548,17 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   int vector_p;
   int float_p;
   int raw_p;
-  int rawnum = regnum % NUM_REGS;
-  int pseudo = regnum / NUM_REGS;
+  int rawnum = regnum % gdbarch_num_regs (current_gdbarch);
+  int pseudo = regnum / gdbarch_num_regs (current_gdbarch);
   if (reggroup == all_reggroup)
     return pseudo;
   vector_p = TYPE_VECTOR (register_type (gdbarch, regnum));
   float_p = TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT;
   /* FIXME: cagney/2003-04-13: Can't yet use gdbarch_num_regs
      (gdbarch), as not all architectures are multi-arch.  */
-  raw_p = rawnum < NUM_REGS;
-  if (REGISTER_NAME (regnum) == NULL || REGISTER_NAME (regnum)[0] == '\0')
+  raw_p = rawnum < gdbarch_num_regs (current_gdbarch);
+  if (gdbarch_register_name (current_gdbarch, regnum) == NULL
+      || gdbarch_register_name (current_gdbarch, regnum)[0] == '\0')
     return 0;
   if (reggroup == float_reggroup)
     return float_p && pseudo;
@@ -568,51 +577,82 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
   return 0;
 }
 
+/* Return the groups that a MIPS register can be categorised into.
+   This version is only used if we have a target description which
+   describes real registers (and their groups).  */
+
+static int
+mips_tdesc_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+                               struct reggroup *reggroup)
+{
+  int rawnum = regnum % gdbarch_num_regs (gdbarch);
+  int pseudo = regnum / gdbarch_num_regs (gdbarch);
+  int ret;
+
+  /* Only save, restore, and display the pseudo registers.  Need to
+     make certain that any code extracting register values from a
+     saved register cache also uses pseudo registers.
+
+     Note: saving and restoring the pseudo registers is slightly
+     strange; if we have 64 bits, we should save and restore all
+     64 bits.  But this is hard and has little benefit.  */
+  if (!pseudo)
+    return 0;
+
+  ret = tdesc_register_in_reggroup_p (gdbarch, rawnum, reggroup);
+  if (ret != -1)
+    return ret;
+
+  return mips_register_reggroup_p (gdbarch, regnum, reggroup);
+}
+
 /* Map the symbol table registers which live in the range [1 *
-   NUM_REGS .. 2 * NUM_REGS) back onto the corresponding raw
+   gdbarch_num_regs .. 2 * gdbarch_num_regs) back onto the corresponding raw
    registers.  Take care of alignment and size problems.  */
 
 static void
 mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
-                          int cookednum, void *buf)
+                          int cookednum, gdb_byte *buf)
 {
-  int rawnum = cookednum % NUM_REGS;
-  gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
+  int rawnum = cookednum % gdbarch_num_regs (current_gdbarch);
+  gdb_assert (cookednum >= gdbarch_num_regs (current_gdbarch)
+             && cookednum < 2 * gdbarch_num_regs (current_gdbarch));
   if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
     regcache_raw_read (regcache, rawnum, buf);
   else if (register_size (gdbarch, rawnum) >
           register_size (gdbarch, cookednum))
     {
       if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
-         || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+         || gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
        regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
       else
        regcache_raw_read_part (regcache, rawnum, 4, 4, buf);
     }
   else
-    internal_error (__FILE__, __LINE__, "bad register size");
+    internal_error (__FILE__, __LINE__, _("bad register size"));
 }
 
 static void
 mips_pseudo_register_write (struct gdbarch *gdbarch,
                            struct regcache *regcache, int cookednum,
-                           const void *buf)
+                           const gdb_byte *buf)
 {
-  int rawnum = cookednum % NUM_REGS;
-  gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
+  int rawnum = cookednum % gdbarch_num_regs (current_gdbarch);
+  gdb_assert (cookednum >= gdbarch_num_regs (current_gdbarch)
+             && cookednum < 2 * gdbarch_num_regs (current_gdbarch));
   if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
     regcache_raw_write (regcache, rawnum, buf);
   else if (register_size (gdbarch, rawnum) >
           register_size (gdbarch, cookednum))
     {
       if (gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p
-         || TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE)
+         || gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_LITTLE)
        regcache_raw_write_part (regcache, rawnum, 0, 4, buf);
       else
        regcache_raw_write_part (regcache, rawnum, 4, 4, buf);
     }
   else
-    internal_error (__FILE__, __LINE__, "bad register size");
+    internal_error (__FILE__, __LINE__, _("bad register size"));
 }
 
 /* Table to translate MIPS16 register field to actual register number.  */
@@ -642,7 +682,7 @@ set_mips64_transfers_32bit_regs (char *args, int from_tty,
   if (!gdbarch_update_p (info))
     {
       mips64_transfers_32bit_regs_p = 0;
-      error ("32-bit compatibility mode not supported");
+      error (_("32-bit compatibility mode not supported"));
     }
 }
 
@@ -651,27 +691,29 @@ set_mips64_transfers_32bit_regs (char *args, int from_tty,
 static int
 mips_convert_register_p (int regnum, struct type *type)
 {
-  return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+  return (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
          && register_size (current_gdbarch, regnum) == 4
-         && (regnum % NUM_REGS) >= mips_regnum (current_gdbarch)->fp0
-         && (regnum % NUM_REGS) < mips_regnum (current_gdbarch)->fp0 + 32
+         && (regnum % gdbarch_num_regs (current_gdbarch))
+               >= mips_regnum (current_gdbarch)->fp0
+         && (regnum % gdbarch_num_regs (current_gdbarch))
+               < mips_regnum (current_gdbarch)->fp0 + 32
          && TYPE_CODE (type) == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8);
 }
 
 static void
 mips_register_to_value (struct frame_info *frame, int regnum,
-                       struct type *type, void *to)
+                       struct type *type, gdb_byte *to)
 {
-  get_frame_register (frame, regnum + 0, (char *) to + 4);
-  get_frame_register (frame, regnum + 1, (char *) to + 0);
+  get_frame_register (frame, regnum + 0, to + 4);
+  get_frame_register (frame, regnum + 1, to + 0);
 }
 
 static void
 mips_value_to_register (struct frame_info *frame, int regnum,
-                       struct type *type, const void *from)
+                       struct type *type, const gdb_byte *from)
 {
-  put_frame_register (frame, regnum + 0, (const char *) from + 4);
-  put_frame_register (frame, regnum + 1, (const char *) from + 0);
+  put_frame_register (frame, regnum + 0, from + 4);
+  put_frame_register (frame, regnum + 1, from + 0);
 }
 
 /* Return the GDB type object for the "standard" data type of data in
@@ -680,30 +722,20 @@ mips_value_to_register (struct frame_info *frame, int regnum,
 static struct type *
 mips_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  gdb_assert (regnum >= 0 && regnum < 2 * NUM_REGS);
-  if ((regnum % NUM_REGS) >= mips_regnum (current_gdbarch)->fp0
-      && (regnum % NUM_REGS) < mips_regnum (current_gdbarch)->fp0 + 32)
+  gdb_assert (regnum >= 0 && regnum < 2 * gdbarch_num_regs (current_gdbarch));
+  if ((regnum % gdbarch_num_regs (current_gdbarch))
+       >= mips_regnum (current_gdbarch)->fp0
+      && (regnum % gdbarch_num_regs (current_gdbarch))
+       < mips_regnum (current_gdbarch)->fp0 + 32)
     {
       /* The floating-point registers raw, or cooked, always match
          mips_isa_regsize(), and also map 1:1, byte for byte.  */
-      switch (gdbarch_byte_order (gdbarch))
-       {
-       case BFD_ENDIAN_BIG:
-         if (mips_isa_regsize (gdbarch) == 4)
-           return builtin_type_ieee_single_big;
-         else
-           return builtin_type_ieee_double_big;
-       case BFD_ENDIAN_LITTLE:
-         if (mips_isa_regsize (gdbarch) == 4)
-           return builtin_type_ieee_single_little;
-         else
-           return builtin_type_ieee_double_little;
-       case BFD_ENDIAN_UNKNOWN:
-       default:
-         internal_error (__FILE__, __LINE__, "bad switch");
-       }
+      if (mips_isa_regsize (gdbarch) == 4)
+       return builtin_type_ieee_single;
+      else
+       return builtin_type_ieee_double;
     }
-  else if (regnum < NUM_REGS)
+  else if (regnum < gdbarch_num_regs (current_gdbarch))
     {
       /* The raw or ISA registers.  These are all sized according to
         the ISA regsize.  */
@@ -716,9 +748,10 @@ mips_register_type (struct gdbarch *gdbarch, int regnum)
     {
       /* The cooked or ABI registers.  These are sized according to
         the ABI (with a few complications).  */
-      if (regnum >= (NUM_REGS
+      if (regnum >= (gdbarch_num_regs (current_gdbarch)
                     + mips_regnum (current_gdbarch)->fp_control_status)
-         && regnum <= NUM_REGS + LAST_EMBED_REGNUM)
+         && regnum <= gdbarch_num_regs (current_gdbarch)
+                      + MIPS_LAST_EMBED_REGNUM)
        /* The pseudo/cooked view of the embedded registers is always
           32-bit.  The raw view is handled below.  */
        return builtin_type_int32;
@@ -737,12 +770,58 @@ mips_register_type (struct gdbarch *gdbarch, int regnum)
     }
 }
 
-/* TARGET_READ_SP -- Remove useless bits from the stack pointer.  */
+/* Return the GDB type for the pseudo register REGNUM, which is the
+   ABI-level view.  This function is only called if there is a target
+   description which includes registers, so we know precisely the
+   types of hardware registers.  */
 
-static CORE_ADDR
-mips_read_sp (void)
+static struct type *
+mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  return read_signed_register (MIPS_SP_REGNUM);
+  const int num_regs = gdbarch_num_regs (gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int rawnum = regnum % num_regs;
+  struct type *rawtype;
+
+  gdb_assert (regnum >= num_regs && regnum < 2 * num_regs);
+
+  /* Absent registers are still absent.  */
+  rawtype = gdbarch_register_type (gdbarch, rawnum);
+  if (TYPE_LENGTH (rawtype) == 0)
+    return rawtype;
+
+  if (rawnum >= MIPS_EMBED_FP0_REGNUM && rawnum < MIPS_EMBED_FP0_REGNUM + 32)
+    /* Present the floating point registers however the hardware did;
+       do not try to convert between FPU layouts.  */
+    return rawtype;
+
+  if (rawnum >= MIPS_EMBED_FP0_REGNUM + 32 && rawnum <= MIPS_LAST_EMBED_REGNUM)
+    {
+      /* The pseudo/cooked view of embedded registers is always
+        32-bit, even if the target transfers 64-bit values for them.
+        New targets relying on XML descriptions should only transfer
+        the necessary 32 bits, but older versions of GDB expected 64,
+        so allow the target to provide 64 bits without interfering
+        with the displayed type.  */
+      return builtin_type_int32;
+    }
+
+  /* Use pointer types for registers if we can.  For n32 we can not,
+     since we do not have a 64-bit pointer type.  */
+  if (mips_abi_regsize (gdbarch) == TYPE_LENGTH (builtin_type_void_data_ptr))
+    {
+      if (rawnum == MIPS_SP_REGNUM || rawnum == MIPS_EMBED_BADVADDR_REGNUM)
+       return builtin_type_void_data_ptr;
+      else if (rawnum == MIPS_EMBED_PC_REGNUM)
+       return builtin_type_void_func_ptr;
+    }
+
+  if (mips_abi_regsize (gdbarch) == 4 && TYPE_LENGTH (rawtype) == 8
+      && rawnum >= MIPS_ZERO_REGNUM && rawnum <= MIPS_EMBED_PC_REGNUM)
+    return builtin_type_int32;
+
+  /* For all other registers, pass through the hardware type.  */
+  return rawtype;
 }
 
 /* Should the upper word of 64-bit addresses be zeroed? */
@@ -761,15 +840,18 @@ mips_mask_address_p (struct gdbarch_tdep *tdep)
     case AUTO_BOOLEAN_AUTO:
       return tdep->default_mask_address_p;
     default:
-      internal_error (__FILE__, __LINE__, "mips_mask_address_p: bad switch");
+      internal_error (__FILE__, __LINE__, _("mips_mask_address_p: bad switch"));
       return -1;
     }
 }
 
 static void
-show_mask_address (char *cmd, int from_tty, struct cmd_list_element *c)
+show_mask_address (struct ui_file *file, int from_tty,
+                  struct cmd_list_element *c, const char *value)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  deprecated_show_value_hack (file, from_tty, c, value);
   switch (mask_address_var)
     {
     case AUTO_BOOLEAN_TRUE:
@@ -784,7 +866,7 @@ show_mask_address (char *cmd, int from_tty, struct cmd_list_element *c)
         mips_mask_address_p (tdep) ? "enabled" : "disabled");
       break;
     default:
-      internal_error (__FILE__, __LINE__, "show_mask_address: bad switch");
+      internal_error (__FILE__, __LINE__, _("show_mask_address: bad switch"));
       break;
     }
 }
@@ -814,16 +896,28 @@ mips_pc_is_mips16 (CORE_ADDR memaddr)
    all registers should be sign extended for simplicity? */
 
 static CORE_ADDR
-mips_read_pc (ptid_t ptid)
+mips_read_pc (struct regcache *regcache)
 {
-  return read_signed_register_pid (mips_regnum (current_gdbarch)->pc, ptid);
+  ULONGEST pc;
+  int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
+  regcache_cooked_read_signed (regcache, regnum, &pc);
+  return pc;
 }
 
 static CORE_ADDR
 mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
   return frame_unwind_register_signed (next_frame,
-                                      NUM_REGS + mips_regnum (gdbarch)->pc);
+                                      gdbarch_num_regs (current_gdbarch)
+                                      + mips_regnum (gdbarch)->pc);
+}
+
+static CORE_ADDR
+mips_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+  return frame_unwind_register_signed (next_frame,
+                                      gdbarch_num_regs (current_gdbarch)
+                                      + MIPS_SP_REGNUM);
 }
 
 /* Assuming NEXT_FRAME->prev is a dummy, return the frame ID of that
@@ -834,14 +928,18 @@ mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
 static struct frame_id
 mips_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
 {
-  return frame_id_build (frame_unwind_register_signed (next_frame, NUM_REGS + MIPS_SP_REGNUM),
-                        frame_pc_unwind (next_frame));
+  return frame_id_build
+          (frame_unwind_register_signed (next_frame,
+                                         gdbarch_num_regs (current_gdbarch)
+                                         + MIPS_SP_REGNUM),
+                                         frame_pc_unwind (next_frame));
 }
 
 static void
-mips_write_pc (CORE_ADDR pc, ptid_t ptid)
+mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  write_register_pid (mips_regnum (current_gdbarch)->pc, pc, ptid);
+  int regnum = mips_regnum (get_regcache_arch (regcache))->pc;
+  regcache_cooked_write_unsigned (regcache, regnum, pc);
 }
 
 /* Fetch and return instruction from the specified location.  If the PC
@@ -850,7 +948,7 @@ mips_write_pc (CORE_ADDR pc, ptid_t ptid)
 static ULONGEST
 mips_fetch_instruction (CORE_ADDR addr)
 {
-  char buf[MIPS_INSN32_SIZE];
+  gdb_byte buf[MIPS_INSN32_SIZE];
   int instlen;
   int status;
 
@@ -861,7 +959,7 @@ mips_fetch_instruction (CORE_ADDR addr)
     }
   else
     instlen = MIPS_INSN32_SIZE;
-  status = deprecated_read_memory_nobpt (addr, buf, instlen);
+  status = read_memory_nobpt (addr, buf, instlen);
   if (status)
     memory_error (status, addr);
   return extract_unsigned_integer (buf, instlen);
@@ -884,23 +982,16 @@ mips_fetch_instruction (CORE_ADDR addr)
 #define rtype_shamt(x) ((x >> 6) & 0x1f)
 #define rtype_funct(x) (x & 0x3f)
 
-static CORE_ADDR
-mips32_relative_offset (unsigned long inst)
+static LONGEST
+mips32_relative_offset (ULONGEST inst)
 {
-  long x;
-  x = itype_immediate (inst);
-  if (x & 0x8000)              /* sign bit set */
-    {
-      x |= 0xffff0000;         /* sign extension */
-    }
-  x = x << 2;
-  return x;
+  return ((itype_immediate (inst) ^ 0x8000) - 0x8000) << 2;
 }
 
-/* Determine whate to set a single step breakpoint while considering
-   branch prediction */
+/* Determine where to set a single step breakpoint while considering
+   branch prediction */
 static CORE_ADDR
-mips32_next_pc (CORE_ADDR pc)
+mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
 {
   unsigned long inst;
   int op;
@@ -931,8 +1022,8 @@ mips32_next_pc (CORE_ADDR pc)
          int tf = itype_rt (inst) & 0x01;
          int cnum = itype_rt (inst) >> 2;
          int fcrcs =
-           read_signed_register (mips_regnum (current_gdbarch)->
-                                 fp_control_status);
+           get_frame_register_signed (frame, mips_regnum (current_gdbarch)->
+                                               fp_control_status);
          int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
 
          if (((cond >> cnum) & 0x01) == tf)
@@ -956,7 +1047,7 @@ mips32_next_pc (CORE_ADDR pc)
            case 8:             /* JR */
            case 9:             /* JALR */
              /* Set PC to that address */
-             pc = read_signed_register (rtype_rs (inst));
+             pc = get_frame_register_signed (frame, rtype_rs (inst));
              break;
            default:
              pc += 4;
@@ -973,7 +1064,7 @@ mips32_next_pc (CORE_ADDR pc)
              case 16:          /* BLTZAL */
              case 18:          /* BLTZALL */
              less_branch:
-               if (read_signed_register (itype_rs (inst)) < 0)
+               if (get_frame_register_signed (frame, itype_rs (inst)) < 0)
                  pc += mips32_relative_offset (inst) + 4;
                else
                  pc += 8;      /* after the delay slot */
@@ -982,7 +1073,7 @@ mips32_next_pc (CORE_ADDR pc)
              case 3:           /* BGEZL */
              case 17:          /* BGEZAL */
              case 19:          /* BGEZALL */
-               if (read_signed_register (itype_rs (inst)) >= 0)
+               if (get_frame_register_signed (frame, itype_rs (inst)) >= 0)
                  pc += mips32_relative_offset (inst) + 4;
                else
                  pc += 8;      /* after the delay slot */
@@ -999,35 +1090,35 @@ mips32_next_pc (CORE_ADDR pc)
            unsigned long reg;
            reg = jtype_target (inst) << 2;
            /* Upper four bits get never changed... */
-           pc = reg + ((pc + 4) & 0xf0000000);
+           pc = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff);
          }
          break;
          /* FIXME case JALX : */
          {
            unsigned long reg;
            reg = jtype_target (inst) << 2;
-           pc = reg + ((pc + 4) & 0xf0000000) + 1;     /* yes, +1 */
+           pc = reg + ((pc + 4) & ~(CORE_ADDR) 0x0fffffff) + 1;        /* yes, +1 */
            /* Add 1 to indicate 16 bit mode - Invert ISA mode */
          }
          break;                /* The new PC will be alternate mode */
        case 4:         /* BEQ, BEQL */
        equal_branch:
-         if (read_signed_register (itype_rs (inst)) ==
-             read_signed_register (itype_rt (inst)))
+         if (get_frame_register_signed (frame, itype_rs (inst)) ==
+             get_frame_register_signed (frame, itype_rt (inst)))
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
        case 5:         /* BNE, BNEL */
        neq_branch:
-         if (read_signed_register (itype_rs (inst)) !=
-             read_signed_register (itype_rt (inst)))
+         if (get_frame_register_signed (frame, itype_rs (inst)) !=
+             get_frame_register_signed (frame, itype_rt (inst)))
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
        case 6:         /* BLEZ, BLEZL */
-         if (read_signed_register (itype_rs (inst)) <= 0)
+         if (get_frame_register_signed (frame, itype_rs (inst)) <= 0)
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
@@ -1035,7 +1126,7 @@ mips32_next_pc (CORE_ADDR pc)
        case 7:
        default:
        greater_branch: /* BGTZ, BGTZL */
-         if (read_signed_register (itype_rs (inst)) > 0)
+         if (get_frame_register_signed (frame, itype_rs (inst)) > 0)
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
@@ -1107,18 +1198,16 @@ extended_offset (unsigned int extension)
 }
 
 /* Only call this function if you know that this is an extendable
-   instruction, It wont malfunction, but why make excess remote memory references?
-   If the immediate operands get sign extended or somthing, do it after
-   the extension is performed.
- */
+   instruction.  It won't malfunction, but why make excess remote memory
+   references?  If the immediate operands get sign extended or something,
+   do it after the extension is performed.  */
 /* FIXME: Every one of these cases needs to worry about sign extension
-   when the offset is to be used in relative addressing */
-
+   when the offset is to be used in relative addressing.  */
 
 static unsigned int
 fetch_mips_16 (CORE_ADDR pc)
 {
-  char buf[8];
+  gdb_byte buf[8];
   pc &= 0xfffffffe;            /* clear the low order bit */
   target_read_memory (pc, buf, 2);
   return extract_unsigned_integer (buf, 2);
@@ -1201,7 +1290,7 @@ unpack_mips16 (CORE_ADDR pc,
        break;
       }
     default:
-      internal_error (__FILE__, __LINE__, "bad switch");
+      internal_error (__FILE__, __LINE__, _("bad switch"));
     }
   upk->offset = offset;
   upk->regx = regx;
@@ -1212,11 +1301,11 @@ unpack_mips16 (CORE_ADDR pc,
 static CORE_ADDR
 add_offset_16 (CORE_ADDR pc, int offset)
 {
-  return ((offset << 2) | ((pc + 2) & (0xf0000000)));
+  return ((offset << 2) | ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)));
 }
 
 static CORE_ADDR
-extended_mips16_next_pc (CORE_ADDR pc,
+extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
                         unsigned int extension, unsigned int insn)
 {
   int op = (insn >> 11);
@@ -1252,7 +1341,7 @@ extended_mips16_next_pc (CORE_ADDR pc,
        struct upk_mips16 upk;
        int reg;
        unpack_mips16 (pc, extension, insn, ritype, &upk);
-       reg = read_signed_register (upk.regx);
+       reg = get_frame_register_signed (frame, upk.regx);
        if (reg == 0)
          pc += (upk.offset << 1) + 2;
        else
@@ -1264,7 +1353,7 @@ extended_mips16_next_pc (CORE_ADDR pc,
        struct upk_mips16 upk;
        int reg;
        unpack_mips16 (pc, extension, insn, ritype, &upk);
-       reg = read_signed_register (upk.regx);
+       reg = get_frame_register_signed (frame, upk.regx);
        if (reg != 0)
          pc += (upk.offset << 1) + 2;
        else
@@ -1277,7 +1366,7 @@ extended_mips16_next_pc (CORE_ADDR pc,
        int reg;
        unpack_mips16 (pc, extension, insn, i8type, &upk);
        /* upk.regx contains the opcode */
-       reg = read_signed_register (24);        /* Test register is 24 */
+       reg = get_frame_register_signed (frame, 24);  /* Test register is 24 */
        if (((upk.regx == 0) && (reg == 0))     /* BTEZ */
            || ((upk.regx == 1) && (reg != 0))) /* BTNEZ */
          /* pc = add_offset_16(pc,upk.offset) ; */
@@ -1311,7 +1400,7 @@ extended_mips16_next_pc (CORE_ADDR pc,
                reg = 31;
                break;          /* BOGUS Guess */
              }
-           pc = read_signed_register (reg);
+           pc = get_frame_register_signed (frame, reg);
          }
        else
          pc += 2;
@@ -1323,7 +1412,7 @@ extended_mips16_next_pc (CORE_ADDR pc,
          that. */
       {
        pc += 2;
-       pc = extended_mips16_next_pc (pc, insn, fetch_mips_16 (pc));
+       pc = extended_mips16_next_pc (frame, pc, insn, fetch_mips_16 (pc));
        break;
       }
     default:
@@ -1336,24 +1425,24 @@ extended_mips16_next_pc (CORE_ADDR pc,
 }
 
 static CORE_ADDR
-mips16_next_pc (CORE_ADDR pc)
+mips16_next_pc (struct frame_info *frame, CORE_ADDR pc)
 {
   unsigned int insn = fetch_mips_16 (pc);
-  return extended_mips16_next_pc (pc, 0, insn);
+  return extended_mips16_next_pc (frame, pc, 0, insn);
 }
 
 /* The mips_next_pc function supports single_step when the remote
    target monitor or stub is not developed enough to do a single_step.
    It works by decoding the current instruction and predicting where a
    branch will go. This isnt hard because all the data is available.
-   The MIPS32 and MIPS16 variants are quite different */
-CORE_ADDR
-mips_next_pc (CORE_ADDR pc)
+   The MIPS32 and MIPS16 variants are quite different */
+static CORE_ADDR
+mips_next_pc (struct frame_info *frame, CORE_ADDR pc)
 {
-  if (pc & 0x01)
-    return mips16_next_pc (pc);
+  if (is_mips16_addr (pc))
+    return mips16_next_pc (frame, pc);
   else
-    return mips32_next_pc (pc);
+    return mips32_next_pc (frame, pc);
 }
 
 struct mips_frame_cache
@@ -1367,11 +1456,11 @@ struct mips_frame_cache
    way we will only recognize the first save of a given register in a
    function prologue.
 
-   For simplicity, save the address in both [0 .. NUM_REGS) and
-   [NUM_REGS .. 2*NUM_REGS).  Strictly speaking, only the second range
-   is used as it is only second range (the ABI instead of ISA
-   registers) that comes into play when finding saved registers in a
-   frame.  */
+   For simplicity, save the address in both [0 .. gdbarch_num_regs) and
+   [gdbarch_num_regs .. 2*gdbarch_num_regs).
+   Strictly speaking, only the second range is used as it is only second
+   range (the ABI instead of ISA registers) that comes into play when finding
+   saved registers in a frame.  */
 
 static void
 set_reg_offset (struct mips_frame_cache *this_cache, int regnum,
@@ -1380,8 +1469,12 @@ set_reg_offset (struct mips_frame_cache *this_cache, int regnum,
   if (this_cache != NULL
       && this_cache->saved_regs[regnum].addr == -1)
     {
-      this_cache->saved_regs[regnum + 0 * NUM_REGS].addr = offset;
-      this_cache->saved_regs[regnum + 1 * NUM_REGS].addr = offset;
+      this_cache->saved_regs[regnum
+                            + 0 * gdbarch_num_regs (current_gdbarch)].addr
+      = offset;
+      this_cache->saved_regs[regnum
+                            + 1 * gdbarch_num_regs (current_gdbarch)].addr
+      = offset;
     }
 }
 
@@ -1448,7 +1541,9 @@ mips16_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
   /* Can be called when there's no process, and hence when there's no
      NEXT_FRAME.  */
   if (next_frame != NULL)
-    sp = read_next_frame_reg (next_frame, NUM_REGS + MIPS_SP_REGNUM);
+    sp = frame_unwind_register_signed (next_frame,
+                                      gdbarch_num_regs (current_gdbarch)
+                                      + MIPS_SP_REGNUM);
   else
     sp = 0;
 
@@ -1600,13 +1695,17 @@ mips16_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
   if (this_cache != NULL)
     {
       this_cache->base =
-        (frame_unwind_register_signed (next_frame, NUM_REGS + frame_reg)
+        (frame_unwind_register_signed (next_frame,
+                                      gdbarch_num_regs (current_gdbarch)
+                                      + frame_reg)
          + frame_offset - frame_adjust);
       /* FIXME: brobecker/2004-10-10: Just as in the mips32 case, we should
          be able to get rid of the assignment below, evetually. But it's
          still needed for now.  */
-      this_cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc]
-        = this_cache->saved_regs[NUM_REGS + MIPS_RA_REGNUM];
+      this_cache->saved_regs[gdbarch_num_regs (current_gdbarch)
+                            + mips_regnum (current_gdbarch)->pc]
+        = this_cache->saved_regs[gdbarch_num_regs (current_gdbarch)
+                                + MIPS_RA_REGNUM];
     }
 
   /* If we didn't reach the end of the prologue when scanning the function
@@ -1635,7 +1734,8 @@ mips_insn16_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   /* Analyze the function prologue.  */
   {
-    const CORE_ADDR pc = frame_pc_unwind (next_frame);
+    const CORE_ADDR pc =
+      frame_unwind_address_in_block (next_frame, NORMAL_FRAME);
     CORE_ADDR start_addr;
 
     find_pc_partial_function (pc, NULL, &start_addr, NULL);
@@ -1649,8 +1749,9 @@ mips_insn16_frame_cache (struct frame_info *next_frame, void **this_cache)
     mips16_scan_prologue (start_addr, pc, next_frame, *this_cache);
   }
   
-  /* SP_REGNUM, contains the value and not the address.  */
-  trad_frame_set_value (cache->saved_regs, NUM_REGS + MIPS_SP_REGNUM, cache->base);
+  /* gdbarch_sp_regnum contains the value and not the address.  */
+  trad_frame_set_value (cache->saved_regs, gdbarch_num_regs (current_gdbarch)
+                                          + MIPS_SP_REGNUM, cache->base);
 
   return (*this_cache);
 }
@@ -1661,7 +1762,8 @@ mips_insn16_frame_this_id (struct frame_info *next_frame, void **this_cache,
 {
   struct mips_frame_cache *info = mips_insn16_frame_cache (next_frame,
                                                           this_cache);
-  (*this_id) = frame_id_build (info->base, frame_func_unwind (next_frame));
+  (*this_id) = frame_id_build (info->base,
+                              frame_func_unwind (next_frame, NORMAL_FRAME));
 }
 
 static void
@@ -1669,7 +1771,7 @@ mips_insn16_frame_prev_register (struct frame_info *next_frame,
                                 void **this_cache,
                                 int regnum, int *optimizedp,
                                 enum lval_type *lvalp, CORE_ADDR *addrp,
-                                int *realnump, void *valuep)
+                                int *realnump, gdb_byte *valuep)
 {
   struct mips_frame_cache *info = mips_insn16_frame_cache (next_frame,
                                                           this_cache);
@@ -1729,7 +1831,7 @@ reset_saved_regs (struct mips_frame_cache *this_cache)
     return;
 
   {
-    const int num_regs = NUM_REGS;
+    const int num_regs = gdbarch_num_regs (current_gdbarch);
     int i;
 
     for (i = 0; i < num_regs; i++)
@@ -1761,7 +1863,9 @@ mips32_scan_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
   /* Can be called when there's no process, and hence when there's no
      NEXT_FRAME.  */
   if (next_frame != NULL)
-    sp = read_next_frame_reg (next_frame, NUM_REGS + MIPS_SP_REGNUM);
+    sp = frame_unwind_register_signed (next_frame,
+                                      gdbarch_num_regs (current_gdbarch)
+                                      + MIPS_SP_REGNUM);
   else
     sp = 0;
 
@@ -1811,12 +1915,15 @@ restart:
          /* Old gcc frame, r30 is virtual frame pointer.  */
          if ((long) low_word != frame_offset)
            frame_addr = sp + low_word;
-         else if (frame_reg == MIPS_SP_REGNUM)
+         else if (next_frame && frame_reg == MIPS_SP_REGNUM)
            {
              unsigned alloca_adjust;
 
              frame_reg = 30;
-             frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
+             frame_addr = frame_unwind_register_signed
+                            (next_frame,
+                             gdbarch_num_regs (current_gdbarch) + 30);
+
              alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
              if (alloca_adjust > 0)
                {
@@ -1839,12 +1946,15 @@ restart:
       else if (inst == 0x03A0F021 || inst == 0x03a0f025 || inst == 0x03a0f02d)
        {
          /* New gcc frame, virtual frame pointer is at r30 + frame_size.  */
-         if (frame_reg == MIPS_SP_REGNUM)
+         if (next_frame && frame_reg == MIPS_SP_REGNUM)
            {
              unsigned alloca_adjust;
 
              frame_reg = 30;
-             frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
+             frame_addr = frame_unwind_register_signed
+                            (next_frame,
+                             gdbarch_num_regs (current_gdbarch) + 30);
+
              alloca_adjust = (unsigned) (frame_addr - sp);
              if (alloca_adjust > 0)
                {
@@ -1909,13 +2019,17 @@ restart:
   if (this_cache != NULL)
     {
       this_cache->base = 
-        (frame_unwind_register_signed (next_frame, NUM_REGS + frame_reg)
+        (frame_unwind_register_signed (next_frame,
+                                      gdbarch_num_regs (current_gdbarch)
+                                      + frame_reg)
          + frame_offset);
       /* FIXME: brobecker/2004-09-15: We should be able to get rid of
          this assignment below, eventually.  But it's still needed
          for now.  */
-      this_cache->saved_regs[NUM_REGS + mips_regnum (current_gdbarch)->pc]
-        = this_cache->saved_regs[NUM_REGS + MIPS_RA_REGNUM];
+      this_cache->saved_regs[gdbarch_num_regs (current_gdbarch)
+                            + mips_regnum (current_gdbarch)->pc]
+        = this_cache->saved_regs[gdbarch_num_regs (current_gdbarch)
+                                + MIPS_RA_REGNUM];
     }
 
   /* If we didn't reach the end of the prologue when scanning the function
@@ -1955,7 +2069,8 @@ mips_insn32_frame_cache (struct frame_info *next_frame, void **this_cache)
 
   /* Analyze the function prologue.  */
   {
-    const CORE_ADDR pc = frame_pc_unwind (next_frame);
+    const CORE_ADDR pc =
+      frame_unwind_address_in_block (next_frame, NORMAL_FRAME);
     CORE_ADDR start_addr;
 
     find_pc_partial_function (pc, NULL, &start_addr, NULL);
@@ -1969,8 +2084,10 @@ mips_insn32_frame_cache (struct frame_info *next_frame, void **this_cache)
     mips32_scan_prologue (start_addr, pc, next_frame, *this_cache);
   }
   
-  /* SP_REGNUM, contains the value and not the address.  */
-  trad_frame_set_value (cache->saved_regs, NUM_REGS + MIPS_SP_REGNUM, cache->base);
+  /* gdbarch_sp_regnum contains the value and not the address.  */
+  trad_frame_set_value (cache->saved_regs,
+                       gdbarch_num_regs (current_gdbarch) + MIPS_SP_REGNUM,
+                       cache->base);
 
   return (*this_cache);
 }
@@ -1981,7 +2098,8 @@ mips_insn32_frame_this_id (struct frame_info *next_frame, void **this_cache,
 {
   struct mips_frame_cache *info = mips_insn32_frame_cache (next_frame,
                                                           this_cache);
-  (*this_id) = frame_id_build (info->base, frame_func_unwind (next_frame));
+  (*this_id) = frame_id_build (info->base,
+                              frame_func_unwind (next_frame, NORMAL_FRAME));
 }
 
 static void
@@ -1989,7 +2107,7 @@ mips_insn32_frame_prev_register (struct frame_info *next_frame,
                                 void **this_cache,
                                 int regnum, int *optimizedp,
                                 enum lval_type *lvalp, CORE_ADDR *addrp,
-                                int *realnump, void *valuep)
+                                int *realnump, gdb_byte *valuep)
 {
   struct mips_frame_cache *info = mips_insn32_frame_cache (next_frame,
                                                           this_cache);
@@ -2053,7 +2171,9 @@ mips_stub_frame_cache (struct frame_info *next_frame, void **this_cache)
   (*this_cache) = this_trad_cache;
 
   /* The return address is in the link register.  */
-  trad_frame_set_reg_realreg (this_trad_cache, PC_REGNUM, MIPS_RA_REGNUM);
+  trad_frame_set_reg_realreg (this_trad_cache,
+                             gdbarch_pc_regnum (current_gdbarch),
+                             MIPS_RA_REGNUM);
 
   /* Frame ID, since it's a frameless / stackless function, no stack
      space is allocated and SP on entry is the current SP.  */
@@ -2083,7 +2203,7 @@ mips_stub_frame_prev_register (struct frame_info *next_frame,
                                 void **this_cache,
                                 int regnum, int *optimizedp,
                                 enum lval_type *lvalp, CORE_ADDR *addrp,
-                                int *realnump, void *valuep)
+                                int *realnump, gdb_byte *valuep)
 {
   struct trad_frame_cache *this_trad_cache
     = mips_stub_frame_cache (next_frame, this_cache);
@@ -2101,11 +2221,21 @@ static const struct frame_unwind mips_stub_frame_unwind =
 static const struct frame_unwind *
 mips_stub_frame_sniffer (struct frame_info *next_frame)
 {
-  CORE_ADDR pc = frame_pc_unwind (next_frame);
+  struct obj_section *s;
+  CORE_ADDR pc = frame_unwind_address_in_block (next_frame, NORMAL_FRAME);
+
   if (in_plt_section (pc, NULL))
     return &mips_stub_frame_unwind;
-  else
-    return NULL;
+
+  /* Binutils for MIPS puts lazy resolution stubs into .MIPS.stubs.  */
+  s = find_pc_section (pc);
+
+  if (s != NULL
+      && strcmp (bfd_get_section_name (s->objfile->obfd, s->the_bfd_section),
+                ".MIPS.stubs") == 0)
+    return &mips_stub_frame_unwind;
+
+  return NULL;
 }
 
 static CORE_ADDR
@@ -2134,22 +2264,6 @@ mips_stub_frame_base_sniffer (struct frame_info *next_frame)
     return NULL;
 }
 
-static CORE_ADDR
-read_next_frame_reg (struct frame_info *fi, int regno)
-{
-  /* Always a pseudo.  */
-  gdb_assert (regno >= NUM_REGS);
-  if (fi == NULL)
-    {
-      LONGEST val;
-      regcache_cooked_read_signed (current_regcache, regno, &val);
-      return val;
-    }
-  else
-    return frame_unwind_register_signed (fi, regno);
-
-}
-
 /* mips_addr_bits_remove - remove useless address bits  */
 
 static CORE_ADDR
@@ -2180,32 +2294,20 @@ mips_addr_bits_remove (CORE_ADDR addr)
 /* mips_software_single_step() is called just before we want to resume
    the inferior, if we want to single-step it but there is no hardware
    or kernel single-step support (MIPS on GNU/Linux for example).  We find
-   the target of the coming instruction and breakpoint it.
-
-   single_step is also called just after the inferior stops.  If we had
-   set up a simulated single-step, we undo our damage.  */
+   the target of the coming instruction and breakpoint it.  */
 
-void
-mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+int
+mips_software_single_step (struct frame_info *frame)
 {
-  static CORE_ADDR next_pc;
-  typedef char binsn_quantum[BREAKPOINT_MAX];
-  static binsn_quantum break_mem;
-  CORE_ADDR pc;
+  CORE_ADDR pc, next_pc;
 
-  if (insert_breakpoints_p)
-    {
-      pc = read_register (mips_regnum (current_gdbarch)->pc);
-      next_pc = mips_next_pc (pc);
+  pc = get_frame_pc (frame);
+  next_pc = mips_next_pc (frame, pc);
 
-      target_insert_breakpoint (next_pc, break_mem);
-    }
-  else
-    target_remove_breakpoint (next_pc, break_mem);
+  insert_single_step_breakpoint (next_pc);
+  return 1;
 }
 
-static struct mips_extra_func_info temp_proc_desc;
-
 /* Test whether the PC points to the return instruction at the
    end of a function. */
 
@@ -2237,7 +2339,7 @@ heuristic_proc_start (CORE_ADDR pc)
   int instlen;
   int seen_adjsp = 0;
 
-  pc = ADDR_BITS_REMOVE (pc);
+  pc = gdbarch_addr_bits_remove (current_gdbarch, pc);
   start_pc = pc;
   fence = start_pc - heuristic_fence_post;
   if (start_pc == 0)
@@ -2260,7 +2362,7 @@ heuristic_proc_start (CORE_ADDR pc)
          {
            static int blurb_printed = 0;
 
-           warning ("GDB can't find the start of the function at 0x%s.",
+           warning (_("GDB can't find the start of the function at 0x%s."),
                     paddr_nz (pc));
 
            if (!blurb_printed)
@@ -2328,7 +2430,7 @@ struct mips_objfile_private
 
 /* According to the current ABI, should the type be passed in a
    floating-point register (assuming that there is space)?  When there
-   is no FPU, FP are not even considered as possibile candidates for
+   is no FPU, FP are not even considered as possible candidates for
    FP registers and, consequently this returns false - forces FP
    arguments into integer registers. */
 
@@ -2340,7 +2442,8 @@ fp_register_arg_p (enum type_code typecode, struct type *arg_type)
               && (typecode == TYPE_CODE_STRUCT
                   || typecode == TYPE_CODE_UNION)
               && TYPE_NFIELDS (arg_type) == 1
-              && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT))
+              && TYPE_CODE (check_typedef (TYPE_FIELD_TYPE (arg_type, 0))) 
+              == TYPE_CODE_FLT))
          && MIPS_FPU_TYPE != MIPS_FPU_NONE);
 }
 
@@ -2394,6 +2497,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int stack_offset = 0;
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   CORE_ADDR func_addr = find_function_addr (function, NULL);
+  int regsize = mips_abi_regsize (gdbarch);
 
   /* For shared libraries, "t9" needs to point at the function
      address.  */
@@ -2416,8 +2520,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
      than necessary for EABI, because the first few arguments are
      passed in registers, but that's OK.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])),
-                    mips_stack_argsize (gdbarch));
+    len += align_up (TYPE_LENGTH (value_type (args[argnum])), regsize);
   sp -= align_up (len, 16);
 
   if (mips_debug)
@@ -2436,7 +2539,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
        fprintf_unfiltered (gdb_stdlog,
                            "mips_eabi_push_dummy_call: struct_return reg=%d 0x%s\n",
                            argreg, paddr_nz (struct_addr));
-      write_register (argreg++, struct_addr);
+      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
     }
 
   /* Now load as many as possible of the first arguments into
@@ -2444,10 +2547,10 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
      from first to last.  */
   for (argnum = 0; argnum < nargs; argnum++)
     {
-      char *val;
-      char valbuf[MAX_REGISTER_SIZE];
+      const gdb_byte *val;
+      gdb_byte valbuf[MAX_REGISTER_SIZE];
       struct value *arg = args[argnum];
-      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+      struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
       enum type_code typecode = TYPE_CODE (arg_type);
 
@@ -2458,27 +2561,25 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
       /* The EABI passes structures that do not fit in a register by
          reference.  */
-      if (len > mips_abi_regsize (gdbarch)
+      if (len > regsize
          && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
        {
-         store_unsigned_integer (valbuf, mips_abi_regsize (gdbarch),
-                                 VALUE_ADDRESS (arg));
+         store_unsigned_integer (valbuf, regsize, VALUE_ADDRESS (arg));
          typecode = TYPE_CODE_PTR;
-         len = mips_abi_regsize (gdbarch);
+         len = regsize;
          val = valbuf;
          if (mips_debug)
            fprintf_unfiltered (gdb_stdlog, " push");
        }
       else
-       val = (char *) VALUE_CONTENTS (arg);
+       val = value_contents (arg);
 
       /* 32-bit ABIs always start floating point arguments in an
          even-numbered floating point register.  Round the FP register
          up before the check to see if there are any FP registers
          left.  Non MIPS_EABI targets also pass the FP in the integer
          registers so also round up normal registers.  */
-      if (mips_abi_regsize (gdbarch) < 8
-         && fp_register_arg_p (typecode, arg_type))
+      if (regsize < 8 && fp_register_arg_p (typecode, arg_type))
        {
          if ((float_argreg & 1))
            float_argreg++;
@@ -2499,9 +2600,15 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       if (fp_register_arg_p (typecode, arg_type)
          && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
        {
-         if (mips_abi_regsize (gdbarch) < 8 && len == 8)
+         /* EABI32 will pass doubles in consecutive registers, even on
+            64-bit cores.  At one time, we used to check the size of
+            `float_argreg' to determine whether or not to pass doubles
+            in consecutive registers, but this is not sufficient for
+            making the ABI determination.  */
+         if (len == 8 && mips_abi (gdbarch) == MIPS_ABI_EABI32)
            {
-             int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
+             int low_offset = gdbarch_byte_order (current_gdbarch)
+                              == BFD_ENDIAN_BIG ? 4 : 0;
              unsigned long regval;
 
              /* Write the low word of the double to the even register(s).  */
@@ -2509,14 +2616,14 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
                                    float_argreg, phex (regval, 4));
-             write_register (float_argreg++, regval);
+             regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
 
              /* Write the high word of the double to the odd register(s).  */
              regval = extract_unsigned_integer (val + 4 - low_offset, 4);
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
                                    float_argreg, phex (regval, 4));
-             write_register (float_argreg++, regval);
+             regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
            }
          else
            {
@@ -2528,7 +2635,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
                                    float_argreg, phex (regval, len));
-             write_register (float_argreg++, regval);
+             regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
            }
        }
       else
@@ -2536,13 +2643,12 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          /* Copy the argument to general registers or the stack in
             register-sized pieces.  Large arguments are split between
             registers and stack.  */
-         /* Note: structs whose size is not a multiple of
-            mips_abi_regsize() are treated specially: Irix cc passes
+         /* Note: structs whose size is not a multiple of regsize
+            are treated specially: Irix cc passes
             them in registers where gcc sometimes puts them on the
             stack.  For maximum compatibility, we will put them in
             both places.  */
-         int odd_sized_struct = ((len > mips_abi_regsize (gdbarch))
-                                 && (len % mips_abi_regsize (gdbarch) != 0));
+         int odd_sized_struct = (len > regsize && len % regsize != 0);
 
          /* Note: Floating-point values that didn't fit into an FP
             register are only written to memory.  */
@@ -2550,8 +2656,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
            {
              /* Remember if the argument was written to the stack.  */
              int stack_used_p = 0;
-             int partial_len = (len < mips_abi_regsize (gdbarch)
-                                ? len : mips_abi_regsize (gdbarch));
+             int partial_len = (len < regsize ? len : regsize);
 
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
@@ -2567,18 +2672,17 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                  int longword_offset = 0;
                  CORE_ADDR addr;
                  stack_used_p = 1;
-                 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+                 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
                    {
-                     if (mips_stack_argsize (gdbarch) == 8
+                     if (regsize == 8
                          && (typecode == TYPE_CODE_INT
                              || typecode == TYPE_CODE_PTR
                              || typecode == TYPE_CODE_FLT) && len <= 4)
-                       longword_offset = mips_stack_argsize (gdbarch) - len;
+                       longword_offset = regsize - len;
                      else if ((typecode == TYPE_CODE_STRUCT
                                || typecode == TYPE_CODE_UNION)
-                              && (TYPE_LENGTH (arg_type)
-                                  < mips_stack_argsize (gdbarch)))
-                       longword_offset = mips_stack_argsize (gdbarch) - len;
+                              && TYPE_LENGTH (arg_type) < regsize)
+                       longword_offset = regsize - len;
                    }
 
                  if (mips_debug)
@@ -2619,9 +2723,8 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                  if (mips_debug)
                    fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
                                      argreg,
-                                     phex (regval,
-                                           mips_abi_regsize (gdbarch)));
-                 write_register (argreg, regval);
+                                     phex (regval, regsize));
+                 regcache_cooked_write_unsigned (regcache, argreg, regval);
                  argreg++;
                }
 
@@ -2635,8 +2738,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                 only needs to be adjusted when it has been used.  */
 
              if (stack_used_p)
-               stack_offset += align_up (partial_len,
-                                         mips_stack_argsize (gdbarch));
+               stack_offset += align_up (partial_len, regsize);
            }
        }
       if (mips_debug)
@@ -2649,12 +2751,12 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   return sp;
 }
 
-/* Determin the return value convention being used.  */
+/* Determine the return value convention being used.  */
 
 static enum return_value_convention
 mips_eabi_return_value (struct gdbarch *gdbarch,
                        struct type *type, struct regcache *regcache,
-                       void *readbuf, const void *writebuf)
+                       gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   if (TYPE_LENGTH (type) > 2 * mips_abi_regsize (gdbarch))
     return RETURN_VALUE_STRUCT_CONVENTION;
@@ -2699,8 +2801,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* Now make space on the stack for the args.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])),
-                    mips_stack_argsize (gdbarch));
+    len += align_up (TYPE_LENGTH (value_type (args[argnum])), MIPS64_REGSIZE);
   sp -= align_up (len, 16);
 
   if (mips_debug)
@@ -2719,7 +2820,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
        fprintf_unfiltered (gdb_stdlog,
                            "mips_n32n64_push_dummy_call: struct_return reg=%d 0x%s\n",
                            argreg, paddr_nz (struct_addr));
-      write_register (argreg++, struct_addr);
+      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
     }
 
   /* Now load as many as possible of the first arguments into
@@ -2727,9 +2828,9 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
      from first to last.  */
   for (argnum = 0; argnum < nargs; argnum++)
     {
-      char *val;
+      const gdb_byte *val;
       struct value *arg = args[argnum];
-      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+      struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
       enum type_code typecode = TYPE_CODE (arg_type);
 
@@ -2738,7 +2839,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                            "mips_n32n64_push_dummy_call: %d len=%d type=%d",
                            argnum + 1, len, (int) typecode);
 
-      val = (char *) VALUE_CONTENTS (arg);
+      val = value_contents (arg);
 
       if (fp_register_arg_p (typecode, arg_type)
          && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
@@ -2751,12 +2852,12 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          if (mips_debug)
            fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
                                float_argreg, phex (regval, len));
-         write_register (float_argreg++, regval);
+         regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
 
          if (mips_debug)
            fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
                                argreg, phex (regval, len));
-         write_register (argreg, regval);
+         regcache_cooked_write_unsigned (regcache, argreg, regval);
          argreg += 1;
        }
       else
@@ -2764,21 +2865,19 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          /* Copy the argument to general registers or the stack in
             register-sized pieces.  Large arguments are split between
             registers and stack.  */
-         /* Note: structs whose size is not a multiple of
-            mips_abi_regsize() are treated specially: Irix cc passes
-            them in registers where gcc sometimes puts them on the
-            stack.  For maximum compatibility, we will put them in
-            both places.  */
-         int odd_sized_struct = ((len > mips_abi_regsize (gdbarch))
-                                 && (len % mips_abi_regsize (gdbarch) != 0));
+         /* Note: structs whose size is not a multiple of MIPS64_REGSIZE
+            are treated specially: Irix cc passes them in registers
+            where gcc sometimes puts them on the stack.  For maximum
+            compatibility, we will put them in both places.  */
+         int odd_sized_struct = (len > MIPS64_REGSIZE
+                                 && len % MIPS64_REGSIZE != 0);
          /* Note: Floating-point values that didn't fit into an FP
             register are only written to memory.  */
          while (len > 0)
            {
-             /* Rememer if the argument was written to the stack.  */
+             /* Remember if the argument was written to the stack.  */
              int stack_used_p = 0;
-             int partial_len = (len < mips_abi_regsize (gdbarch)
-                                ? len : mips_abi_regsize (gdbarch));
+             int partial_len = (len < MIPS64_REGSIZE ? len : MIPS64_REGSIZE);
 
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
@@ -2794,13 +2893,13 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                  int longword_offset = 0;
                  CORE_ADDR addr;
                  stack_used_p = 1;
-                 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+                 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
                    {
-                     if (mips_stack_argsize (gdbarch) == 8
-                         && (typecode == TYPE_CODE_INT
-                             || typecode == TYPE_CODE_PTR
-                             || typecode == TYPE_CODE_FLT) && len <= 4)
-                       longword_offset = mips_stack_argsize (gdbarch) - len;
+                     if ((typecode == TYPE_CODE_INT
+                          || typecode == TYPE_CODE_PTR
+                          || typecode == TYPE_CODE_FLT)
+                         && len <= 4)
+                       longword_offset = MIPS64_REGSIZE - len;
                    }
 
                  if (mips_debug)
@@ -2845,35 +2944,20 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                     big endian targets.
 
                     It does not seem to be necessary to do the
-                    same for integral types.
+                    same for integral types.  */
 
-                    cagney/2001-07-23: gdb/179: Also, GCC, when
-                    outputting LE O32 with sizeof (struct) <
-                    mips_abi_regsize(), generates a left shift as
-                    part of storing the argument in a register a
-                    register (the left shift isn't generated when
-                    sizeof (struct) >= mips_abi_regsize()).  Since
-                    it is quite possible that this is GCC
-                    contradicting the LE/O32 ABI, GDB has not been
-                    adjusted to accommodate this.  Either someone
-                    needs to demonstrate that the LE/O32 ABI
-                    specifies such a left shift OR this new ABI gets
-                    identified as such and GDB gets tweaked
-                    accordingly.  */
-
-                 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-                     && partial_len < mips_abi_regsize (gdbarch)
-                     && (typecode == TYPE_CODE_STRUCT ||
-                         typecode == TYPE_CODE_UNION))
-                   regval <<= ((mips_abi_regsize (gdbarch) - partial_len) *
-                               TARGET_CHAR_BIT);
+                 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
+                     && partial_len < MIPS64_REGSIZE
+                     && (typecode == TYPE_CODE_STRUCT
+                         || typecode == TYPE_CODE_UNION))
+                   regval <<= ((MIPS64_REGSIZE - partial_len)
+                               * TARGET_CHAR_BIT);
 
                  if (mips_debug)
                    fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
                                      argreg,
-                                     phex (regval,
-                                           mips_abi_regsize (gdbarch)));
-                 write_register (argreg, regval);
+                                     phex (regval, MIPS64_REGSIZE));
+                 regcache_cooked_write_unsigned (regcache, argreg, regval);
                  argreg++;
                }
 
@@ -2887,8 +2971,7 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                 adjusted when it has been used.  */
 
              if (stack_used_p)
-               stack_offset += align_up (partial_len,
-                                         mips_stack_argsize (gdbarch));
+               stack_offset += align_up (partial_len, MIPS64_REGSIZE);
            }
        }
       if (mips_debug)
@@ -2904,14 +2987,36 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 static enum return_value_convention
 mips_n32n64_return_value (struct gdbarch *gdbarch,
                          struct type *type, struct regcache *regcache,
-                         void *readbuf, const void *writebuf)
+                         gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   if (TYPE_CODE (type) == TYPE_CODE_STRUCT
       || TYPE_CODE (type) == TYPE_CODE_UNION
       || TYPE_CODE (type) == TYPE_CODE_ARRAY
-      || TYPE_LENGTH (type) > 2 * mips_abi_regsize (gdbarch))
+      || TYPE_LENGTH (type) > 2 * MIPS64_REGSIZE)
     return RETURN_VALUE_STRUCT_CONVENTION;
+  else if (TYPE_CODE (type) == TYPE_CODE_FLT
+          && TYPE_LENGTH (type) == 16
+          && tdep->mips_fpu_type != MIPS_FPU_NONE)
+    {
+      /* A 128-bit floating-point value fills both $f0 and $f2.  The
+        two registers are used in the same as memory order, so the
+        eight bytes with the lower memory address are in $f0.  */
+      if (mips_debug)
+       fprintf_unfiltered (gdb_stderr, "Return float in $f0 and $f2\n");
+      mips_xfer_register (regcache,
+                         gdbarch_num_regs (current_gdbarch)
+                         + mips_regnum (current_gdbarch)->fp0,
+                         8, gdbarch_byte_order (current_gdbarch),
+                         readbuf, writebuf, 0);
+      mips_xfer_register (regcache,
+                         gdbarch_num_regs (current_gdbarch)
+                         + mips_regnum (current_gdbarch)->fp0 + 2,
+                         8, gdbarch_byte_order (current_gdbarch),
+                         readbuf ? readbuf + 8 : readbuf,
+                         writebuf ? writebuf + 8 : writebuf, 0);
+      return RETURN_VALUE_REGISTER_CONVENTION;
+    }
   else if (TYPE_CODE (type) == TYPE_CODE_FLT
           && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {
@@ -2920,9 +3025,11 @@ mips_n32n64_return_value (struct gdbarch *gdbarch,
       if (mips_debug)
        fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
       mips_xfer_register (regcache,
-                         NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+                         gdbarch_num_regs (current_gdbarch)
+                         + mips_regnum (current_gdbarch)->fp0,
                          TYPE_LENGTH (type),
-                         TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+                         gdbarch_byte_order (current_gdbarch),
+                         readbuf, writebuf, 0);
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
   else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -2951,9 +3058,11 @@ mips_n32n64_return_value (struct gdbarch *gdbarch,
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n",
                                offset);
-         mips_xfer_register (regcache, NUM_REGS + regnum,
+         mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+                                       + regnum,
                              TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
-                             TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+                             gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, offset);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
@@ -2975,7 +3084,8 @@ mips_n32n64_return_value (struct gdbarch *gdbarch,
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
                                offset, xfer, regnum);
-         mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+         mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+                                       + regnum, xfer,
                              BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
@@ -2996,8 +3106,10 @@ mips_n32n64_return_value (struct gdbarch *gdbarch,
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
                                offset, xfer, regnum);
-         mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
-                             TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+         mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+                                       + regnum, xfer,
+                             gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, offset);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
@@ -3038,8 +3150,16 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* Now make space on the stack for the args.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])),
-                    mips_stack_argsize (gdbarch));
+    {
+      struct type *arg_type = check_typedef (value_type (args[argnum]));
+      int arglen = TYPE_LENGTH (arg_type);
+
+      /* Align to double-word if necessary.  */
+      if (mips_type_needs_double_align (arg_type))
+       len = align_up (len, MIPS32_REGSIZE * 2);
+      /* Allocate space on the stack.  */
+      len += align_up (arglen, MIPS32_REGSIZE);
+    }
   sp -= align_up (len, 16);
 
   if (mips_debug)
@@ -3058,8 +3178,8 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
        fprintf_unfiltered (gdb_stdlog,
                            "mips_o32_push_dummy_call: struct_return reg=%d 0x%s\n",
                            argreg, paddr_nz (struct_addr));
-      write_register (argreg++, struct_addr);
-      stack_offset += mips_stack_argsize (gdbarch);
+      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
+      stack_offset += MIPS32_REGSIZE;
     }
 
   /* Now load as many as possible of the first arguments into
@@ -3067,9 +3187,9 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
      from first to last.  */
   for (argnum = 0; argnum < nargs; argnum++)
     {
-      char *val;
+      const gdb_byte *val;
       struct value *arg = args[argnum];
-      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+      struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
       enum type_code typecode = TYPE_CODE (arg_type);
 
@@ -3078,15 +3198,14 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                            "mips_o32_push_dummy_call: %d len=%d type=%d",
                            argnum + 1, len, (int) typecode);
 
-      val = (char *) VALUE_CONTENTS (arg);
+      val = value_contents (arg);
 
       /* 32-bit ABIs always start floating point arguments in an
          even-numbered floating point register.  Round the FP register
          up before the check to see if there are any FP registers
          left.  O32/O64 targets also pass the FP in the integer
          registers so also round up normal registers.  */
-      if (mips_abi_regsize (gdbarch) < 8
-         && fp_register_arg_p (typecode, arg_type))
+      if (fp_register_arg_p (typecode, arg_type))
        {
          if ((float_argreg & 1))
            float_argreg++;
@@ -3105,9 +3224,10 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       if (fp_register_arg_p (typecode, arg_type)
          && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
        {
-         if (mips_abi_regsize (gdbarch) < 8 && len == 8)
+         if (register_size (gdbarch, float_argreg) < 8 && len == 8)
            {
-             int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
+             int low_offset = gdbarch_byte_order (current_gdbarch)
+                              == BFD_ENDIAN_BIG ? 4 : 0;
              unsigned long regval;
 
              /* Write the low word of the double to the even register(s).  */
@@ -3115,23 +3235,23 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
                                    float_argreg, phex (regval, 4));
-             write_register (float_argreg++, regval);
+             regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
                                    argreg, phex (regval, 4));
-             write_register (argreg++, regval);
+             regcache_cooked_write_unsigned (regcache, argreg++, regval);
 
              /* Write the high word of the double to the odd register(s).  */
              regval = extract_unsigned_integer (val + 4 - low_offset, 4);
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
                                    float_argreg, phex (regval, 4));
-             write_register (float_argreg++, regval);
+             regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
 
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
                                    argreg, phex (regval, 4));
-             write_register (argreg++, regval);
+             regcache_cooked_write_unsigned (regcache, argreg++, regval);
            }
          else
            {
@@ -3143,7 +3263,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
                                    float_argreg, phex (regval, len));
-             write_register (float_argreg++, regval);
+             regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
              /* CAGNEY: 32 bit MIPS ABI's always reserve two FP
                 registers for each argument.  The below is (my
                 guess) to ensure that the corresponding integer
@@ -3151,40 +3271,39 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
                                    argreg, phex (regval, len));
-             write_register (argreg, regval);
-             argreg += (mips_abi_regsize (gdbarch) == 8) ? 1 : 2;
+             regcache_cooked_write_unsigned (regcache, argreg, regval);
+             argreg += 2;
            }
          /* Reserve space for the FP register.  */
-         stack_offset += align_up (len, mips_stack_argsize (gdbarch));
+         stack_offset += align_up (len, MIPS32_REGSIZE);
        }
       else
        {
          /* Copy the argument to general registers or the stack in
             register-sized pieces.  Large arguments are split between
             registers and stack.  */
-         /* Note: structs whose size is not a multiple of
-            mips_abi_regsize() are treated specially: Irix cc passes
+         /* Note: structs whose size is not a multiple of MIPS32_REGSIZE
+            are treated specially: Irix cc passes
             them in registers where gcc sometimes puts them on the
             stack.  For maximum compatibility, we will put them in
             both places.  */
-         int odd_sized_struct = ((len > mips_abi_regsize (gdbarch))
-                                 && (len % mips_abi_regsize (gdbarch) != 0));
+         int odd_sized_struct = (len > MIPS32_REGSIZE
+                                 && len % MIPS32_REGSIZE != 0);
          /* Structures should be aligned to eight bytes (even arg registers)
             on MIPS_ABI_O32, if their first member has double precision.  */
-         if (mips_abi_regsize (gdbarch) < 8
-             && mips_type_needs_double_align (arg_type))
+         if (mips_type_needs_double_align (arg_type))
            {
              if ((argreg & 1))
-               argreg++;
+               {
+                 argreg++;
+                 stack_offset += MIPS32_REGSIZE;
+               }
            }
-         /* Note: Floating-point values that didn't fit into an FP
-            register are only written to memory.  */
          while (len > 0)
            {
              /* Remember if the argument was written to the stack.  */
              int stack_used_p = 0;
-             int partial_len = (len < mips_abi_regsize (gdbarch)
-                                ? len : mips_abi_regsize (gdbarch));
+             int partial_len = (len < MIPS32_REGSIZE ? len : MIPS32_REGSIZE);
 
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
@@ -3192,22 +3311,13 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
              /* Write this portion of the argument to the stack.  */
              if (argreg > MIPS_LAST_ARG_REGNUM
-                 || odd_sized_struct
-                 || fp_register_arg_p (typecode, arg_type))
+                 || odd_sized_struct)
                {
                  /* Should shorter than int integer values be
                     promoted to int before being stored? */
                  int longword_offset = 0;
                  CORE_ADDR addr;
                  stack_used_p = 1;
-                 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-                   {
-                     if (mips_stack_argsize (gdbarch) == 8
-                         && (typecode == TYPE_CODE_INT
-                             || typecode == TYPE_CODE_PTR
-                             || typecode == TYPE_CODE_FLT) && len <= 4)
-                       longword_offset = mips_stack_argsize (gdbarch) - len;
-                   }
 
                  if (mips_debug)
                    {
@@ -3234,12 +3344,10 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                }
 
              /* Note!!! This is NOT an else clause.  Odd sized
-                structs may go thru BOTH paths.  Floating point
-                arguments will not.  */
+                structs may go thru BOTH paths.  */
              /* Write this portion of the argument to a general
                 purpose register.  */
-             if (argreg <= MIPS_LAST_ARG_REGNUM
-                 && !fp_register_arg_p (typecode, arg_type))
+             if (argreg <= MIPS_LAST_ARG_REGNUM)
                {
                  LONGEST regval = extract_signed_integer (val, partial_len);
                  /* Value may need to be sign extended, because
@@ -3258,9 +3366,9 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
                     cagney/2001-07-23: gdb/179: Also, GCC, when
                     outputting LE O32 with sizeof (struct) <
-                    mips_abi_regsize(), generates a left shift as
-                    part of storing the argument in a register a
-                    register (the left shift isn't generated when
+                    mips_abi_regsize(), generates a left shift
+                    as part of storing the argument in a register
+                    (the left shift isn't generated when
                     sizeof (struct) >= mips_abi_regsize()).  Since
                     it is quite possible that this is GCC
                     contradicting the LE/O32 ABI, GDB has not been
@@ -3270,20 +3378,18 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                     identified as such and GDB gets tweaked
                     accordingly.  */
 
-                 if (mips_abi_regsize (gdbarch) < 8
-                     && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-                     && partial_len < mips_abi_regsize (gdbarch)
-                     && (typecode == TYPE_CODE_STRUCT ||
-                         typecode == TYPE_CODE_UNION))
-                   regval <<= ((mips_abi_regsize (gdbarch) - partial_len) *
-                               TARGET_CHAR_BIT);
+                 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
+                     && partial_len < MIPS32_REGSIZE
+                     && (typecode == TYPE_CODE_STRUCT
+                         || typecode == TYPE_CODE_UNION))
+                   regval <<= ((MIPS32_REGSIZE - partial_len)
+                               * TARGET_CHAR_BIT);
 
                  if (mips_debug)
                    fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
                                      argreg,
-                                     phex (regval,
-                                           mips_abi_regsize (gdbarch)));
-                 write_register (argreg, regval);
+                                     phex (regval, MIPS32_REGSIZE));
+                 regcache_cooked_write_unsigned (regcache, argreg, regval);
                  argreg++;
 
                  /* Prevent subsequent floating point arguments from
@@ -3302,8 +3408,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                 refered to as their "home".  Consequently, space is
                 always allocated.  */
 
-             stack_offset += align_up (partial_len,
-                                       mips_stack_argsize (gdbarch));
+             stack_offset += align_up (partial_len, MIPS32_REGSIZE);
            }
        }
       if (mips_debug)
@@ -3319,7 +3424,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 static enum return_value_convention
 mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
                       struct regcache *regcache,
-                      void *readbuf, const void *writebuf)
+                      gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
 
@@ -3335,9 +3440,11 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
       if (mips_debug)
        fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
       mips_xfer_register (regcache,
-                         NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+                         gdbarch_num_regs (current_gdbarch)
+                           + mips_regnum (current_gdbarch)->fp0,
                          TYPE_LENGTH (type),
-                         TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+                         gdbarch_byte_order (current_gdbarch),
+                         readbuf, writebuf, 0);
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
   else if (TYPE_CODE (type) == TYPE_CODE_FLT
@@ -3348,26 +3455,34 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
          FP0.  */
       if (mips_debug)
        fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n");
-      switch (TARGET_BYTE_ORDER)
+      switch (gdbarch_byte_order (current_gdbarch))
        {
        case BFD_ENDIAN_LITTLE:
          mips_xfer_register (regcache,
-                             NUM_REGS + mips_regnum (current_gdbarch)->fp0 +
-                             0, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+                             gdbarch_num_regs (current_gdbarch)
+                               + mips_regnum (current_gdbarch)->fp0 +
+                             0, 4, gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, 0);
          mips_xfer_register (regcache,
-                             NUM_REGS + mips_regnum (current_gdbarch)->fp0 +
-                             1, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 4);
+                             gdbarch_num_regs (current_gdbarch)
+                               + mips_regnum (current_gdbarch)->fp0 + 1,
+                             4, gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, 4);
          break;
        case BFD_ENDIAN_BIG:
          mips_xfer_register (regcache,
-                             NUM_REGS + mips_regnum (current_gdbarch)->fp0 +
-                             1, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+                             gdbarch_num_regs (current_gdbarch)
+                               + mips_regnum (current_gdbarch)->fp0 + 1,
+                             4, gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, 0);
          mips_xfer_register (regcache,
-                             NUM_REGS + mips_regnum (current_gdbarch)->fp0 +
-                             0, 4, TARGET_BYTE_ORDER, readbuf, writebuf, 4);
+                             gdbarch_num_regs (current_gdbarch)
+                               + mips_regnum (current_gdbarch)->fp0 + 0,
+                             4, gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, 4);
          break;
        default:
-         internal_error (__FILE__, __LINE__, "bad switch");
+         internal_error (__FILE__, __LINE__, _("bad switch"));
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
@@ -3388,7 +3503,7 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
       /* A struct that contains one or two floats.  Each value is part
          in the least significant part of their floating point
          register..  */
-      bfd_byte reg[MAX_REGISTER_SIZE];
+      gdb_byte reg[MAX_REGISTER_SIZE];
       int regnum;
       int field;
       for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0;
@@ -3399,9 +3514,11 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n",
                                offset);
-         mips_xfer_register (regcache, NUM_REGS + regnum,
+         mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+                                       + regnum,
                              TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
-                             TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+                             gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, offset);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
@@ -3425,7 +3542,8 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
                                offset, xfer, regnum);
-         mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+         mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+                                       + regnum, xfer,
                              BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
@@ -3435,21 +3553,23 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
     {
       /* A scalar extract each part but least-significant-byte
          justified.  o32 thinks registers are 4 byte, regardless of
-         the ISA.  mips_stack_argsize controls this.  */
+         the ISA.  */
       int offset;
       int regnum;
       for (offset = 0, regnum = MIPS_V0_REGNUM;
           offset < TYPE_LENGTH (type);
-          offset += mips_stack_argsize (gdbarch), regnum++)
+          offset += MIPS32_REGSIZE, regnum++)
        {
-         int xfer = mips_stack_argsize (gdbarch);
+         int xfer = MIPS32_REGSIZE;
          if (offset + xfer > TYPE_LENGTH (type))
            xfer = TYPE_LENGTH (type) - offset;
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
                                offset, xfer, regnum);
-         mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
-                             TARGET_BYTE_ORDER, readbuf, writebuf, offset);
+         mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+                                       + regnum, xfer,
+                             gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, offset);
        }
       return RETURN_VALUE_REGISTER_CONVENTION;
     }
@@ -3492,8 +3612,13 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* Now make space on the stack for the args.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])),
-                    mips_stack_argsize (gdbarch));
+    {
+      struct type *arg_type = check_typedef (value_type (args[argnum]));
+      int arglen = TYPE_LENGTH (arg_type);
+
+      /* Allocate space on the stack.  */
+      len += align_up (arglen, MIPS64_REGSIZE);
+    }
   sp -= align_up (len, 16);
 
   if (mips_debug)
@@ -3512,8 +3637,8 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
        fprintf_unfiltered (gdb_stdlog,
                            "mips_o64_push_dummy_call: struct_return reg=%d 0x%s\n",
                            argreg, paddr_nz (struct_addr));
-      write_register (argreg++, struct_addr);
-      stack_offset += mips_stack_argsize (gdbarch);
+      regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
+      stack_offset += MIPS64_REGSIZE;
     }
 
   /* Now load as many as possible of the first arguments into
@@ -3521,9 +3646,9 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
      from first to last.  */
   for (argnum = 0; argnum < nargs; argnum++)
     {
-      char *val;
+      const gdb_byte *val;
       struct value *arg = args[argnum];
-      struct type *arg_type = check_typedef (VALUE_TYPE (arg));
+      struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
       enum type_code typecode = TYPE_CODE (arg_type);
 
@@ -3532,19 +3657,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                            "mips_o64_push_dummy_call: %d len=%d type=%d",
                            argnum + 1, len, (int) typecode);
 
-      val = (char *) VALUE_CONTENTS (arg);
-
-      /* 32-bit ABIs always start floating point arguments in an
-         even-numbered floating point register.  Round the FP register
-         up before the check to see if there are any FP registers
-         left.  O32/O64 targets also pass the FP in the integer
-         registers so also round up normal registers.  */
-      if (mips_abi_regsize (gdbarch) < 8
-         && fp_register_arg_p (typecode, arg_type))
-       {
-         if ((float_argreg & 1))
-           float_argreg++;
-       }
+      val = value_contents (arg);
 
       /* Floating point arguments passed in registers have to be
          treated specially.  On 32-bit architectures, doubles
@@ -3559,86 +3672,35 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
       if (fp_register_arg_p (typecode, arg_type)
          && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
        {
-         if (mips_abi_regsize (gdbarch) < 8 && len == 8)
-           {
-             int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
-             unsigned long regval;
-
-             /* Write the low word of the double to the even register(s).  */
-             regval = extract_unsigned_integer (val + low_offset, 4);
-             if (mips_debug)
-               fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
-                                   float_argreg, phex (regval, 4));
-             write_register (float_argreg++, regval);
-             if (mips_debug)
-               fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
-                                   argreg, phex (regval, 4));
-             write_register (argreg++, regval);
-
-             /* Write the high word of the double to the odd register(s).  */
-             regval = extract_unsigned_integer (val + 4 - low_offset, 4);
-             if (mips_debug)
-               fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
-                                   float_argreg, phex (regval, 4));
-             write_register (float_argreg++, regval);
-
-             if (mips_debug)
-               fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
-                                   argreg, phex (regval, 4));
-             write_register (argreg++, regval);
-           }
-         else
-           {
-             /* This is a floating point value that fits entirely
-                in a single register.  */
-             /* On 32 bit ABI's the float_argreg is further adjusted
-                above to ensure that it is even register aligned.  */
-             LONGEST regval = extract_unsigned_integer (val, len);
-             if (mips_debug)
-               fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
-                                   float_argreg, phex (regval, len));
-             write_register (float_argreg++, regval);
-             /* CAGNEY: 32 bit MIPS ABI's always reserve two FP
-                registers for each argument.  The below is (my
-                guess) to ensure that the corresponding integer
-                register has reserved the same space.  */
-             if (mips_debug)
-               fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
-                                   argreg, phex (regval, len));
-             write_register (argreg, regval);
-             argreg += (mips_abi_regsize (gdbarch) == 8) ? 1 : 2;
-           }
+         LONGEST regval = extract_unsigned_integer (val, len);
+         if (mips_debug)
+           fprintf_unfiltered (gdb_stdlog, " - fpreg=%d val=%s",
+                               float_argreg, phex (regval, len));
+         regcache_cooked_write_unsigned (regcache, float_argreg++, regval);
+         if (mips_debug)
+           fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
+                               argreg, phex (regval, len));
+         regcache_cooked_write_unsigned (regcache, argreg, regval);
+         argreg++;
          /* Reserve space for the FP register.  */
-         stack_offset += align_up (len, mips_stack_argsize (gdbarch));
+         stack_offset += align_up (len, MIPS64_REGSIZE);
        }
       else
        {
          /* Copy the argument to general registers or the stack in
             register-sized pieces.  Large arguments are split between
             registers and stack.  */
-         /* Note: structs whose size is not a multiple of
-            mips_abi_regsize() are treated specially: Irix cc passes
-            them in registers where gcc sometimes puts them on the
-            stack.  For maximum compatibility, we will put them in
-            both places.  */
-         int odd_sized_struct = ((len > mips_abi_regsize (gdbarch))
-                                 && (len % mips_abi_regsize (gdbarch) != 0));
-         /* Structures should be aligned to eight bytes (even arg registers)
-            on MIPS_ABI_O32, if their first member has double precision.  */
-         if (mips_abi_regsize (gdbarch) < 8
-             && mips_type_needs_double_align (arg_type))
-           {
-             if ((argreg & 1))
-               argreg++;
-           }
-         /* Note: Floating-point values that didn't fit into an FP
-            register are only written to memory.  */
+         /* Note: structs whose size is not a multiple of MIPS64_REGSIZE
+            are treated specially: Irix cc passes them in registers
+            where gcc sometimes puts them on the stack.  For maximum
+            compatibility, we will put them in both places.  */
+         int odd_sized_struct = (len > MIPS64_REGSIZE
+                                 && len % MIPS64_REGSIZE != 0);
          while (len > 0)
            {
              /* Remember if the argument was written to the stack.  */
              int stack_used_p = 0;
-             int partial_len = (len < mips_abi_regsize (gdbarch)
-                                ? len : mips_abi_regsize (gdbarch));
+             int partial_len = (len < MIPS64_REGSIZE ? len : MIPS64_REGSIZE);
 
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
@@ -3646,21 +3708,20 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
              /* Write this portion of the argument to the stack.  */
              if (argreg > MIPS_LAST_ARG_REGNUM
-                 || odd_sized_struct
-                 || fp_register_arg_p (typecode, arg_type))
+                 || odd_sized_struct)
                {
                  /* Should shorter than int integer values be
                     promoted to int before being stored? */
                  int longword_offset = 0;
                  CORE_ADDR addr;
                  stack_used_p = 1;
-                 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+                 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
                    {
-                     if (mips_stack_argsize (gdbarch) == 8
-                         && (typecode == TYPE_CODE_INT
-                             || typecode == TYPE_CODE_PTR
-                             || typecode == TYPE_CODE_FLT) && len <= 4)
-                       longword_offset = mips_stack_argsize (gdbarch) - len;
+                     if ((typecode == TYPE_CODE_INT
+                          || typecode == TYPE_CODE_PTR
+                          || typecode == TYPE_CODE_FLT)
+                         && len <= 4)
+                       longword_offset = MIPS64_REGSIZE - len;
                    }
 
                  if (mips_debug)
@@ -3688,12 +3749,10 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                }
 
              /* Note!!! This is NOT an else clause.  Odd sized
-                structs may go thru BOTH paths.  Floating point
-                arguments will not.  */
+                structs may go thru BOTH paths.  */
              /* Write this portion of the argument to a general
                 purpose register.  */
-             if (argreg <= MIPS_LAST_ARG_REGNUM
-                 && !fp_register_arg_p (typecode, arg_type))
+             if (argreg <= MIPS_LAST_ARG_REGNUM)
                {
                  LONGEST regval = extract_signed_integer (val, partial_len);
                  /* Value may need to be sign extended, because
@@ -3706,38 +3765,20 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                     big endian targets.
 
                     It does not seem to be necessary to do the
-                    same for integral types.
+                    same for integral types. */
 
-                    Also don't do this adjustment on O64 binaries.
-
-                    cagney/2001-07-23: gdb/179: Also, GCC, when
-                    outputting LE O32 with sizeof (struct) <
-                    mips_abi_regsize(), generates a left shift as
-                    part of storing the argument in a register a
-                    register (the left shift isn't generated when
-                    sizeof (struct) >= mips_abi_regsize()).  Since
-                    it is quite possible that this is GCC
-                    contradicting the LE/O32 ABI, GDB has not been
-                    adjusted to accommodate this.  Either someone
-                    needs to demonstrate that the LE/O32 ABI
-                    specifies such a left shift OR this new ABI gets
-                    identified as such and GDB gets tweaked
-                    accordingly.  */
-
-                 if (mips_abi_regsize (gdbarch) < 8
-                     && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-                     && partial_len < mips_abi_regsize (gdbarch)
-                     && (typecode == TYPE_CODE_STRUCT ||
-                         typecode == TYPE_CODE_UNION))
-                   regval <<= ((mips_abi_regsize (gdbarch) - partial_len) *
-                               TARGET_CHAR_BIT);
+                 if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG
+                     && partial_len < MIPS64_REGSIZE
+                     && (typecode == TYPE_CODE_STRUCT
+                         || typecode == TYPE_CODE_UNION))
+                   regval <<= ((MIPS64_REGSIZE - partial_len)
+                               * TARGET_CHAR_BIT);
 
                  if (mips_debug)
                    fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
                                      argreg,
-                                     phex (regval,
-                                           mips_abi_regsize (gdbarch)));
-                 write_register (argreg, regval);
+                                     phex (regval, MIPS64_REGSIZE));
+                 regcache_cooked_write_unsigned (regcache, argreg, regval);
                  argreg++;
 
                  /* Prevent subsequent floating point arguments from
@@ -3756,8 +3797,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                 refered to as their "home".  Consequently, space is
                 always allocated.  */
 
-             stack_offset += align_up (partial_len,
-                                       mips_stack_argsize (gdbarch));
+             stack_offset += align_up (partial_len, MIPS64_REGSIZE);
            }
        }
       if (mips_debug)
@@ -3773,9 +3813,51 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 static enum return_value_convention
 mips_o64_return_value (struct gdbarch *gdbarch,
                       struct type *type, struct regcache *regcache,
-                      void *readbuf, const void *writebuf)
+                      gdb_byte *readbuf, const gdb_byte *writebuf)
 {
-  return RETURN_VALUE_STRUCT_CONVENTION;
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+
+  if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+      || TYPE_CODE (type) == TYPE_CODE_UNION
+      || TYPE_CODE (type) == TYPE_CODE_ARRAY)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else if (fp_register_arg_p (TYPE_CODE (type), type))
+    {
+      /* A floating-point value.  It fits in the least significant
+         part of FP0.  */
+      if (mips_debug)
+       fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
+      mips_xfer_register (regcache,
+                         gdbarch_num_regs (current_gdbarch)
+                           + mips_regnum (current_gdbarch)->fp0,
+                         TYPE_LENGTH (type),
+                         gdbarch_byte_order (current_gdbarch),
+                         readbuf, writebuf, 0);
+      return RETURN_VALUE_REGISTER_CONVENTION;
+    }
+  else
+    {
+      /* A scalar extract each part but least-significant-byte
+         justified. */
+      int offset;
+      int regnum;
+      for (offset = 0, regnum = MIPS_V0_REGNUM;
+          offset < TYPE_LENGTH (type);
+          offset += MIPS64_REGSIZE, regnum++)
+       {
+         int xfer = MIPS64_REGSIZE;
+         if (offset + xfer > TYPE_LENGTH (type))
+           xfer = TYPE_LENGTH (type) - offset;
+         if (mips_debug)
+           fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
+                               offset, xfer, regnum);
+         mips_xfer_register (regcache, gdbarch_num_regs (current_gdbarch)
+                                       + regnum, xfer,
+                             gdbarch_byte_order (current_gdbarch),
+                             readbuf, writebuf, offset);
+       }
+      return RETURN_VALUE_REGISTER_CONVENTION;
+    }
 }
 
 /* Floating point register management.
@@ -3811,19 +3893,13 @@ mips_o64_return_value (struct gdbarch *gdbarch,
 static struct type *
 mips_float_register_type (void)
 {
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-    return builtin_type_ieee_single_big;
-  else
-    return builtin_type_ieee_single_little;
+  return builtin_type_ieee_single;
 }
 
 static struct type *
 mips_double_register_type (void)
 {
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-    return builtin_type_ieee_double_big;
-  else
-    return builtin_type_ieee_double_little;
+  return builtin_type_ieee_double;
 }
 
 /* Copy a 32-bit single-precision value from the current frame
@@ -3831,20 +3907,21 @@ mips_double_register_type (void)
 
 static void
 mips_read_fp_register_single (struct frame_info *frame, int regno,
-                             char *rare_buffer)
+                             gdb_byte *rare_buffer)
 {
   int raw_size = register_size (current_gdbarch, regno);
-  char *raw_buffer = alloca (raw_size);
+  gdb_byte *raw_buffer = alloca (raw_size);
 
   if (!frame_register_read (frame, regno, raw_buffer))
-    error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
+    error (_("can't read register %d (%s)"),
+          regno, gdbarch_register_name (current_gdbarch, regno));
   if (raw_size == 8)
     {
       /* We have a 64-bit value for this register.  Find the low-order
          32 bits.  */
       int offset;
 
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
        offset = 4;
       else
        offset = 0;
@@ -3863,27 +3940,28 @@ mips_read_fp_register_single (struct frame_info *frame, int regno,
 
 static void
 mips_read_fp_register_double (struct frame_info *frame, int regno,
-                             char *rare_buffer)
+                             gdb_byte *rare_buffer)
 {
   int raw_size = register_size (current_gdbarch, regno);
 
-  if (raw_size == 8 && !mips2_fp_compat ())
+  if (raw_size == 8 && !mips2_fp_compat (frame))
     {
       /* We have a 64-bit value for this register, and we should use
          all 64 bits.  */
       if (!frame_register_read (frame, regno, rare_buffer))
-       error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
+       error (_("can't read register %d (%s)"),
+              regno, gdbarch_register_name (current_gdbarch, regno));
     }
   else
     {
       if ((regno - mips_regnum (current_gdbarch)->fp0) & 1)
        internal_error (__FILE__, __LINE__,
-                       "mips_read_fp_register_double: bad access to "
-                       "odd-numbered FP register");
+                       _("mips_read_fp_register_double: bad access to "
+                       "odd-numbered FP register"));
 
       /* mips_read_fp_register_single will find the correct 32 bits from
          each register.  */
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
        {
          mips_read_fp_register_single (frame, regno, rare_buffer + 4);
          mips_read_fp_register_single (frame, regno + 1, rare_buffer);
@@ -3900,20 +3978,21 @@ static void
 mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
                        int regnum)
 {                              /* do values for FP (float) regs */
-  char *raw_buffer;
+  gdb_byte *raw_buffer;
   double doub, flt1;   /* doubles extracted from raw hex data */
   int inv1, inv2;
 
-  raw_buffer =
-    (char *) alloca (2 *
-                    register_size (current_gdbarch,
-                                   mips_regnum (current_gdbarch)->fp0));
+  raw_buffer = alloca (2 * register_size (current_gdbarch,
+                                         mips_regnum (current_gdbarch)->fp0));
 
-  fprintf_filtered (file, "%s:", REGISTER_NAME (regnum));
-  fprintf_filtered (file, "%*s", 4 - (int) strlen (REGISTER_NAME (regnum)),
+  fprintf_filtered (file, "%s:",
+                   gdbarch_register_name (current_gdbarch, regnum));
+  fprintf_filtered (file, "%*s",
+                   4 - (int) strlen (gdbarch_register_name
+                                       (current_gdbarch, regnum)),
                    "");
 
-  if (register_size (current_gdbarch, regnum) == 4 || mips2_fp_compat ())
+  if (register_size (current_gdbarch, regnum) == 4 || mips2_fp_compat (frame))
     {
       /* 4-byte registers: Print hex and floating.  Also print even
          numbered registers as doubles.  */
@@ -3971,13 +4050,13 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
 
 static void
 mips_print_register (struct ui_file *file, struct frame_info *frame,
-                    int regnum, int all)
+                    int regnum)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
-  char raw_buffer[MAX_REGISTER_SIZE];
+  gdb_byte raw_buffer[MAX_REGISTER_SIZE];
   int offset;
 
-  if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
+  if (TYPE_CODE (register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
     {
       mips_print_fp_register (file, frame, regnum);
       return;
@@ -3986,11 +4065,12 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
   /* Get the data in raw format.  */
   if (!frame_register_read (frame, regnum, raw_buffer))
     {
-      fprintf_filtered (file, "%s: [Invalid]", REGISTER_NAME (regnum));
+      fprintf_filtered (file, "%s: [Invalid]",
+                       gdbarch_register_name (current_gdbarch, regnum));
       return;
     }
 
-  fputs_filtered (REGISTER_NAME (regnum), file);
+  fputs_filtered (gdbarch_register_name (current_gdbarch, regnum), file);
 
   /* The problem with printing numeric register names (r26, etc.) is that
      the user can't use them on input.  Probably the best solution is to
@@ -4001,7 +4081,7 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
   else
     fprintf_filtered (file, ": ");
 
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     offset =
       register_size (current_gdbarch,
                     regnum) - register_size (current_gdbarch, regnum);
@@ -4009,7 +4089,7 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
     offset = 0;
 
   print_scalar_formatted (raw_buffer + offset,
-                         gdbarch_register_type (gdbarch, regnum), 'x', 0,
+                         register_type (gdbarch, regnum), 'x', 0,
                          file);
 }
 
@@ -4035,60 +4115,87 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   /* do values for GP (int) regs */
-  char raw_buffer[MAX_REGISTER_SIZE];
+  gdb_byte raw_buffer[MAX_REGISTER_SIZE];
   int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8);       /* display cols per row */
   int col, byte;
   int regnum;
 
   /* For GP registers, we print a separate row of names above the vals */
-  fprintf_filtered (file, "     ");
   for (col = 0, regnum = start_regnum;
-       col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+       col < ncols && regnum < gdbarch_num_regs (current_gdbarch)
+                              + gdbarch_num_pseudo_regs (current_gdbarch);
+       regnum++)
     {
-      if (*REGISTER_NAME (regnum) == '\0')
+      if (*gdbarch_register_name (current_gdbarch, regnum) == '\0')
        continue;               /* unused register */
-      if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
+      if (TYPE_CODE (register_type (gdbarch, regnum)) ==
          TYPE_CODE_FLT)
        break;                  /* end the row: reached FP register */
+      /* Large registers are handled separately.  */
+      if (register_size (current_gdbarch, regnum)
+         > mips_abi_regsize (current_gdbarch))
+       {
+         if (col > 0)
+           break;              /* End the row before this register.  */
+
+         /* Print this register on a row by itself.  */
+         mips_print_register (file, frame, regnum);
+         fprintf_filtered (file, "\n");
+         return regnum + 1;
+       }
+      if (col == 0)
+       fprintf_filtered (file, "     ");
       fprintf_filtered (file,
                        mips_abi_regsize (current_gdbarch) == 8 ? "%17s" : "%9s",
-                       REGISTER_NAME (regnum));
+                       gdbarch_register_name (current_gdbarch, regnum));
       col++;
     }
+
+  if (col == 0)
+    return regnum;
+
   /* print the R0 to R31 names */
-  if ((start_regnum % NUM_REGS) < MIPS_NUMREGS)
-    fprintf_filtered (file, "\n R%-4d", start_regnum % NUM_REGS);
+  if ((start_regnum % gdbarch_num_regs (current_gdbarch)) < MIPS_NUMREGS)
+    fprintf_filtered (file, "\n R%-4d",
+                     start_regnum % gdbarch_num_regs (current_gdbarch));
   else
     fprintf_filtered (file, "\n      ");
 
   /* now print the values in hex, 4 or 8 to the row */
   for (col = 0, regnum = start_regnum;
-       col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS; regnum++)
+       col < ncols && regnum < gdbarch_num_regs (current_gdbarch)
+                              + gdbarch_num_pseudo_regs (current_gdbarch);
+       regnum++)
     {
-      if (*REGISTER_NAME (regnum) == '\0')
+      if (*gdbarch_register_name (current_gdbarch, regnum) == '\0')
        continue;               /* unused register */
-      if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
+      if (TYPE_CODE (register_type (gdbarch, regnum)) ==
          TYPE_CODE_FLT)
        break;                  /* end row: reached FP register */
+      if (register_size (current_gdbarch, regnum)
+         > mips_abi_regsize (current_gdbarch))
+       break;                  /* End row: large register.  */
+
       /* OK: get the data in raw format.  */
       if (!frame_register_read (frame, regnum, raw_buffer))
-       error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
+       error (_("can't read register %d (%s)"),
+              regnum, gdbarch_register_name (current_gdbarch, regnum));
       /* pad small registers */
       for (byte = 0;
           byte < (mips_abi_regsize (current_gdbarch)
                   - register_size (current_gdbarch, regnum)); byte++)
        printf_filtered ("  ");
       /* Now print the register value in hex, endian order. */
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+      if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
        for (byte =
             register_size (current_gdbarch,
                            regnum) - register_size (current_gdbarch, regnum);
             byte < register_size (current_gdbarch, regnum); byte++)
-         fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
+         fprintf_filtered (file, "%02x", raw_buffer[byte]);
       else
        for (byte = register_size (current_gdbarch, regnum) - 1;
             byte >= 0; byte--)
-         fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
+         fprintf_filtered (file, "%02x", raw_buffer[byte]);
       fprintf_filtered (file, " ");
       col++;
     }
@@ -4106,20 +4213,21 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
 {
   if (regnum != -1)            /* do one specified register */
     {
-      gdb_assert (regnum >= NUM_REGS);
-      if (*(REGISTER_NAME (regnum)) == '\0')
-       error ("Not a valid register for the current processor type");
+      gdb_assert (regnum >= gdbarch_num_regs (current_gdbarch));
+      if (*(gdbarch_register_name (current_gdbarch, regnum)) == '\0')
+       error (_("Not a valid register for the current processor type"));
 
-      mips_print_register (file, frame, regnum, 0);
+      mips_print_register (file, frame, regnum);
       fprintf_filtered (file, "\n");
     }
   else
     /* do all (or most) registers */
     {
-      regnum = NUM_REGS;
-      while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
+      regnum = gdbarch_num_regs (current_gdbarch);
+      while (regnum < gdbarch_num_regs (current_gdbarch)
+                     + gdbarch_num_pseudo_regs (current_gdbarch))
        {
-         if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) ==
+         if (TYPE_CODE (register_type (gdbarch, regnum)) ==
              TYPE_CODE_FLT)
            {
              if (all)          /* true for "INFO ALL-REGISTERS" command */
@@ -4150,16 +4258,22 @@ is_delayed (unsigned long insn)
 }
 
 int
-mips_step_skips_delay (CORE_ADDR pc)
+mips_single_step_through_delay (struct gdbarch *gdbarch,
+                               struct frame_info *frame)
 {
-  char buf[MIPS_INSN32_SIZE];
+  CORE_ADDR pc = get_frame_pc (frame);
+  gdb_byte buf[MIPS_INSN32_SIZE];
 
   /* There is no branch delay slot on MIPS16.  */
   if (mips_pc_is_mips16 (pc))
     return 0;
 
-  if (target_read_memory (pc, buf, sizeof buf) != 0)
-    /* If error reading memory, guess that it is not a delayed branch.  */
+  if (!breakpoint_here_p (pc + 4))
+    return 0;
+
+  if (!safe_frame_unwind_memory (frame, pc, buf, sizeof buf))
+    /* If error reading memory, guess that it is not a delayed
+       branch.  */
     return 0;
   return is_delayed (extract_unsigned_integer (buf, sizeof buf));
 }
@@ -4240,7 +4354,7 @@ show_mipsfpu_command (char *args, int from_tty)
       fpu = "absent (none)";
       break;
     default:
-      internal_error (__FILE__, __LINE__, "bad switch");
+      internal_error (__FILE__, __LINE__, _("bad switch"));
     }
   if (mips_fpu_type_auto)
     printf_unfiltered
@@ -4271,7 +4385,7 @@ set_mipsfpu_single_command (char *args, int from_tty)
      instead of relying on globals.  Doing that would let generic code
      handle the search for this specific architecture.  */
   if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, "set mipsfpu failed");
+    internal_error (__FILE__, __LINE__, _("set mipsfpu failed"));
 }
 
 static void
@@ -4285,7 +4399,7 @@ set_mipsfpu_double_command (char *args, int from_tty)
      instead of relying on globals.  Doing that would let generic code
      handle the search for this specific architecture.  */
   if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, "set mipsfpu failed");
+    internal_error (__FILE__, __LINE__, _("set mipsfpu failed"));
 }
 
 static void
@@ -4299,7 +4413,7 @@ set_mipsfpu_none_command (char *args, int from_tty)
      instead of relying on globals.  Doing that would let generic code
      handle the search for this specific architecture.  */
   if (!gdbarch_update_p (info))
-    internal_error (__FILE__, __LINE__, "set mipsfpu failed");
+    internal_error (__FILE__, __LINE__, _("set mipsfpu failed"));
 }
 
 static void
@@ -4318,10 +4432,10 @@ void
 deprecated_mips_set_processor_regs_hack (void)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  CORE_ADDR prid;
-
-  prid = read_register (PRID_REGNUM);
+  ULONGEST prid;
 
+  regcache_cooked_read_unsigned (get_current_regcache (),
+                                MIPS_PRID_REGNUM, &prid);
   if ((prid & ~0xf) == 0x700)
     tdep->mips_processor_reg_names = mips_r3041_reg_names;
 }
@@ -4371,27 +4485,27 @@ gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info)
     info->disassembler_options = "gpr-names=32";
 
   /* Call the appropriate disassembler based on the target endian-ness.  */
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     return print_insn_big_mips (memaddr, info);
   else
     return print_insn_little_mips (memaddr, info);
 }
 
-/* This function implements the BREAKPOINT_FROM_PC macro.  It uses the program
-   counter value to determine whether a 16- or 32-bit breakpoint should be
-   used.  It returns a pointer to a string of bytes that encode a breakpoint
-   instruction, stores the length of the string to *lenptr, and adjusts pc
-   (if necessary) to point to the actual memory location where the
-   breakpoint should be inserted.  */
+/* This function implements gdbarch_breakpoint_from_pc.  It uses the program
+   counter value to determine whether a 16- or 32-bit breakpoint should be used.
+   It returns a pointer to a string of bytes that encode a breakpoint
+   instruction, stores the length of the string to *lenptr, and adjusts pc (if
+   necessary) to point to the actual memory location where the breakpoint
+   should be inserted.  */
 
-static const unsigned char *
+static const gdb_byte *
 mips_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
 {
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+  if (gdbarch_byte_order (current_gdbarch) == BFD_ENDIAN_BIG)
     {
       if (mips_pc_is_mips16 (*pcptr))
        {
-         static unsigned char mips16_big_breakpoint[] = { 0xe8, 0xa5 };
+         static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
          *pcptr = unmake_mips16_addr (*pcptr);
          *lenptr = sizeof (mips16_big_breakpoint);
          return mips16_big_breakpoint;
@@ -4401,9 +4515,9 @@ mips_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
          /* The IDT board uses an unusual breakpoint value, and
             sometimes gets confused when it sees the usual MIPS
             breakpoint instruction.  */
-         static unsigned char big_breakpoint[] = { 0, 0x5, 0, 0xd };
-         static unsigned char pmon_big_breakpoint[] = { 0, 0, 0, 0xd };
-         static unsigned char idt_big_breakpoint[] = { 0, 0, 0x0a, 0xd };
+         static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd };
+         static gdb_byte pmon_big_breakpoint[] = { 0, 0, 0, 0xd };
+         static gdb_byte idt_big_breakpoint[] = { 0, 0, 0x0a, 0xd };
 
          *lenptr = sizeof (big_breakpoint);
 
@@ -4421,16 +4535,16 @@ mips_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
     {
       if (mips_pc_is_mips16 (*pcptr))
        {
-         static unsigned char mips16_little_breakpoint[] = { 0xa5, 0xe8 };
+         static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
          *pcptr = unmake_mips16_addr (*pcptr);
          *lenptr = sizeof (mips16_little_breakpoint);
          return mips16_little_breakpoint;
        }
       else
        {
-         static unsigned char little_breakpoint[] = { 0xd, 0, 0x5, 0 };
-         static unsigned char pmon_little_breakpoint[] = { 0xd, 0, 0, 0 };
-         static unsigned char idt_little_breakpoint[] = { 0xd, 0x0a, 0, 0 };
+         static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };
+         static gdb_byte pmon_little_breakpoint[] = { 0xd, 0, 0, 0 };
+         static gdb_byte idt_little_breakpoint[] = { 0xd, 0x0a, 0, 0 };
 
          *lenptr = sizeof (little_breakpoint);
 
@@ -4463,7 +4577,7 @@ mips_breakpoint_from_pc (CORE_ADDR *pcptr, int *lenptr)
    gory details.  */
 
 static CORE_ADDR
-mips_skip_trampoline_code (CORE_ADDR pc)
+mips_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
   char *name;
   CORE_ADDR start_addr;
@@ -4476,14 +4590,14 @@ mips_skip_trampoline_code (CORE_ADDR pc)
      target PC is in $31 ($ra).  */
   if (strcmp (name, "__mips16_ret_sf") == 0
       || strcmp (name, "__mips16_ret_df") == 0)
-    return read_signed_register (MIPS_RA_REGNUM);
+    return get_frame_register_signed (frame, MIPS_RA_REGNUM);
 
   if (strncmp (name, "__mips16_call_stub_", 19) == 0)
     {
       /* If the PC is in __mips16_call_stub_{1..10}, this is a call stub
          and the target PC is in $2.  */
       if (name[19] >= '0' && name[19] <= '9')
-       return read_signed_register (2);
+       return get_frame_register_signed (frame, 2);
 
       /* If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e.
          before the jal instruction, this is effectively a call stub
@@ -4505,7 +4619,7 @@ mips_skip_trampoline_code (CORE_ADDR pc)
                 So scan down to the lui/addi and extract the target
                 address from those two instructions.  */
 
-             CORE_ADDR target_pc = read_signed_register (2);
+             CORE_ADDR target_pc = get_frame_register_signed (frame, 2);
              ULONGEST inst;
              int i;
 
@@ -4536,91 +4650,14 @@ mips_skip_trampoline_code (CORE_ADDR pc)
          else
            /* This is the 'return' part of a call stub.  The return
               address is in $r18.  */
-           return read_signed_register (18);
+           return get_frame_register_signed (frame, 18);
        }
     }
   return 0;                    /* not a stub */
 }
 
-
-/* Return non-zero if the PC is inside a call thunk (aka stub or trampoline).
-   This implements the IN_SOLIB_CALL_TRAMPOLINE macro.  */
-
-static int
-mips_in_call_stub (CORE_ADDR pc, char *name)
-{
-  CORE_ADDR start_addr;
-
-  /* Find the starting address of the function containing the PC.  If the
-     caller didn't give us a name, look it up at the same time.  */
-  if (find_pc_partial_function (pc, name ? NULL : &name, &start_addr, NULL) ==
-      0)
-    return 0;
-
-  if (strncmp (name, "__mips16_call_stub_", 19) == 0)
-    {
-      /* If the PC is in __mips16_call_stub_{1..10}, this is a call stub.  */
-      if (name[19] >= '0' && name[19] <= '9')
-       return 1;
-      /* If the PC at the start of __mips16_call_stub_{s,d}f_{0..10}, i.e.
-         before the jal instruction, this is effectively a call stub.  */
-      else if (name[19] == 's' || name[19] == 'd')
-       return pc == start_addr;
-    }
-
-  return 0;                    /* not a stub */
-}
-
-
-/* Return non-zero if the PC is inside a return thunk (aka stub or
-   trampoline).  */
-
-static int
-mips_in_solib_return_trampoline (CORE_ADDR pc, char *name)
-{
-  CORE_ADDR start_addr;
-
-  /* Find the starting address of the function containing the PC.  */
-  if (find_pc_partial_function (pc, NULL, &start_addr, NULL) == 0)
-    return 0;
-
-  /* If the PC is in __mips16_ret_{d,s}f, this is a return stub.  */
-  if (strcmp (name, "__mips16_ret_sf") == 0
-      || strcmp (name, "__mips16_ret_df") == 0)
-    return 1;
-
-  /* If the PC is in __mips16_call_stub_{s,d}f_{0..10} but not at the start,
-     i.e. after the jal instruction, this is effectively a return stub.  */
-  if (strncmp (name, "__mips16_call_stub_", 19) == 0
-      && (name[19] == 's' || name[19] == 'd') && pc != start_addr)
-    return 1;
-
-  return 0;                    /* not a stub */
-}
-
-
-/* Return non-zero if the PC is in a library helper function that
-   should be ignored.  This implements the
-   DEPRECATED_IGNORE_HELPER_CALL macro.  */
-
-int
-mips_ignore_helper (CORE_ADDR pc)
-{
-  char *name;
-
-  /* Find the starting address and name of the function containing the PC.  */
-  if (find_pc_partial_function (pc, &name, NULL, NULL) == 0)
-    return 0;
-
-  /* If the PC is in __mips16_ret_{d,s}f, this is a library helper function
-     that we want to ignore.  */
-  return (strcmp (name, "__mips16_ret_sf") == 0
-         || strcmp (name, "__mips16_ret_df") == 0);
-}
-
-
 /* Convert a dbx stab register number (from `r' declaration) to a GDB
-   [1 * NUM_REGS .. 2 * NUM_REGS) REGNUM.  */
+   [1 * gdbarch_num_regs .. 2 * gdbarch_num_regs) REGNUM.  */
 
 static int
 mips_stab_reg_to_regnum (int num)
@@ -4637,13 +4674,14 @@ mips_stab_reg_to_regnum (int num)
   else
     /* This will hopefully (eventually) provoke a warning.  Should
        we be calling complaint() here?  */
-    return NUM_REGS + NUM_PSEUDO_REGS;
-  return NUM_REGS + regnum;
+    return gdbarch_num_regs (current_gdbarch)
+          + gdbarch_num_pseudo_regs (current_gdbarch);
+  return gdbarch_num_regs (current_gdbarch) + regnum;
 }
 
 
 /* Convert a dwarf, dwarf2, or ecoff register number to a GDB [1 *
-   NUM_REGS .. 2 * NUM_REGS) REGNUM.  */
+   gdbarch_num_regs .. 2 * gdbarch_num_regs) REGNUM.  */
 
 static int
 mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num)
@@ -4660,38 +4698,39 @@ mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num)
   else
     /* This will hopefully (eventually) provoke a warning.  Should we
        be calling complaint() here?  */
-    return NUM_REGS + NUM_PSEUDO_REGS;
-  return NUM_REGS + regnum;
+    return gdbarch_num_regs (current_gdbarch)
+          + gdbarch_num_pseudo_regs (current_gdbarch);
+  return gdbarch_num_regs (current_gdbarch) + regnum;
 }
 
 static int
 mips_register_sim_regno (int regnum)
 {
   /* Only makes sense to supply raw registers.  */
-  gdb_assert (regnum >= 0 && regnum < NUM_REGS);
+  gdb_assert (regnum >= 0 && regnum < gdbarch_num_regs (current_gdbarch));
   /* FIXME: cagney/2002-05-13: Need to look at the pseudo register to
      decide if it is valid.  Should instead define a standard sim/gdb
      register numbering scheme.  */
-  if (REGISTER_NAME (NUM_REGS + regnum) != NULL
-      && REGISTER_NAME (NUM_REGS + regnum)[0] != '\0')
+  if (gdbarch_register_name (current_gdbarch,
+                            gdbarch_num_regs
+                              (current_gdbarch) + regnum) != NULL
+      && gdbarch_register_name (current_gdbarch,
+                               gdbarch_num_regs
+                                 (current_gdbarch) + regnum)[0] != '\0')
     return regnum;
   else
     return LEGACY_SIM_REGNO_IGNORE;
 }
 
 
-/* Convert an integer into an address.  By first converting the value
-   into a pointer and then extracting it signed, the address is
-   guarenteed to be correctly sign extended.  */
+/* Convert an integer into an address.  Extracting the value signed
+   guarantees a correctly sign extended address.  */
 
 static CORE_ADDR
-mips_integer_to_address (struct type *type, void *buf)
+mips_integer_to_address (struct gdbarch *gdbarch,
+                        struct type *type, const gdb_byte *buf)
 {
-  char *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr));
-  LONGEST val = unpack_long (type, buf);
-  store_signed_integer (tmp, TYPE_LENGTH (builtin_type_void_data_ptr), val);
-  return extract_signed_integer (tmp,
-                                TYPE_LENGTH (builtin_type_void_data_ptr));
+  return (CORE_ADDR) extract_signed_integer (buf, TYPE_LENGTH (type));
 }
 
 static void
@@ -4719,7 +4758,21 @@ mips_find_abi_section (bfd *abfd, asection *sect, void *obj)
   else if (strcmp (name, ".mdebug.eabi64") == 0)
     *abip = MIPS_ABI_EABI64;
   else
-    warning ("unsupported ABI %s.", name + 8);
+    warning (_("unsupported ABI %s."), name + 8);
+}
+
+static void
+mips_find_long_section (bfd *abfd, asection *sect, void *obj)
+{
+  int *lbp = (int *) obj;
+  const char *name = bfd_get_section_name (abfd, sect);
+
+  if (strncmp (name, ".gcc_compiled_long32", 20) == 0)
+    *lbp = 32;
+  else if (strncmp (name, ".gcc_compiled_long64", 20) == 0)
+    *lbp = 64;
+  else if (strncmp (name, ".gcc_compiled_long", 18) == 0)
+    warning (_("unrecognized .gcc_compiled_longXX"));
 }
 
 static enum mips_abi
@@ -4731,7 +4784,45 @@ global_mips_abi (void)
     if (mips_abi_strings[i] == mips_abi_string)
       return (enum mips_abi) i;
 
-  internal_error (__FILE__, __LINE__, "unknown ABI string");
+  internal_error (__FILE__, __LINE__, _("unknown ABI string"));
+}
+
+static void
+mips_register_g_packet_guesses (struct gdbarch *gdbarch)
+{
+  static struct target_desc *tdesc_gp32, *tdesc_gp64;
+
+  if (tdesc_gp32 == NULL)
+    {
+      /* Create feature sets with the appropriate properties.  The values
+        are not important.  */
+
+      tdesc_gp32 = allocate_target_description ();
+      set_tdesc_property (tdesc_gp32, PROPERTY_GP32, "");
+
+      tdesc_gp64 = allocate_target_description ();
+      set_tdesc_property (tdesc_gp64, PROPERTY_GP64, "");
+    }
+
+  /* If the size matches the set of 32-bit or 64-bit integer registers,
+     assume that's what we've got.  */
+  register_remote_g_packet_guess (gdbarch, 38 * 4, tdesc_gp32);
+  register_remote_g_packet_guess (gdbarch, 38 * 8, tdesc_gp64);
+
+  /* If the size matches the full set of registers GDB traditionally
+     knows about, including floating point, for either 32-bit or
+     64-bit, assume that's what we've got.  */
+  register_remote_g_packet_guess (gdbarch, 90 * 4, tdesc_gp32);
+  register_remote_g_packet_guess (gdbarch, 90 * 8, tdesc_gp64);
+
+  /* Otherwise we don't have a useful guess.  */
+}
+
+static struct value *
+value_of_mips_user_reg (struct frame_info *frame, const void *baton)
+{
+  const int *reg_p = baton;
+  return value_of_register (*reg_p, frame);
 }
 
 static struct gdbarch *
@@ -4741,8 +4832,108 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   struct gdbarch_tdep *tdep;
   int elf_flags;
   enum mips_abi mips_abi, found_abi, wanted_abi;
-  int num_regs;
+  int i, num_regs;
   enum mips_fpu_type fpu_type;
+  struct tdesc_arch_data *tdesc_data = NULL;
+
+  /* Check any target description for validity.  */
+  if (tdesc_has_registers (info.target_desc))
+    {
+      static const char *const mips_gprs[] = {
+       "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+       "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+       "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+       "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"
+      };
+      static const char *const mips_fprs[] = {
+       "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
+       "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
+       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
+       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
+      };
+
+      const struct tdesc_feature *feature;
+      int valid_p;
+
+      feature = tdesc_find_feature (info.target_desc,
+                                   "org.gnu.gdb.mips.cpu");
+      if (feature == NULL)
+       return NULL;
+
+      tdesc_data = tdesc_data_alloc ();
+
+      valid_p = 1;
+      for (i = MIPS_ZERO_REGNUM; i <= MIPS_RA_REGNUM; i++)
+       valid_p &= tdesc_numbered_register (feature, tdesc_data, i,
+                                           mips_gprs[i]);
+
+
+      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                         MIPS_EMBED_LO_REGNUM, "lo");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                         MIPS_EMBED_HI_REGNUM, "hi");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                         MIPS_EMBED_PC_REGNUM, "pc");
+
+      if (!valid_p)
+       {
+         tdesc_data_cleanup (tdesc_data);
+         return NULL;
+       }
+
+      feature = tdesc_find_feature (info.target_desc,
+                                   "org.gnu.gdb.mips.cp0");
+      if (feature == NULL)
+       {
+         tdesc_data_cleanup (tdesc_data);
+         return NULL;
+       }
+
+      valid_p = 1;
+      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                         MIPS_EMBED_BADVADDR_REGNUM,
+                                         "badvaddr");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                         MIPS_PS_REGNUM, "status");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                         MIPS_EMBED_CAUSE_REGNUM, "cause");
+
+      if (!valid_p)
+       {
+         tdesc_data_cleanup (tdesc_data);
+         return NULL;
+       }
+
+      /* FIXME drow/2007-05-17: The FPU should be optional.  The MIPS
+        backend is not prepared for that, though.  */
+      feature = tdesc_find_feature (info.target_desc,
+                                   "org.gnu.gdb.mips.fpu");
+      if (feature == NULL)
+       {
+         tdesc_data_cleanup (tdesc_data);
+         return NULL;
+       }
+
+      valid_p = 1;
+      for (i = 0; i < 32; i++)
+       valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                           i + MIPS_EMBED_FP0_REGNUM,
+                                           mips_fprs[i]);
+
+      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                         MIPS_EMBED_FP0_REGNUM + 32, "fcsr");
+      valid_p &= tdesc_numbered_register (feature, tdesc_data,
+                                         MIPS_EMBED_FP0_REGNUM + 33, "fir");
+
+      if (!valid_p)
+       {
+         tdesc_data_cleanup (tdesc_data);
+         return NULL;
+       }
+
+      /* It would be nice to detect an attempt to use a 64-bit ABI
+        when only 32-bit registers are provided.  */
+    }
 
   /* First of all, extract the elf_flags, if available.  */
   if (info.abfd && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
@@ -4815,6 +5006,13 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        }
     }
 
+  /* Default 64-bit objects to N64 instead of O32.  */
+  if (found_abi == MIPS_ABI_UNKNOWN
+      && info.abfd != NULL
+      && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour
+      && elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64)
+    found_abi = MIPS_ABI_N64;
+
   if (gdbarch_debug)
     fprintf_unfiltered (gdb_stdlog, "mips_gdbarch_init: found_abi = %d\n",
                        found_abi);
@@ -4871,6 +5069,20 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     fprintf_unfiltered (gdb_stdlog,
                        "mips_gdbarch_init: fpu_type = %d\n", fpu_type);
 
+  /* Check for blatant incompatibilities.  */
+
+  /* If we have only 32-bit registers, then we can't debug a 64-bit
+     ABI.  */
+  if (info.target_desc
+      && tdesc_property (info.target_desc, PROPERTY_GP32) != NULL
+      && mips_abi != MIPS_ABI_EABI32
+      && mips_abi != MIPS_ABI_O32)
+    {
+      if (tdesc_data != NULL)
+       tdesc_data_cleanup (tdesc_data);
+      return NULL;
+    }
+
   /* try to find a pre-existing architecture */
   for (arches = gdbarch_list_lookup_by_info (arches, &info);
        arches != NULL;
@@ -4890,6 +5102,9 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       /* Be pedantic about which FPU is selected.  */
       if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type)
        continue;
+
+      if (tdesc_data != NULL)
+       tdesc_data_cleanup (tdesc_data);
       return arches->gdbarch;
     }
 
@@ -4901,6 +5116,23 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->found_abi = found_abi;
   tdep->mips_abi = mips_abi;
   tdep->mips_fpu_type = fpu_type;
+  tdep->register_size_valid_p = 0;
+  tdep->register_size = 0;
+
+  if (info.target_desc)
+    {
+      /* Some useful properties can be inferred from the target.  */
+      if (tdesc_property (info.target_desc, PROPERTY_GP32) != NULL)
+       {
+         tdep->register_size_valid_p = 1;
+         tdep->register_size = 4;
+       }
+      else if (tdesc_property (info.target_desc, PROPERTY_GP64) != NULL)
+       {
+         tdep->register_size_valid_p = 1;
+         tdep->register_size = 8;
+       }
+    }
 
   /* Initially set everything according to the default ABI/ISA.  */
   set_gdbarch_short_bit (gdbarch, 16);
@@ -4920,7 +5152,20 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     const char **reg_names;
     struct mips_regnum *regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch,
                                                         struct mips_regnum);
-    if (info.osabi == GDB_OSABI_IRIX)
+    if (tdesc_has_registers (info.target_desc))
+      {
+       regnum->lo = MIPS_EMBED_LO_REGNUM;
+       regnum->hi = MIPS_EMBED_HI_REGNUM;
+       regnum->badvaddr = MIPS_EMBED_BADVADDR_REGNUM;
+       regnum->cause = MIPS_EMBED_CAUSE_REGNUM;
+       regnum->pc = MIPS_EMBED_PC_REGNUM;
+       regnum->fp0 = MIPS_EMBED_FP0_REGNUM;
+       regnum->fp_control_status = 70;
+       regnum->fp_implementation_revision = 71;
+       num_regs = MIPS_LAST_EMBED_REGNUM + 1;
+       reg_names = NULL;
+      }
+    else if (info.osabi == GDB_OSABI_IRIX)
       {
        regnum->fp0 = 32;
        regnum->pc = 64;
@@ -4950,7 +5195,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        else
          reg_names = mips_generic_reg_names;
       }
-    /* FIXME: cagney/2003-11-15: For MIPS, hasn't PC_REGNUM been
+    /* FIXME: cagney/2003-11-15: For MIPS, hasn't gdbarch_pc_regnum been
        replaced by read_pc?  */
     set_gdbarch_pc_regnum (gdbarch, regnum->pc + num_regs);
     set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
@@ -5014,8 +5259,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
       set_gdbarch_long_double_bit (gdbarch, 128);
-      set_gdbarch_long_double_format (gdbarch,
-                                      &floatformat_n32n64_long_double_big);
+      set_gdbarch_long_double_format (gdbarch, floatformats_n32n64_long);
       break;
     case MIPS_ABI_N64:
       set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call);
@@ -5027,11 +5271,62 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       set_gdbarch_ptr_bit (gdbarch, 64);
       set_gdbarch_long_long_bit (gdbarch, 64);
       set_gdbarch_long_double_bit (gdbarch, 128);
-      set_gdbarch_long_double_format (gdbarch,
-                                      &floatformat_n32n64_long_double_big);
+      set_gdbarch_long_double_format (gdbarch, floatformats_n32n64_long);
       break;
     default:
-      internal_error (__FILE__, __LINE__, "unknown ABI in switch");
+      internal_error (__FILE__, __LINE__, _("unknown ABI in switch"));
+    }
+
+  /* GCC creates a pseudo-section whose name specifies the size of
+     longs, since -mlong32 or -mlong64 may be used independent of
+     other options.  How those options affect pointer sizes is ABI and
+     architecture dependent, so use them to override the default sizes
+     set by the ABI.  This table shows the relationship between ABI,
+     -mlongXX, and size of pointers:
+
+     ABI               -mlongXX        ptr bits
+     ---               --------        --------
+     o32               32              32
+     o32               64              32
+     n32               32              32
+     n32               64              64
+     o64               32              32
+     o64               64              64
+     n64               32              32
+     n64               64              64
+     eabi32            32              32
+     eabi32            64              32
+     eabi64            32              32
+     eabi64            64              64
+
+    Note that for o32 and eabi32, pointers are always 32 bits
+    regardless of any -mlongXX option.  For all others, pointers and
+    longs are the same, as set by -mlongXX or set by defaults.
+ */
+
+  if (info.abfd != NULL)
+    {
+      int long_bit = 0;
+
+      bfd_map_over_sections (info.abfd, mips_find_long_section, &long_bit);
+      if (long_bit)
+       {
+         set_gdbarch_long_bit (gdbarch, long_bit);
+         switch (mips_abi)
+           {
+           case MIPS_ABI_O32:
+           case MIPS_ABI_EABI32:
+             break;
+           case MIPS_ABI_N32:
+           case MIPS_ABI_O64:
+           case MIPS_ABI_N64:
+           case MIPS_ABI_EABI64:
+             set_gdbarch_ptr_bit (gdbarch, long_bit);
+             break;
+           default:
+             internal_error (__FILE__, __LINE__, _("unknown ABI in switch"));
+           }
+       }
     }
 
   /* FIXME: jlarmour/2000-04-07: There *is* a flag EF_MIPS_32BIT_MODE
@@ -5057,7 +5352,6 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_read_pc (gdbarch, mips_read_pc);
   set_gdbarch_write_pc (gdbarch, mips_write_pc);
-  set_gdbarch_read_sp (gdbarch, mips_read_sp);
 
   /* Add/remove bits from an address.  The MIPS needs be careful to
      ensure that all 32 bit addresses are sign extended to 64 bits.  */
@@ -5065,6 +5359,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Unwind the frame.  */
   set_gdbarch_unwind_pc (gdbarch, mips_unwind_pc);
+  set_gdbarch_unwind_sp (gdbarch, mips_unwind_sp);
   set_gdbarch_unwind_dummy_id (gdbarch, mips_unwind_dummy_id);
 
   /* Map debug register numbers onto internal register numbers.  */
@@ -5114,29 +5409,58 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_skip_trampoline_code (gdbarch, mips_skip_trampoline_code);
 
-  /* NOTE drow/2004-02-11: We overload the core solib trampoline code
-     to support MIPS16.  This is a bad thing.  Make sure not to do it
-     if we have an OS ABI that actually supports shared libraries, since
-     shared library support is more important.  If we have an OS someday
-     that supports both shared libraries and MIPS16, we'll have to find
-     a better place for these.  */
-  if (info.osabi == GDB_OSABI_UNKNOWN)
-    {
-      set_gdbarch_in_solib_call_trampoline (gdbarch, mips_in_call_stub);
-      set_gdbarch_in_solib_return_trampoline (gdbarch, mips_in_solib_return_trampoline);
-    }
+  set_gdbarch_single_step_through_delay (gdbarch, mips_single_step_through_delay);
+
+  /* Virtual tables.  */
+  set_gdbarch_vbit_in_delta (gdbarch, 1);
+
+  mips_register_g_packet_guesses (gdbarch);
 
   /* Hook in OS ABI-specific overrides, if they have been registered.  */
+  info.tdep_info = (void *) tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
   /* Unwind the frame.  */
+  frame_unwind_append_sniffer (gdbarch, dwarf2_frame_sniffer);
   frame_unwind_append_sniffer (gdbarch, mips_stub_frame_sniffer);
   frame_unwind_append_sniffer (gdbarch, mips_insn16_frame_sniffer);
   frame_unwind_append_sniffer (gdbarch, mips_insn32_frame_sniffer);
+  frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
   frame_base_append_sniffer (gdbarch, mips_stub_frame_base_sniffer);
   frame_base_append_sniffer (gdbarch, mips_insn16_frame_base_sniffer);
   frame_base_append_sniffer (gdbarch, mips_insn32_frame_base_sniffer);
 
+  if (tdesc_data)
+    {
+      set_tdesc_pseudo_register_type (gdbarch, mips_pseudo_register_type);
+      tdesc_use_registers (gdbarch, tdesc_data);
+
+      /* Override the normal target description methods to handle our
+        dual real and pseudo registers.  */
+      set_gdbarch_register_name (gdbarch, mips_register_name);
+      set_gdbarch_register_reggroup_p (gdbarch, mips_tdesc_register_reggroup_p);
+
+      num_regs = gdbarch_num_regs (gdbarch);
+      set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
+      set_gdbarch_pc_regnum (gdbarch, tdep->regnum->pc + num_regs);
+      set_gdbarch_sp_regnum (gdbarch, MIPS_SP_REGNUM + num_regs);
+    }
+
+  /* Add ABI-specific aliases for the registers.  */
+  if (mips_abi == MIPS_ABI_N32 || mips_abi == MIPS_ABI_N64)
+    for (i = 0; i < ARRAY_SIZE (mips_n32_n64_aliases); i++)
+      user_reg_add (gdbarch, mips_n32_n64_aliases[i].name,
+                   value_of_mips_user_reg, &mips_n32_n64_aliases[i].regnum);
+  else
+    for (i = 0; i < ARRAY_SIZE (mips_o32_aliases); i++)
+      user_reg_add (gdbarch, mips_o32_aliases[i].name,
+                   value_of_mips_user_reg, &mips_o32_aliases[i].regnum);
+
+  /* Add some other standard aliases.  */
+  for (i = 0; i < ARRAY_SIZE (mips_register_aliases); i++)
+    user_reg_add (gdbarch, mips_register_aliases[i].name,
+                 value_of_mips_user_reg, &mips_register_aliases[i].regnum);
+
   return gdbarch;
 }
 
@@ -5154,11 +5478,16 @@ mips_abi_update (char *ignore_args, int from_tty, struct cmd_list_element *c)
 /* Print out which MIPS ABI is in use.  */
 
 static void
-show_mips_abi (char *ignore_args, int from_tty)
+show_mips_abi (struct ui_file *file,
+              int from_tty,
+              struct cmd_list_element *ignored_cmd,
+              const char *ignored_value)
 {
   if (gdbarch_bfd_arch_info (current_gdbarch)->arch != bfd_arch_mips)
-    printf_filtered
-      ("The MIPS ABI is unknown because the current architecture is not MIPS.\n");
+    fprintf_filtered
+      (file, 
+       "The MIPS ABI is unknown because the current architecture "
+       "is not MIPS.\n");
   else
     {
       enum mips_abi global_abi = global_mips_abi ();
@@ -5166,18 +5495,21 @@ show_mips_abi (char *ignore_args, int from_tty)
       const char *actual_abi_str = mips_abi_strings[actual_abi];
 
       if (global_abi == MIPS_ABI_UNKNOWN)
-       printf_filtered
-         ("The MIPS ABI is set automatically (currently \"%s\").\n",
+       fprintf_filtered
+         (file, 
+          "The MIPS ABI is set automatically (currently \"%s\").\n",
           actual_abi_str);
       else if (global_abi == actual_abi)
-       printf_filtered
-         ("The MIPS ABI is assumed to be \"%s\" (due to user setting).\n",
+       fprintf_filtered
+         (file,
+          "The MIPS ABI is assumed to be \"%s\" (due to user setting).\n",
           actual_abi_str);
       else
        {
          /* Probably shouldn't happen...  */
-         printf_filtered
-           ("The (auto detected) MIPS ABI \"%s\" is in use even though the user setting was \"%s\".\n",
+         fprintf_filtered
+           (file,
+            "The (auto detected) MIPS ABI \"%s\" is in use even though the user setting was \"%s\".\n",
             actual_abi_str, mips_abi_strings[global_abi]);
        }
     }
@@ -5191,7 +5523,7 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
     {
       int ef_mips_arch;
       int ef_mips_32bitmode;
-      /* determine the ISA */
+      /* Determine the ISA.  */
       switch (tdep->elf_flags & EF_MIPS_ARCH)
        {
        case E_MIPS_ARCH_1:
@@ -5210,7 +5542,7 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
          ef_mips_arch = 0;
          break;
        }
-      /* determine the size of a pointer */
+      /* Determine the size of a pointer.  */
       ef_mips_32bitmode = (tdep->elf_flags & EF_MIPS_32BITMODE);
       fprintf_unfiltered (file,
                          "mips_dump_tdep: tdep->elf_flags = 0x%x\n",
@@ -5244,140 +5576,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
                       : MIPS_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
                       : MIPS_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
                       : "???"));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: mips_stack_argsize() = %d\n",
-                     mips_stack_argsize (current_gdbarch));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: ADDR_BITS_REMOVE # %s\n",
-                     XSTRING (ADDR_BITS_REMOVE (ADDR)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: ATTACH_DETACH # %s\n",
-                     XSTRING (ATTACH_DETACH));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: DWARF_REG_TO_REGNUM # %s\n",
-                     XSTRING (DWARF_REG_TO_REGNUM (REGNUM)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: ECOFF_REG_TO_REGNUM # %s\n",
-                     XSTRING (ECOFF_REG_TO_REGNUM (REGNUM)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: FIRST_EMBED_REGNUM = %d\n",
-                     FIRST_EMBED_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: DEPRECATED_IGNORE_HELPER_CALL # %s\n",
-                     XSTRING (DEPRECATED_IGNORE_HELPER_CALL (PC)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: IN_SOLIB_CALL_TRAMPOLINE # %s\n",
-                     XSTRING (IN_SOLIB_CALL_TRAMPOLINE (PC, NAME)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: LAST_EMBED_REGNUM = %d\n",
-                     LAST_EMBED_REGNUM);
-#ifdef MACHINE_CPROC_FP_OFFSET
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MACHINE_CPROC_FP_OFFSET = %d\n",
-                     MACHINE_CPROC_FP_OFFSET);
-#endif
-#ifdef MACHINE_CPROC_PC_OFFSET
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MACHINE_CPROC_PC_OFFSET = %d\n",
-                     MACHINE_CPROC_PC_OFFSET);
-#endif
-#ifdef MACHINE_CPROC_SP_OFFSET
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MACHINE_CPROC_SP_OFFSET = %d\n",
-                     MACHINE_CPROC_SP_OFFSET);
-#endif
-  fprintf_unfiltered (file, "mips_dump_tdep: MIPS_DEFAULT_ABI = FIXME!\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MIPS_EFI_SYMBOL_NAME = multi-arch!!\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MIPS_LAST_ARG_REGNUM = %d (%d regs)\n",
-                     MIPS_LAST_ARG_REGNUM,
-                     MIPS_LAST_ARG_REGNUM - MIPS_A0_REGNUM + 1);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MIPS_NUMREGS = %d\n", MIPS_NUMREGS);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: mips_abi_regsize() = %d\n",
-                     mips_abi_regsize (current_gdbarch));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: PRID_REGNUM = %d\n", PRID_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: PROC_FRAME_ADJUST = function?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: PROC_FRAME_OFFSET = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_FRAME_REG = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_FREG_MASK = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_FREG_OFFSET = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_HIGH_ADDR = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_LOW_ADDR = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_PC_REG = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_REG_MASK = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_REG_OFFSET = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PROC_SYMBOL = function?\n");
-  fprintf_unfiltered (file, "mips_dump_tdep: PS_REGNUM = %d\n", PS_REGNUM);
-#ifdef SAVED_BYTES
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: SAVED_BYTES = %d\n", SAVED_BYTES);
-#endif
-#ifdef SAVED_FP
-  fprintf_unfiltered (file, "mips_dump_tdep: SAVED_FP = %d\n", SAVED_FP);
-#endif
-#ifdef SAVED_PC
-  fprintf_unfiltered (file, "mips_dump_tdep: SAVED_PC = %d\n", SAVED_PC);
-#endif
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: SETUP_ARBITRARY_FRAME # %s\n",
-                     XSTRING (SETUP_ARBITRARY_FRAME (NUMARGS, ARGS)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: SOFTWARE_SINGLE_STEP # %s\n",
-                     XSTRING (SOFTWARE_SINGLE_STEP (SIG, BP_P)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P () = %d\n",
-                     SOFTWARE_SINGLE_STEP_P ());
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: STAB_REG_TO_REGNUM # %s\n",
-                     XSTRING (STAB_REG_TO_REGNUM (REGNUM)));
-#ifdef STACK_END_ADDR
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: STACK_END_ADDR = %d\n",
-                     STACK_END_ADDR);
-#endif
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: STEP_SKIPS_DELAY # %s\n",
-                     XSTRING (STEP_SKIPS_DELAY (PC)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: STEP_SKIPS_DELAY_P = %d\n",
-                     STEP_SKIPS_DELAY_P);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: STOPPED_BY_WATCHPOINT # %s\n",
-                     XSTRING (STOPPED_BY_WATCHPOINT (WS)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: TABULAR_REGISTER_OUTPUT = used?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: TARGET_CAN_USE_HARDWARE_WATCHPOINT # %s\n",
-                     XSTRING (TARGET_CAN_USE_HARDWARE_WATCHPOINT
-                              (TYPE, CNT, OTHERTYPE)));
-#ifdef TRACE_CLEAR
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: TRACE_CLEAR # %s\n",
-                     XSTRING (TRACE_CLEAR (THREAD, STATE)));
-#endif
-#ifdef TRACE_FLAVOR
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: TRACE_FLAVOR = %d\n", TRACE_FLAVOR);
-#endif
-#ifdef TRACE_FLAVOR_SIZE
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: TRACE_FLAVOR_SIZE = %d\n",
-                     TRACE_FLAVOR_SIZE);
-#endif
-#ifdef TRACE_SET
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: TRACE_SET # %s\n",
-                     XSTRING (TRACE_SET (X, STATE)));
-#endif
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: VM_MIN_ADDRESS = %ld\n",
-                     (long) VM_MIN_ADDRESS);
 }
 
 extern initialize_file_ftype _initialize_mips_tdep;    /* -Wmissing-prototypes */
@@ -5391,7 +5589,7 @@ _initialize_mips_tdep (void)
   mips_abi_string = mips_abi_strings[MIPS_ABI_UNKNOWN];
   if (MIPS_ABI_LAST + 1
       != sizeof (mips_abi_strings) / sizeof (mips_abi_strings[0]))
-    internal_error (__FILE__, __LINE__, "mips_abi_strings out of sync");
+    internal_error (__FILE__, __LINE__, _("mips_abi_strings out of sync"));
 
   gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep);
 
@@ -5399,122 +5597,104 @@ _initialize_mips_tdep (void)
 
   /* Add root prefix command for all "set mips"/"show mips" commands */
   add_prefix_cmd ("mips", no_class, set_mips_command,
-                 "Various MIPS specific commands.",
+                 _("Various MIPS specific commands."),
                  &setmipscmdlist, "set mips ", 0, &setlist);
 
   add_prefix_cmd ("mips", no_class, show_mips_command,
-                 "Various MIPS specific commands.",
+                 _("Various MIPS specific commands."),
                  &showmipscmdlist, "show mips ", 0, &showlist);
 
-  /* Allow the user to override the saved register size. */
-  add_setshow_enum_cmd ("saved-gpreg-size", class_obscure,
-                       size_enums, &mips_abi_regsize_string, "\
-Set size of general purpose registers saved on the stack.\n", "\
-Show size of general purpose registers saved on the stack.\n", "\
-This option can be set to one of:\n\
-  32    - Force GDB to treat saved GP registers as 32-bit\n\
-  64    - Force GDB to treat saved GP registers as 64-bit\n\
-  auto  - Allow GDB to use the target's default setting or autodetect the\n\
-          saved GP register size from information contained in the executable.\n\
-          (default: auto)", "\
-Size of general purpose registers saved on the stack is %s.\n",
-                       NULL, NULL, &setmipscmdlist, &showmipscmdlist);
-
-  /* Allow the user to override the argument stack size. */
-  add_setshow_enum_cmd ("stack-arg-size", class_obscure,
-                      size_enums, &mips_stack_argsize_string, "\
-Set the amount of stack space reserved for each argument.\n", "\
-Show the amount of stack space reserved for each argument.\n", "\
-This option can be set to one of:\n\
-  32    - Force GDB to allocate 32-bit chunks per argument\n\
-  64    - Force GDB to allocate 64-bit chunks per argument\n\
-  auto  - Allow GDB to determine the correct setting from the current\n\
-          target and executable (default)", "\
-The amount of stack space reserved for each argument is %s.\n",
-                       NULL, NULL, &setmipscmdlist, &showmipscmdlist);
-
   /* Allow the user to override the ABI. */
-  c = add_set_enum_cmd
-    ("abi", class_obscure, mips_abi_strings, &mips_abi_string,
-     "Set the ABI used by this program.\n"
-     "This option can be set to one of:\n"
-     "  auto  - the default ABI associated with the current binary\n"
-     "  o32\n"
-     "  o64\n" "  n32\n" "  n64\n" "  eabi32\n" "  eabi64", &setmipscmdlist);
-  set_cmd_sfunc (c, mips_abi_update);
-  add_cmd ("abi", class_obscure, show_mips_abi,
-          "Show ABI in use by MIPS target", &showmipscmdlist);
+  add_setshow_enum_cmd ("abi", class_obscure, mips_abi_strings,
+                       &mips_abi_string, _("\
+Set the MIPS ABI used by this program."), _("\
+Show the MIPS ABI used by this program."), _("\
+This option can be set to one of:\n\
+  auto  - the default ABI associated with the current binary\n\
+  o32\n\
+  o64\n\
+  n32\n\
+  n64\n\
+  eabi32\n\
+  eabi64"),
+                       mips_abi_update,
+                       show_mips_abi,
+                       &setmipscmdlist, &showmipscmdlist);
 
   /* Let the user turn off floating point and set the fence post for
      heuristic_proc_start.  */
 
   add_prefix_cmd ("mipsfpu", class_support, set_mipsfpu_command,
-                 "Set use of MIPS floating-point coprocessor.",
+                 _("Set use of MIPS floating-point coprocessor."),
                  &mipsfpulist, "set mipsfpu ", 0, &setlist);
   add_cmd ("single", class_support, set_mipsfpu_single_command,
-          "Select single-precision MIPS floating-point coprocessor.",
+          _("Select single-precision MIPS floating-point coprocessor."),
           &mipsfpulist);
   add_cmd ("double", class_support, set_mipsfpu_double_command,
-          "Select double-precision MIPS floating-point coprocessor.",
+          _("Select double-precision MIPS floating-point coprocessor."),
           &mipsfpulist);
   add_alias_cmd ("on", "double", class_support, 1, &mipsfpulist);
   add_alias_cmd ("yes", "double", class_support, 1, &mipsfpulist);
   add_alias_cmd ("1", "double", class_support, 1, &mipsfpulist);
   add_cmd ("none", class_support, set_mipsfpu_none_command,
-          "Select no MIPS floating-point coprocessor.", &mipsfpulist);
+          _("Select no MIPS floating-point coprocessor."), &mipsfpulist);
   add_alias_cmd ("off", "none", class_support, 1, &mipsfpulist);
   add_alias_cmd ("no", "none", class_support, 1, &mipsfpulist);
   add_alias_cmd ("0", "none", class_support, 1, &mipsfpulist);
   add_cmd ("auto", class_support, set_mipsfpu_auto_command,
-          "Select MIPS floating-point coprocessor automatically.",
+          _("Select MIPS floating-point coprocessor automatically."),
           &mipsfpulist);
   add_cmd ("mipsfpu", class_support, show_mipsfpu_command,
-          "Show current use of MIPS floating-point coprocessor target.",
+          _("Show current use of MIPS floating-point coprocessor target."),
           &showlist);
 
   /* We really would like to have both "0" and "unlimited" work, but
      command.c doesn't deal with that.  So make it a var_zinteger
      because the user can always use "999999" or some such for unlimited.  */
   add_setshow_zinteger_cmd ("heuristic-fence-post", class_support,
-                           &heuristic_fence_post, "\
-Set the distance searched for the start of a function.\n", "\
-Show the distance searched for the start of a function.\n", "\
+                           &heuristic_fence_post, _("\
+Set the distance searched for the start of a function."), _("\
+Show the distance searched for the start of a function."), _("\
 If you are debugging a stripped executable, GDB needs to search through the\n\
 program for the start of a function.  This command sets the distance of the\n\
-search.  The only need to set it is when debugging a stripped executable.", "\
-The distance searched for the start of a function is %s.\n",
-                           reinit_frame_cache_sfunc, NULL,
+search.  The only need to set it is when debugging a stripped executable."),
+                           reinit_frame_cache_sfunc,
+                           NULL, /* FIXME: i18n: The distance searched for the start of a function is %s.  */
                            &setlist, &showlist);
 
   /* Allow the user to control whether the upper bits of 64-bit
      addresses should be zeroed.  */
-  add_setshow_auto_boolean_cmd ("mask-address", no_class, &mask_address_var, "\
-Set zeroing of upper 32 bits of 64-bit addresses.", "\
-Show zeroing of upper 32 bits of 64-bit addresses.", "\
+  add_setshow_auto_boolean_cmd ("mask-address", no_class,
+                               &mask_address_var, _("\
+Set zeroing of upper 32 bits of 64-bit addresses."), _("\
+Show zeroing of upper 32 bits of 64-bit addresses."), _("\
 Use \"on\" to enable the masking, \"off\" to disable it and \"auto\" to \n\
-allow GDB to determine the correct value.\n", "\
-Zerroing of upper 32 bits of 64-bit address is %s.",
-                               NULL, show_mask_address, &setmipscmdlist, &showmipscmdlist);
+allow GDB to determine the correct value."),
+                               NULL, show_mask_address,
+                               &setmipscmdlist, &showmipscmdlist);
 
   /* Allow the user to control the size of 32 bit registers within the
      raw remote packet.  */
   add_setshow_boolean_cmd ("remote-mips64-transfers-32bit-regs", class_obscure,
-                          &mips64_transfers_32bit_regs_p, "\
-Set compatibility with 64-bit MIPS target that transfers 32-bit quantities.", "\
-Show compatibility with 64-bit MIPS target that transfers 32-bit quantities.", "\
+                          &mips64_transfers_32bit_regs_p, _("\
+Set compatibility with 64-bit MIPS target that transfers 32-bit quantities."),
+                          _("\
+Show compatibility with 64-bit MIPS target that transfers 32-bit quantities."),
+                          _("\
 Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
 that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
-64 bits for others.  Use \"off\" to disable compatibility mode", "\
-Compatibility with 64-bit MIPS target that transfers 32-bit quantities is %s.",
- set_mips64_transfers_32bit_regs, NULL, &setlist, &showlist);
+64 bits for others.  Use \"off\" to disable compatibility mode"),
+                          set_mips64_transfers_32bit_regs,
+                          NULL, /* FIXME: i18n: Compatibility with 64-bit MIPS target that transfers 32-bit quantities is %s.  */
+                          &setlist, &showlist);
 
   /* Debug this files internals. */
   add_setshow_zinteger_cmd ("mips", class_maintenance,
-                           &mips_debug, "\
-Set mips debugging.\n", "\
-Show mips debugging.\n", "\
-When non-zero, mips specific debugging is enabled.\n", "\
-Mips debugging is currently %s.\n",
-                           NULL, NULL,
+                           &mips_debug, _("\
+Set mips debugging."), _("\
+Show mips debugging."), _("\
+When non-zero, mips specific debugging is enabled."),
+                           NULL,
+                           NULL, /* FIXME: i18n: Mips debugging is currently %s.  */
                            &setdebuglist, &showdebuglist);
 }
This page took 0.10669 seconds and 4 git commands to generate.