2007-06-13 Markus Deuling <deuling@de.ibm.com>
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index c109ed28821c9a81da96d691d837ed0e10325e71..c1c7e72b40059c8896a177772b2ef48fddc227a3 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, 2005 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"
@@ -55,6 +55,9 @@
 #include "trad-frame.h"
 #include "infcall.h"
 #include "floatformat.h"
+#include "remote.h"
+#include "target-descriptions.h"
+#include "dwarf2-frame.h"
 
 static const struct objfile_data *mips_pdr_data;
 
@@ -72,6 +75,11 @@ enum
   MIPS_FPU_DOUBLE_REGSIZE = 8
 };
 
+enum
+{
+  MIPS32_REGSIZE = 4,
+  MIPS64_REGSIZE = 8
+};
 
 static const char *mips_abi_string;
 
@@ -86,21 +94,6 @@ static const char *mips_abi_strings[] = {
   NULL
 };
 
-/* Various MIPS ISA options (related to stack analysis) can be
-   overridden dynamically.  Establish an enum/array for managing
-   them. */
-
-static const char size_auto[] = "auto";
-static const char size_32[] = "32";
-static const char size_64[] = "64";
-
-static const char *size_enums[] = {
-  size_auto,
-  size_32,
-  size_64,
-  0
-};
-
 /* Some MIPS boards don't support floating point while others only
    support single-precision floating-point operations.  */
 
@@ -119,6 +112,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
 {
@@ -141,11 +139,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;
 }
@@ -165,10 +170,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)
 {
@@ -202,7 +213,7 @@ is_mips16_addr (CORE_ADDR addr)
 static CORE_ADDR
 unmake_mips16_addr (CORE_ADDR addr)
 {
-  return ((addr) & ~1);
+  return ((addr) & ~(CORE_ADDR) 1);
 }
 
 /* Return the contents of register REGNUM as a signed integer.  */
@@ -245,44 +256,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
 
@@ -312,11 +323,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)
@@ -387,23 +398,6 @@ mips2_fp_compat (void)
   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);
@@ -422,7 +416,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) };
@@ -499,10 +493,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
@@ -515,7 +509,7 @@ mips_register_name (int regno)
       else
        return mips_gpr_names[rawnum];
     }
-  else if (32 <= rawnum && rawnum < NUM_REGS)
+  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];
@@ -534,16 +528,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;
@@ -563,22 +558,23 @@ mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
 }
 
 /* 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);
@@ -590,17 +586,18 @@ mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
 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);
@@ -645,27 +642,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
@@ -674,30 +673,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.  */
@@ -710,9 +699,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 + MIPS_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;
@@ -731,13 +721,6 @@ mips_register_type (struct gdbarch *gdbarch, int regnum)
     }
 }
 
-/* TARGET_READ_SP -- Remove useless bits from the stack pointer.  */
-
-static CORE_ADDR
-mips_read_sp (void)
-{
-  return read_signed_register (MIPS_SP_REGNUM);
-}
 
 /* Should the upper word of 64-bit addresses be zeroed? */
 enum auto_boolean mask_address_var = AUTO_BOOLEAN_AUTO;
@@ -820,7 +803,16 @@ 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
@@ -831,8 +823,11 @@ 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
@@ -847,7 +842,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;
 
@@ -858,7 +853,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);
@@ -887,8 +882,8 @@ mips32_relative_offset (ULONGEST inst)
   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)
 {
@@ -989,14 +984,14 @@ 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 */
@@ -1108,7 +1103,7 @@ extended_offset (unsigned int extension)
 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);
@@ -1202,7 +1197,7 @@ 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
@@ -1337,7 +1332,7 @@ mips16_next_pc (CORE_ADDR pc)
    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
+static CORE_ADDR
 mips_next_pc (CORE_ADDR pc)
 {
   if (pc & 0x01)
@@ -1357,11 +1352,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,
@@ -1370,8 +1365,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;
     }
 }
 
@@ -1438,7 +1437,8 @@ 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 = read_next_frame_reg (next_frame, gdbarch_num_regs (current_gdbarch)
+                                          + MIPS_SP_REGNUM);
   else
     sp = 0;
 
@@ -1590,13 +1590,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
@@ -1625,7 +1629,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);
@@ -1640,7 +1645,8 @@ mips_insn16_frame_cache (struct frame_info *next_frame, void **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);
+  trad_frame_set_value (cache->saved_regs, gdbarch_num_regs (current_gdbarch)
+                                          + MIPS_SP_REGNUM, cache->base);
 
   return (*this_cache);
 }
@@ -1651,7 +1657,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
@@ -1659,7 +1666,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);
@@ -1719,7 +1726,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++)
@@ -1751,7 +1758,8 @@ 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 = read_next_frame_reg (next_frame, gdbarch_num_regs (current_gdbarch)
+                                         + MIPS_SP_REGNUM);
   else
     sp = 0;
 
@@ -1806,7 +1814,9 @@ restart:
              unsigned alloca_adjust;
 
              frame_reg = 30;
-             frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
+             frame_addr = read_next_frame_reg (next_frame,
+                                               gdbarch_num_regs
+                                                 (current_gdbarch) + 30);
              alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
              if (alloca_adjust > 0)
                {
@@ -1834,7 +1844,9 @@ restart:
              unsigned alloca_adjust;
 
              frame_reg = 30;
-             frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
+             frame_addr = read_next_frame_reg (next_frame,
+                                               gdbarch_num_regs 
+                                                 (current_gdbarch) + 30);
              alloca_adjust = (unsigned) (frame_addr - sp);
              if (alloca_adjust > 0)
                {
@@ -1899,13 +1911,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
@@ -1945,7 +1961,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);
@@ -1960,7 +1977,9 @@ mips_insn32_frame_cache (struct frame_info *next_frame, void **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);
+  trad_frame_set_value (cache->saved_regs,
+                       gdbarch_num_regs (current_gdbarch) + MIPS_SP_REGNUM,
+                       cache->base);
 
   return (*this_cache);
 }
@@ -1971,7 +1990,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
@@ -1979,7 +1999,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);
@@ -2073,7 +2093,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);
@@ -2091,11 +2111,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
@@ -2128,7 +2158,7 @@ static CORE_ADDR
 read_next_frame_reg (struct frame_info *fi, int regno)
 {
   /* Always a pseudo.  */
-  gdb_assert (regno >= NUM_REGS);
+  gdb_assert (regno >= gdbarch_num_regs (current_gdbarch));
   if (fi == NULL)
     {
       LONGEST val;
@@ -2170,28 +2200,18 @@ 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 regcache *regcache)
 {
-  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 = read_register (mips_regnum (current_gdbarch)->pc);
+  next_pc = mips_next_pc (pc);
 
-      target_insert_breakpoint (next_pc, break_mem);
-    }
-  else
-    target_remove_breakpoint (next_pc, break_mem);
+  insert_single_step_breakpoint (next_pc);
+  return 1;
 }
 
 /* Test whether the PC points to the return instruction at the
@@ -2225,7 +2245,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)
@@ -2316,7 +2336,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. */
 
@@ -2328,7 +2348,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);
 }
 
@@ -2382,6 +2403,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.  */
@@ -2404,8 +2426,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)
@@ -2432,8 +2453,8 @@ 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));
       int len = TYPE_LENGTH (arg_type);
@@ -2446,27 +2467,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++;
@@ -2487,9 +2506,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).  */
@@ -2524,13 +2549,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.  */
@@ -2538,8 +2562,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",
@@ -2555,18 +2578,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)
@@ -2607,8 +2629,7 @@ 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)));
+                                     phex (regval, regsize));
                  write_register (argreg, regval);
                  argreg++;
                }
@@ -2623,8 +2644,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)
@@ -2637,12 +2657,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;
@@ -2687,8 +2707,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)
@@ -2715,7 +2734,7 @@ 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));
       int len = TYPE_LENGTH (arg_type);
@@ -2726,7 +2745,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)
@@ -2752,21 +2771,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",
@@ -2782,13 +2799,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)
@@ -2833,34 +2850,19 @@ 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.
-
-                    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.  */
+                    same for integral types.  */
 
-                 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)));
+                                     phex (regval, MIPS64_REGSIZE));
                  write_register (argreg, regval);
                  argreg++;
                }
@@ -2875,8 +2877,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)
@@ -2892,14 +2893,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)
     {
@@ -2908,9 +2931,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
@@ -2939,9 +2964,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;
     }
@@ -2963,7 +2990,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;
@@ -2984,8 +3012,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;
     }
@@ -3026,8 +3056,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)
@@ -3047,7 +3085,7 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                            "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);
+      stack_offset += MIPS32_REGSIZE;
     }
 
   /* Now load as many as possible of the first arguments into
@@ -3055,7 +3093,7 @@ 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));
       int len = TYPE_LENGTH (arg_type);
@@ -3066,15 +3104,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++;
@@ -3093,9 +3130,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).  */
@@ -3140,39 +3178,38 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
                                    argreg, phex (regval, len));
              write_register (argreg, regval);
-             argreg += (mips_abi_regsize (gdbarch) == 8) ? 1 : 2;
+             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",
@@ -3180,22 +3217,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)
                    {
@@ -3222,12 +3250,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
@@ -3246,9 +3272,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
@@ -3258,19 +3284,17 @@ 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)));
+                                     phex (regval, MIPS32_REGSIZE));
                  write_register (argreg, regval);
                  argreg++;
 
@@ -3290,8 +3314,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)
@@ -3307,7 +3330,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);
 
@@ -3323,9 +3346,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
@@ -3336,23 +3361,31 @@ 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"));
@@ -3376,7 +3409,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;
@@ -3387,9 +3420,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;
     }
@@ -3413,7 +3448,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;
@@ -3423,21 +3459,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;
     }
@@ -3480,8 +3518,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)
@@ -3501,7 +3544,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                            "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);
+      stack_offset += MIPS64_REGSIZE;
     }
 
   /* Now load as many as possible of the first arguments into
@@ -3509,7 +3552,7 @@ 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));
       int len = TYPE_LENGTH (arg_type);
@@ -3520,19 +3563,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
@@ -3547,86 +3578,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));
+         write_register (float_argreg++, regval);
+         if (mips_debug)
+           fprintf_unfiltered (gdb_stdlog, " - reg=%d val=%s",
+                               argreg, phex (regval, len));
+         write_register (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",
@@ -3634,21 +3614,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)
@@ -3676,12 +3655,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
@@ -3694,37 +3671,19 @@ 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.
-
-                    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.  */
+                    same for integral types. */
 
-                 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)));
+                                     phex (regval, MIPS64_REGSIZE));
                  write_register (argreg, regval);
                  argreg++;
 
@@ -3744,8 +3703,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)
@@ -3761,9 +3719,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.
@@ -3799,19 +3799,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
@@ -3819,20 +3813,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;
@@ -3851,7 +3846,7 @@ 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);
 
@@ -3860,7 +3855,8 @@ mips_read_fp_register_double (struct frame_info *frame, int regno,
       /* 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
     {
@@ -3871,7 +3867,7 @@ mips_read_fp_register_double (struct frame_info *frame, int regno,
 
       /* 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);
@@ -3888,17 +3884,18 @@ 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 ())
@@ -3959,13 +3956,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;
@@ -3974,11 +3971,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
@@ -3989,7 +3987,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);
@@ -3997,7 +3995,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);
 }
 
@@ -4023,60 +4021,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++;
     }
@@ -4094,20 +4119,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')
+      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 */
@@ -4142,12 +4168,15 @@ mips_single_step_through_delay (struct gdbarch *gdbarch,
                                struct frame_info *frame)
 {
   CORE_ADDR pc = get_frame_pc (frame);
-  char buf[MIPS_INSN32_SIZE];
+  gdb_byte buf[MIPS_INSN32_SIZE];
 
   /* There is no branch delay slot on MIPS16.  */
   if (mips_pc_is_mips16 (pc))
     return 0;
 
+  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.  */
@@ -4362,27 +4391,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;
@@ -4392,9 +4421,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);
 
@@ -4412,16 +4441,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);
 
@@ -4534,7 +4563,7 @@ mips_skip_trampoline_code (CORE_ADDR pc)
 }
 
 /* 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)
@@ -4551,13 +4580,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)
@@ -4574,39 +4604,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 gdbarch *gdbarch,
-                        struct type *type, const bfd_byte *buf)
+                        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
@@ -4637,6 +4667,20 @@ mips_find_abi_section (bfd *abfd, asection *sect, void *obj)
     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
 global_mips_abi (void)
 {
@@ -4649,6 +4693,37 @@ global_mips_abi (void)
   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 gdbarch *
 mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
@@ -4730,6 +4805,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);
@@ -4786,6 +4868,16 @@ 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)
+    return NULL;
+
   /* try to find a pre-existing architecture */
   for (arches = gdbarch_list_lookup_by_info (arches, &info);
        arches != NULL;
@@ -4816,6 +4908,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);
@@ -4929,8 +5038,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);
@@ -4942,13 +5050,64 @@ 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"));
     }
 
+  /* 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
      that could indicate -gp32 BUT gas/config/tc-mips.c contains the
      comment:
@@ -4972,7 +5131,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.  */
@@ -4980,6 +5138,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.  */
@@ -5031,13 +5190,20 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   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.  */
   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);
@@ -5059,11 +5225,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 ();
@@ -5071,18 +5242,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]);
        }
     }
@@ -5096,7 +5270,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:
@@ -5115,7 +5289,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",
@@ -5149,9 +5323,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));
 }
 
 extern initialize_file_ftype _initialize_mips_tdep;    /* -Wmissing-prototypes */
@@ -5180,35 +5351,6 @@ _initialize_mips_tdep (void)
                  _("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."), _("\
-Show size of general purpose registers saved on the stack."), _("\
-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\n\
-          executable (default)."),
-                       NULL,
-                       NULL, /* FIXME: i18n: Size of general purpose registers saved on the stack is %s.  */
-                       &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."), _("\
-Show the amount of stack space reserved for each argument."), _("\
-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)"),
-                       NULL,
-                       NULL, /* FIXME: i18n: The amount of stack space reserved for each argument is %s.  */
-                       &setmipscmdlist, &showmipscmdlist);
-
   /* Allow the user to override the ABI. */
   add_setshow_enum_cmd ("abi", class_obscure, mips_abi_strings,
                        &mips_abi_string, _("\
This page took 0.087346 seconds and 4 git commands to generate.