Fia x comment typo.
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index bc364ebad50849d79b1b5f85b9cff372a57025c2..2c3e8c27090121babba96eef0b454faf3420dcdc 100644 (file)
 #include "osabi.h"
 #include "mips-tdep.h"
 #include "block.h"
-
+#include "reggroups.h"
 #include "opcode/mips.h"
 #include "elf/mips.h"
 #include "elf-bfd.h"
 #include "symcat.h"
+#include "sim-regno.h"
+#include "dis-asm.h"
+
+static void set_reg_offset (CORE_ADDR *saved_regs, int regnum, CORE_ADDR off);
+static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum);
 
 /* A useful bit in the CP0 status register (PS_REGNUM).  */
 /* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip.  */
@@ -129,10 +134,30 @@ struct gdbarch_tdep
     int mips_default_saved_regsize;
     int mips_fp_register_double;
     int mips_default_stack_argsize;
-    int gdb_target_is_mips64;
     int default_mask_address_p;
+    /* Is the target using 64-bit raw integer registers but only
+       storing a left-aligned 32-bit value in each?  */
+    int mips64_transfers_32bit_regs_p;
+    /* Indexes for various registers.  IRIX and embedded have
+       different values.  This contains the "public" fields.  Don't
+       add any that do not need to be public.  */
+    const struct mips_regnum *regnum;
+    /* Register names table for the current register set.  */
+    const char **mips_processor_reg_names;
   };
 
+const struct mips_regnum *
+mips_regnum (struct gdbarch *gdbarch)
+{
+  return gdbarch_tdep (gdbarch)->regnum;
+}
+
+static int
+mips_fpa0_regnum (struct gdbarch *gdbarch)
+{
+  return mips_regnum (gdbarch)->fp0 + 12;
+}
+
 #define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
                   || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64)
 
@@ -150,14 +175,35 @@ static const char *mips_saved_regsize_string = size_auto;
 
 #define MIPS_SAVED_REGSIZE (mips_saved_regsize())
 
+/* MIPS16 function addresses are odd (bit 0 is set).  Here are some
+   functions to test, set, or clear bit 0 of addresses.  */
+
+static CORE_ADDR
+is_mips16_addr (CORE_ADDR addr)
+{
+  return ((addr) & 1);
+}
+
+static CORE_ADDR
+make_mips16_addr (CORE_ADDR addr)
+{
+  return ((addr) | 1);
+}
+
+static CORE_ADDR
+unmake_mips16_addr (CORE_ADDR addr)
+{
+  return ((addr) & ~1);
+}
+
 /* Return the contents of register REGNUM as a signed integer.  */
 
 static LONGEST
 read_signed_register (int regnum)
 {
-  void *buf = alloca (REGISTER_RAW_SIZE (regnum));
+  void *buf = alloca (register_size (current_gdbarch, regnum));
   deprecated_read_register_gen (regnum, buf);
-  return (extract_signed_integer (buf, REGISTER_RAW_SIZE (regnum)));
+  return (extract_signed_integer (buf, register_size (current_gdbarch, regnum)));
 }
 
 static LONGEST
@@ -187,6 +233,13 @@ mips_abi (struct gdbarch *gdbarch)
   return gdbarch_tdep (gdbarch)->mips_abi;
 }
 
+int
+mips_regsize (struct gdbarch *gdbarch)
+{
+  return (gdbarch_bfd_arch_info (gdbarch)->bits_per_word
+         / gdbarch_bfd_arch_info (gdbarch)->bits_per_byte);
+}
+
 static unsigned int
 mips_saved_regsize (void)
 {
@@ -200,17 +253,13 @@ mips_saved_regsize (void)
 
 /* 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. This field is already
-   being used to store the symbol size, so the assumption is
-   that the symbol size cannot exceed 2^31.
+   "info" field is used for this purpose.
 
    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
 
-   MSYMBOL_IS_SPECIAL   tests the "special" bit in a minimal symbol
-   MSYMBOL_SIZE         returns the size of the minimal symbol, i.e.
-   the "info" field with the "special" bit masked out */
+   MSYMBOL_IS_SPECIAL   tests the "special" bit in a minimal symbol  */
 
 static void
 mips_elf_make_msymbol_special (asymbol *sym, struct minimal_symbol *msym)
@@ -229,12 +278,6 @@ msymbol_is_special (struct minimal_symbol *msym)
   return (((long) MSYMBOL_INFO (msym) & 0x80000000) != 0);
 }
 
-static long
-msymbol_size (struct minimal_symbol *msym)
-{
-  return ((long) MSYMBOL_INFO (msym) & 0x7fffffff);
-}
-
 /* XFER a value from the big/little/left end of the register.
    Depending on the size of the value it might occupy the entire
    register or just part of it.  Make an allowance for this, aligning
@@ -247,12 +290,13 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length,
 {
   bfd_byte reg[MAX_REGISTER_SIZE];
   int reg_offset = 0;
+  gdb_assert (reg_num >= NUM_REGS);
   /* Need to transfer the left or right part of the register, based on
      the targets byte order.  */
   switch (endian)
     {
     case BFD_ENDIAN_BIG:
-      reg_offset = REGISTER_RAW_SIZE (reg_num) - length;
+      reg_offset = register_size (current_gdbarch, reg_num) - length;
       break;
     case BFD_ENDIAN_LITTLE:
       reg_offset = 0;
@@ -275,9 +319,9 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length,
        fprintf_unfiltered (gdb_stdlog, "%02x", out[buf_offset + i]);
     }
   if (in != NULL)
-    regcache_raw_read_part (regcache, reg_num, reg_offset, length, in + buf_offset);
+    regcache_cooked_read_part (regcache, reg_num, reg_offset, length, in + buf_offset);
   if (out != NULL)
-    regcache_raw_write_part (regcache, reg_num, reg_offset, length, out + buf_offset);
+    regcache_cooked_write_part (regcache, reg_num, reg_offset, length, out + buf_offset);
   if (mips_debug && in != NULL)
     {
       int i;
@@ -298,7 +342,7 @@ mips2_fp_compat (void)
 {
   /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
      meaningful.  */
-  if (REGISTER_RAW_SIZE (FP0_REGNUM) == 4)
+  if (register_size (current_gdbarch, mips_regnum (current_gdbarch)->fp0) == 4)
     return 0;
 
 #if 0
@@ -316,9 +360,7 @@ mips2_fp_compat (void)
 
 /* Indicate that the ABI makes use of double-precision registers
    provided by the FPU (rather than combining pairs of registers to
-   form double-precision values).  Do not use "TARGET_IS_MIPS64" to
-   determine if the ABI is using double-precision registers.  See also
-   MIPS_FPU_TYPE. */
+   form double-precision values).  See also MIPS_FPU_TYPE.  */
 #define FP_REGISTER_DOUBLE (gdbarch_tdep (current_gdbarch)->mips_fp_register_double)
 
 /* The amount of space reserved on the stack for registers. This is
@@ -342,14 +384,10 @@ mips_stack_argsize (void)
     return 4;
 }
 
-#define GDB_TARGET_IS_MIPS64 (gdbarch_tdep (current_gdbarch)->gdb_target_is_mips64 + 0)
-
 #define MIPS_DEFAULT_MASK_ADDRESS_P (gdbarch_tdep (current_gdbarch)->default_mask_address_p)
 
 #define VM_MIN_ADDRESS (CORE_ADDR)0x400000
 
-int gdb_print_insn_mips (bfd_vma, disassemble_info *);
-
 static mips_extra_func_info_t heuristic_proc_desc (CORE_ADDR, CORE_ADDR,
                                                   struct frame_info *, int);
 
@@ -357,10 +395,6 @@ static CORE_ADDR heuristic_proc_start (CORE_ADDR);
 
 static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
 
-static int mips_set_processor_type (char *);
-
-static void mips_show_processor_type_command (char *, int);
-
 static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
 
 static mips_extra_func_info_t find_proc_desc (CORE_ADDR pc,
@@ -373,32 +407,71 @@ static CORE_ADDR after_prologue (CORE_ADDR pc,
 static struct type *mips_float_register_type (void);
 static struct type *mips_double_register_type (void);
 
-/* This value is the model of MIPS in use.  It is derived from the value
-   of the PrID register.  */
-
-char *mips_processor_type;
-
-char *tmp_mips_processor_type;
-
 /* The list of available "set mips " and "show mips " commands */
 
 static struct cmd_list_element *setmipscmdlist = NULL;
 static struct cmd_list_element *showmipscmdlist = NULL;
 
-/* A set of original names, to be used when restoring back to generic
-   registers from a specific set.  */
-static char *mips_generic_reg_names[] = MIPS_REGISTER_NAMES;
-
 /* Integer registers 0 thru 31 are handled explicitly by
    mips_register_name().  Processor specific registers 32 and above
-   are listed in the sets of register names assigned to
-   mips_processor_reg_names.  */
-static char **mips_processor_reg_names = mips_generic_reg_names;
+   are listed in the followign tables.  */
+
+enum { NUM_MIPS_PROCESSOR_REGS = (90 - 32) };
+
+/* Generic MIPS.  */
+
+static const char *mips_generic_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
+  "sr",        "lo",   "hi",   "bad",  "cause","pc",
+  "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
+  "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
+  "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",
+  "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",
+  "fsr",  "fir",  ""/*"fp"*/,  "",
+  "",  "",     "",     "",     "",     "",     "",     "",
+  "",  "",     "",     "",     "",     "",     "",     "",
+};
+
+/* Names of IDT R3041 registers.  */
+
+static const char *mips_r3041_reg_names[] = {
+  "sr",        "lo",   "hi",   "bad",  "cause","pc",
+  "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
+  "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
+  "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",
+  "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",
+  "fsr",  "fir",  "",/*"fp"*/  "",
+  "",  "",     "bus",  "ccfg", "",     "",     "",     "",
+  "",  "",     "port", "cmp",  "",     "",     "epc",  "prid",
+};
+
+/* Names of tx39 registers.  */
+
+static const char *mips_tx39_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
+  "sr",        "lo",   "hi",   "bad",  "cause","pc",
+  "",   "",    "",     "",     "",     "",     "",     "",
+  "",   "",    "",     "",     "",     "",     "",     "",
+  "",          "",     "",     "",     "",     "",     "",     "",
+  "",          "",     "",     "",     "",     "",     "",     "",
+  "",          "",     "",     "",
+  "",  "",     "",     "",     "",     "",     "",     "",
+  "",  "", "config", "cache", "debug", "depc", "epc",  ""
+};
+
+/* Names of IRIX registers.  */
+static const char *mips_irix_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
+  "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
+  "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
+  "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",
+  "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",
+  "pc",        "cause", "bad", "hi",   "lo",   "fsr",  "fir"
+};
+
 
 /* Return the name of the register corresponding to REGNO.  */
 static const char *
 mips_register_name (int regno)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   /* GPR names for all ABIs other than n32/n64.  */
   static char *mips_gpr_names[] = {
     "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
@@ -417,92 +490,113 @@ 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)
+    return "";
+
   /* The MIPS integer registers are always mapped from 0 to 31.  The
      names of the registers (which reflects the conventions regarding
      register use) vary depending on the ABI.  */
-  if (0 <= regno && regno < 32)
+  if (0 <= rawnum && rawnum < 32)
     {
       if (abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64)
-       return mips_n32_n64_gpr_names[regno];
+       return mips_n32_n64_gpr_names[rawnum];
       else
-       return mips_gpr_names[regno];
+       return mips_gpr_names[rawnum];
+    }
+  else if (32 <= rawnum && rawnum < NUM_REGS)
+    {
+      gdb_assert (rawnum - 32 < NUM_MIPS_PROCESSOR_REGS);
+      return tdep->mips_processor_reg_names[rawnum - 32];
     }
-  else if (32 <= regno && regno < NUM_REGS)
-    return mips_processor_reg_names[regno - 32];
   else
     internal_error (__FILE__, __LINE__,
-                   "mips_register_name: bad register number %d", regno);
+                   "mips_register_name: bad register number %d", rawnum);
 }
 
-/* *INDENT-OFF* */
-/* Names of IDT R3041 registers.  */
-
-char *mips_r3041_reg_names[] = {
-       "sr",   "lo",   "hi",   "bad",  "cause","pc",
-       "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
-       "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
-       "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",
-       "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",
-       "fsr",  "fir",  "",/*"fp"*/     "",
-       "",     "",     "bus",  "ccfg", "",     "",     "",     "",
-       "",     "",     "port", "cmp",  "",     "",     "epc",  "prid",
-};
-
-/* Names of IDT R3051 registers.  */
-
-char *mips_r3051_reg_names[] = {
-       "sr",   "lo",   "hi",   "bad",  "cause","pc",
-       "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
-       "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
-       "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",
-       "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",
-       "fsr",  "fir",  ""/*"fp"*/,     "",
-       "inx",  "rand", "elo",  "",     "ctxt", "",     "",     "",
-       "",     "",     "ehi",  "",     "",     "",     "epc",  "prid",
-};
-
-/* Names of IDT R3081 registers.  */
-
-char *mips_r3081_reg_names[] = {
-       "sr",   "lo",   "hi",   "bad",  "cause","pc",
-       "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
-       "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
-       "f16",  "f17",  "f18",  "f19",  "f20",  "f21",  "f22",  "f23",
-       "f24",  "f25",  "f26",  "f27",  "f28",  "f29",  "f30",  "f31",
-       "fsr",  "fir",  ""/*"fp"*/,     "",
-       "inx",  "rand", "elo",  "cfg",  "ctxt", "",     "",     "",
-       "",     "",     "ehi",  "",     "",     "",     "epc",  "prid",
-};
-
-/* Names of LSI 33k registers.  */
-
-char *mips_lsi33k_reg_names[] = {
-       "epc",  "hi",   "lo",   "sr",   "cause","badvaddr",
-       "dcic", "bpc",  "bda",  "",     "",     "",     "",      "",
-       "",     "",     "",     "",     "",     "",     "",      "",
-       "",     "",     "",     "",     "",     "",     "",      "",
-       "",     "",     "",     "",     "",     "",     "",      "",
-       "",     "",     "",     "",
-       "",     "",     "",     "",     "",     "",     "",      "",
-       "",     "",     "",     "",     "",     "",     "",      "",
-};
-
-struct {
-  char *name;
-  char **regnames;
-} mips_processor_type_table[] = {
-  { "generic", mips_generic_reg_names },
-  { "r3041", mips_r3041_reg_names },
-  { "r3051", mips_r3051_reg_names },
-  { "r3071", mips_r3081_reg_names },
-  { "r3081", mips_r3081_reg_names },
-  { "lsi33k", mips_lsi33k_reg_names },
-  { NULL, NULL }
-};
-/* *INDENT-ON* */
+/* Return the groups that a MIPS register can be categorised into.  */
 
+static int
+mips_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
+                         struct reggroup *reggroup)
+{
+  int vector_p;
+  int float_p;
+  int raw_p;
+  int rawnum = regnum % NUM_REGS;
+  int pseudo = regnum / NUM_REGS;
+  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')
+    return 0;
+  if (reggroup == float_reggroup)
+    return float_p && pseudo;
+  if (reggroup == vector_reggroup)
+    return vector_p && pseudo;
+  if (reggroup == general_reggroup)
+    return (!vector_p && !float_p) && pseudo;
+  /* Save the pseudo registers.  Need to make certain that any code
+     extracting register values from a saved register cache also uses
+     pseudo registers.  */
+  if (reggroup == save_reggroup)
+    return raw_p && pseudo;
+  /* Restore the same pseudo register.  */
+  if (reggroup == restore_reggroup)
+    return raw_p && pseudo;
+  return 0;   
+}
+
+/* Map the symbol table registers which live in the range [1 *
+   NUM_REGS .. 2 * 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 rawnum = cookednum % NUM_REGS;
+  gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
+  if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
+    return 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)
+       regcache_raw_read_part (regcache, rawnum, 0, 4, buf);
+      else
+       regcache_raw_read_part (regcache, rawnum, 4, 4, buf);
+    }
+  else
+    internal_error (__FILE__, __LINE__, "bad register size");
+}
 
+static void
+mips_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+                           int cookednum, const void *buf)
+{
+  int rawnum = cookednum % NUM_REGS;
+  gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
+  if (register_size (gdbarch, rawnum) == register_size (gdbarch, cookednum))
+    return 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)
+       regcache_raw_write_part (regcache, rawnum, 0, 4, buf);
+      else
+       regcache_raw_write_part (regcache, rawnum, 4, 4, buf);
+    }
+  else
+    internal_error (__FILE__, __LINE__, "bad register size");
+}
 
 /* Table to translate MIPS16 register field to actual register number.  */
 static int mips16_to_32_reg[8] =
@@ -538,145 +632,102 @@ struct linked_proc_info
   }
  *linked_proc_desc_table = NULL;
 
-void
-mips_print_extra_frame_info (struct frame_info *fi)
-{
-  if (fi
-      && get_frame_extra_info (fi)
-      && get_frame_extra_info (fi)->proc_desc
-      && get_frame_extra_info (fi)->proc_desc->pdr.framereg < NUM_REGS)
-    printf_filtered (" frame pointer is at %s+%s\n",
-                    REGISTER_NAME (get_frame_extra_info (fi)->proc_desc->pdr.framereg),
-                    paddr_d (get_frame_extra_info (fi)->proc_desc->pdr.frameoffset));
-}
-
 /* Number of bytes of storage in the actual machine representation for
-   register N.  NOTE: This indirectly defines the register size
-   transfered by the GDB protocol. */
+   register N.  NOTE: This defines the pseudo register type so need to
+   rebuild the architecture vector.  */
 
 static int mips64_transfers_32bit_regs_p = 0;
 
-static int
-mips_register_raw_size (int reg_nr)
-{
-  if (mips64_transfers_32bit_regs_p)
-    return REGISTER_VIRTUAL_SIZE (reg_nr);
-  else if (reg_nr >= FP0_REGNUM && reg_nr < FP0_REGNUM + 32
-          && FP_REGISTER_DOUBLE)
-    /* For MIPS_ABI_N32 (for example) we need 8 byte floating point
-       registers.  */
-    return 8;
-  else
-    return MIPS_REGSIZE;
+static void
+set_mips64_transfers_32bit_regs (char *args, int from_tty,
+                                struct cmd_list_element *c)
+{
+  struct gdbarch_info info;
+  gdbarch_info_init (&info);
+  /* FIXME: cagney/2003-11-15: Should be setting a field in "info"
+     instead of relying on globals.  Doing that would let generic code
+     handle the search for this specific architecture.  */
+  if (!gdbarch_update_p (info))
+    {
+      mips64_transfers_32bit_regs_p = 0;
+      error ("32-bit compatibility mode not supported");
+    }
 }
 
-/* Convert between RAW and VIRTUAL registers.  The RAW register size
-   defines the remote-gdb packet. */
+/* Convert to/from a register and the corresponding memory value.  */
 
 static int
-mips_register_convertible (int reg_nr)
+mips_convert_register_p (int regnum, struct type *type)
 {
-  if (mips64_transfers_32bit_regs_p)
-    return 0;
-  else
-    return (REGISTER_RAW_SIZE (reg_nr) > REGISTER_VIRTUAL_SIZE (reg_nr));
+  return (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
+         && register_size (current_gdbarch, regnum) == 4
+         && (regnum) >= mips_regnum (current_gdbarch)->fp0 && (regnum) < mips_regnum (current_gdbarch)->fp0 + 32
+         && TYPE_CODE(type) == TYPE_CODE_FLT
+         && TYPE_LENGTH(type) == 8);
 }
 
 static void
-mips_register_convert_to_virtual (int n, struct type *virtual_type,
-                                 char *raw_buf, char *virt_buf)
+mips_register_to_value (struct frame_info *frame, int regnum,
+                       struct type *type, void *to)
 {
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-    memcpy (virt_buf,
-           raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
-           TYPE_LENGTH (virtual_type));
-  else
-    memcpy (virt_buf,
-           raw_buf,
-           TYPE_LENGTH (virtual_type));
+  get_frame_register (frame, regnum + 0, (char *) to + 4);
+  get_frame_register (frame, regnum + 1, (char *) to + 0);
 }
 
 static void
-mips_register_convert_to_raw (struct type *virtual_type, int n,
-                             char *virt_buf, char *raw_buf)
+mips_value_to_register (struct frame_info *frame, int regnum,
+                       struct type *type, const void *from)
 {
-  memset (raw_buf, 0, REGISTER_RAW_SIZE (n));
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-    memcpy (raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
-           virt_buf,
-           TYPE_LENGTH (virtual_type));
-  else
-    memcpy (raw_buf,
-           virt_buf,
-           TYPE_LENGTH (virtual_type));
+  put_frame_register (frame, regnum + 0, (const char *) from + 4);
+  put_frame_register (frame, regnum + 1, (const char *) from + 0);
 }
 
-void
-mips_register_convert_to_type (int regnum, struct type *type, char *buffer)
-{
-  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-      && REGISTER_RAW_SIZE (regnum) == 4
-      && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
-      && TYPE_CODE(type) == TYPE_CODE_FLT
-      && TYPE_LENGTH(type) == 8) 
-    {
-      char temp[4];
-      memcpy (temp, ((char *)(buffer))+4, 4);
-      memcpy (((char *)(buffer))+4, (buffer), 4);
-      memcpy (((char *)(buffer)), temp, 4); 
-    }
-}
-
-void
-mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
-{
-if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-    && REGISTER_RAW_SIZE (regnum) == 4
-    && (regnum) >= FP0_REGNUM && (regnum) < FP0_REGNUM + 32
-    && TYPE_CODE(type) == TYPE_CODE_FLT
-    && TYPE_LENGTH(type) == 8) 
-  {
-    char temp[4];
-    memcpy (temp, ((char *)(buffer))+4, 4);
-    memcpy (((char *)(buffer))+4, (buffer), 4);
-    memcpy (((char *)(buffer)), temp, 4);
-  }
-}
-
-/* Return the GDB type object for the "standard" data type
-   of data in register REG.  
-   
-   Note: kevinb/2002-08-01: The definition below should faithfully
-   reproduce the behavior of each of the REGISTER_VIRTUAL_TYPE
-   definitions found in config/mips/tm-*.h.  I'm concerned about the
-   ``FCRCS_REGNUM <= reg && reg <= LAST_EMBED_REGNUM'' clause though.
-   In some cases DEPRECATED_FP_REGNUM is in this range, and I doubt
-   that this code is correct for the 64-bit case.  */
+/* Return the GDB type object for the "standard" data type of data in
+   register REG.  */
 
 static struct type *
-mips_register_virtual_type (int reg)
+mips_register_type (struct gdbarch *gdbarch, int regnum)
 {
-  if (FP0_REGNUM <= reg && reg < FP0_REGNUM + 32)
+  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)
     {
-      /* Floating point registers...  */
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-       return builtin_type_ieee_double_big;
-      else
-       return builtin_type_ieee_double_little;
+      /* The floating-point registers raw, or cooked, always match
+         mips_regsize(), and also map 1:1, byte for byte.  */
+      switch (gdbarch_byte_order (gdbarch))
+       {
+       case BFD_ENDIAN_BIG:
+         if (mips_regsize (gdbarch) == 4)
+           return builtin_type_ieee_single_big;
+         else
+           return builtin_type_ieee_double_big;
+       case BFD_ENDIAN_LITTLE:
+         if (mips_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");
+       }
     }
-  else if (reg == PS_REGNUM /* CR */)
-    return builtin_type_uint32;
-  else if (FCRCS_REGNUM <= reg && reg <= LAST_EMBED_REGNUM)
-    return builtin_type_uint32;
+  else if (regnum >= (NUM_REGS + mips_regnum (current_gdbarch)->fp_control_status)
+          && regnum <= NUM_REGS + 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;
+  else if (regnum >= NUM_REGS && mips_regsize (gdbarch)
+          && gdbarch_tdep (gdbarch)->mips64_transfers_32bit_regs_p)
+    /* The target, while using a 64-bit register buffer, is only
+       transfering 32-bits of each integer register.  Reflect this in
+       the cooked/pseudo register value.  */
+    return builtin_type_int32;
+  else if (mips_regsize (gdbarch) == 8)
+    /* 64-bit ISA.  */
+    return builtin_type_int64;
   else
-    {
-      /* Everything else...
-         Return type appropriate for width of register.  */
-      if (MIPS_REGSIZE == TYPE_LENGTH (builtin_type_uint64))
-       return builtin_type_uint64;
-      else
-       return builtin_type_uint32;
-    }
+    /* 32-bit ISA.  */
+    return builtin_type_int32;
 }
 
 /* TARGET_READ_SP -- Remove useless bits from the stack pointer.  */
@@ -739,18 +790,6 @@ mips_eabi_use_struct_convention (int gcc_p, struct type *type)
   return (TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE);
 }
 
-static int
-mips_n32n64_use_struct_convention (int gcc_p, struct type *type)
-{
-  return (TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE);
-}
-
-static int
-mips_o32_use_struct_convention (int gcc_p, struct type *type)
-{
-  return 1;    /* Structures are returned by ref in extra arg0.  */
-}
-
 /* Should call_function pass struct by reference? 
    For each architecture, structs are passed either by
    value or by reference, depending on their size.  */
@@ -787,7 +826,7 @@ pc_is_mips16 (bfd_vma memaddr)
   struct minimal_symbol *sym;
 
   /* If bit 0 of the address is set, assume this is a MIPS16 address. */
-  if (IS_MIPS16_ADDR (memaddr))
+  if (is_mips16_addr (memaddr))
     return 1;
 
   /* A flag indicating that this is a MIPS16 function is stored by elfread.c in
@@ -920,7 +959,7 @@ mips_fetch_instruction (CORE_ADDR addr)
   if (pc_is_mips16 (addr))
     {
       instlen = MIPS16_INSTLEN;
-      addr = UNMAKE_MIPS16_ADDR (addr);
+      addr = unmake_mips16_addr (addr);
     }
   else
     instlen = MIPS_INSTLEN;
@@ -994,7 +1033,7 @@ mips32_next_pc (CORE_ADDR pc)
        {
          int tf = itype_rt (inst) & 0x01;
          int cnum = itype_rt (inst) >> 2;
-         int fcrcs = read_signed_register (FCRCS_REGNUM);
+         int fcrcs = read_signed_register (mips_regnum (current_gdbarch)->fp_control_status);
          int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
 
          if (((cond >> cnum) & 0x01) == tf)
@@ -1423,101 +1462,100 @@ mips_next_pc (CORE_ADDR pc)
     return mips32_next_pc (pc);
 }
 
-/* Guaranteed to set fci->saved_regs to some values (it never leaves it
-   NULL).
-
-   Note: kevinb/2002-08-09: The only caller of this function is (and
-   should remain) mips_frame_init_saved_regs().  In fact,
-   aside from calling mips_find_saved_regs(), mips_frame_init_saved_regs()
-   does nothing more than set frame->saved_regs[SP_REGNUM].  These two
-   functions should really be combined and now that there is only one
-   caller, it should be straightforward.  (Watch out for multiple returns
-   though.)  */
+/* Set up the 'saved_regs' array.  This is a data structure containing
+   the addresses on the stack where each register has been saved, for
+   each stack frame.  Registers that have not been saved will have
+   zero here.  The stack pointer register is special: rather than the
+   address where the stack register has been saved,
+   saved_regs[SP_REGNUM] will have the actual value of the previous
+   frame's stack register.  */
 
 static void
 mips_find_saved_regs (struct frame_info *fci)
 {
   int ireg;
-  CORE_ADDR reg_position;
   /* r0 bit means kernel trap */
   int kernel_trap;
   /* What registers have been saved?  Bitmasks.  */
   unsigned long gen_mask, float_mask;
   mips_extra_func_info_t proc_desc;
   t_inst inst;
+  CORE_ADDR *saved_regs;
 
-  frame_saved_regs_zalloc (fci);
+  if (deprecated_get_frame_saved_regs (fci) != NULL)
+    return;
+  saved_regs = frame_saved_regs_zalloc (fci);
 
   /* If it is the frame for sigtramp, the saved registers are located
-     in a sigcontext structure somewhere on the stack.
-     If the stack layout for sigtramp changes we might have to change these
-     constants and the companion fixup_sigtramp in mdebugread.c  */
+     in a sigcontext structure somewhere on the stack.  If the stack
+     layout for sigtramp changes we might have to change these
+     constants and the companion fixup_sigtramp in mdebugread.c */
 #ifndef SIGFRAME_BASE
-/* To satisfy alignment restrictions, sigcontext is located 4 bytes
-   above the sigtramp frame.  */
-#define SIGFRAME_BASE          MIPS_REGSIZE
+  /* To satisfy alignment restrictions, sigcontext is located 4 bytes
+     above the sigtramp frame.  */
+#define SIGFRAME_BASE          mips_regsize (current_gdbarch)
 /* FIXME!  Are these correct?? */
-#define SIGFRAME_PC_OFF                (SIGFRAME_BASE + 2 * MIPS_REGSIZE)
-#define SIGFRAME_REGSAVE_OFF   (SIGFRAME_BASE + 3 * MIPS_REGSIZE)
+#define SIGFRAME_PC_OFF                (SIGFRAME_BASE + 2 * mips_regsize (current_gdbarch))
+#define SIGFRAME_REGSAVE_OFF   (SIGFRAME_BASE + 3 * mips_regsize (current_gdbarch))
 #define SIGFRAME_FPREGSAVE_OFF \
-        (SIGFRAME_REGSAVE_OFF + MIPS_NUMREGS * MIPS_REGSIZE + 3 * MIPS_REGSIZE)
-#endif
-#ifndef SIGFRAME_REG_SIZE
-/* FIXME!  Is this correct?? */
-#define SIGFRAME_REG_SIZE      MIPS_REGSIZE
+        (SIGFRAME_REGSAVE_OFF + MIPS_NUMREGS * mips_regsize (current_gdbarch) + 3 * mips_regsize (current_gdbarch))
 #endif
   if ((get_frame_type (fci) == SIGTRAMP_FRAME))
     {
       for (ireg = 0; ireg < MIPS_NUMREGS; ireg++)
        {
-         reg_position = get_frame_base (fci) + SIGFRAME_REGSAVE_OFF
-           + ireg * SIGFRAME_REG_SIZE;
-         get_frame_saved_regs (fci)[ireg] = reg_position;
+         CORE_ADDR reg_position = (get_frame_base (fci) + SIGFRAME_REGSAVE_OFF
+                                   + ireg * mips_regsize (current_gdbarch));
+         set_reg_offset (saved_regs, ireg, reg_position);
        }
       for (ireg = 0; ireg < MIPS_NUMREGS; ireg++)
        {
-         reg_position = get_frame_base (fci) + SIGFRAME_FPREGSAVE_OFF
-           + ireg * SIGFRAME_REG_SIZE;
-         get_frame_saved_regs (fci)[FP0_REGNUM + ireg] = reg_position;
+         CORE_ADDR reg_position = (get_frame_base (fci)
+                                   + SIGFRAME_FPREGSAVE_OFF
+                                   + ireg * mips_regsize (current_gdbarch));
+         set_reg_offset (saved_regs, mips_regnum (current_gdbarch)->fp0 + ireg, reg_position);
        }
-      get_frame_saved_regs (fci)[PC_REGNUM] = get_frame_base (fci) + SIGFRAME_PC_OFF;
+
+      set_reg_offset (saved_regs, PC_REGNUM, get_frame_base (fci) + SIGFRAME_PC_OFF);
+      /* SP_REGNUM, contains the value and not the address.  */
+      set_reg_offset (saved_regs, SP_REGNUM, get_frame_base (fci));
       return;
     }
 
   proc_desc = get_frame_extra_info (fci)->proc_desc;
   if (proc_desc == NULL)
-    /* I'm not sure how/whether this can happen.  Normally when we can't
-       find a proc_desc, we "synthesize" one using heuristic_proc_desc
-       and set the saved_regs right away.  */
+    /* I'm not sure how/whether this can happen.  Normally when we
+       can't find a proc_desc, we "synthesize" one using
+       heuristic_proc_desc and set the saved_regs right away.  */
     return;
 
   kernel_trap = PROC_REG_MASK (proc_desc) & 1;
   gen_mask = kernel_trap ? 0xFFFFFFFF : PROC_REG_MASK (proc_desc);
   float_mask = kernel_trap ? 0xFFFFFFFF : PROC_FREG_MASK (proc_desc);
 
-  if (                         /* In any frame other than the innermost or a frame interrupted by
-                                  a signal, we assume that all registers have been saved.
-                                  This assumes that all register saves in a function happen before
-                                  the first function call.  */
+  if (/* In any frame other than the innermost or a frame interrupted
+        by a signal, we assume that all registers have been saved.
+        This assumes that all register saves in a function happen
+        before the first function call.  */
        (get_next_frame (fci) == NULL
        || (get_frame_type (get_next_frame (fci)) == SIGTRAMP_FRAME))
 
-  /* In a dummy frame we know exactly where things are saved.  */
+       /* In a dummy frame we know exactly where things are saved.  */
        && !PROC_DESC_IS_DUMMY (proc_desc)
 
-  /* Don't bother unless we are inside a function prologue.  Outside the
-     prologue, we know where everything is. */
+       /* Don't bother unless we are inside a function prologue.
+         Outside the prologue, we know where everything is. */
 
        && in_prologue (get_frame_pc (fci), PROC_LOW_ADDR (proc_desc))
 
-  /* Not sure exactly what kernel_trap means, but if it means
-     the kernel saves the registers without a prologue doing it,
-     we better not examine the prologue to see whether registers
-     have been saved yet.  */
+       /* Not sure exactly what kernel_trap means, but if it means the
+         kernel saves the registers without a prologue doing it, we
+         better not examine the prologue to see whether registers
+         have been saved yet.  */
        && !kernel_trap)
     {
-      /* We need to figure out whether the registers that the proc_desc
-         claims are saved have been saved yet.  */
+      /* We need to figure out whether the registers that the
+         proc_desc claims are saved have been saved yet.  */
 
       CORE_ADDR addr;
 
@@ -1530,8 +1568,8 @@ mips_find_saved_regs (struct frame_info *fci)
       addr = PROC_LOW_ADDR (proc_desc);
       instlen = pc_is_mips16 (addr) ? MIPS16_INSTLEN : MIPS_INSTLEN;
 
-      /* Scan through this function's instructions preceding the current
-         PC, and look for those that save registers.  */
+      /* Scan through this function's instructions preceding the
+         current PC, and look for those that save registers.  */
       while (addr < get_frame_pc (fci))
        {
          inst = mips_fetch_instruction (addr);
@@ -1545,125 +1583,122 @@ mips_find_saved_regs (struct frame_info *fci)
       float_mask = float_save_found;
     }
 
-  /* Fill in the offsets for the registers which gen_mask says
-     were saved.  */
-  reg_position = get_frame_base (fci) + PROC_REG_OFFSET (proc_desc);
-  for (ireg = MIPS_NUMREGS - 1; gen_mask; --ireg, gen_mask <<= 1)
-    if (gen_mask & 0x80000000)
-      {
-       get_frame_saved_regs (fci)[ireg] = reg_position;
-       reg_position -= MIPS_SAVED_REGSIZE;
-      }
+  /* Fill in the offsets for the registers which gen_mask says were
+     saved.  */
+  {
+    CORE_ADDR reg_position = (get_frame_base (fci)
+                             + PROC_REG_OFFSET (proc_desc));
+    for (ireg = MIPS_NUMREGS - 1; gen_mask; --ireg, gen_mask <<= 1)
+      if (gen_mask & 0x80000000)
+       {
+         set_reg_offset (saved_regs, ireg, reg_position);
+         reg_position -= MIPS_SAVED_REGSIZE;
+       }
+  }
 
-  /* The MIPS16 entry instruction saves $s0 and $s1 in the reverse order
-     of that normally used by gcc.  Therefore, we have to fetch the first
-     instruction of the function, and if it's an entry instruction that
-     saves $s0 or $s1, correct their saved addresses.  */
+  /* The MIPS16 entry instruction saves $s0 and $s1 in the reverse
+     order of that normally used by gcc.  Therefore, we have to fetch
+     the first instruction of the function, and if it's an entry
+     instruction that saves $s0 or $s1, correct their saved addresses.  */
   if (pc_is_mips16 (PROC_LOW_ADDR (proc_desc)))
     {
       inst = mips_fetch_instruction (PROC_LOW_ADDR (proc_desc));
-      if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700)                /* entry */
+      if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700)
+       /* entry */
        {
          int reg;
          int sreg_count = (inst >> 6) & 3;
 
          /* Check if the ra register was pushed on the stack.  */
-         reg_position = get_frame_base (fci) + PROC_REG_OFFSET (proc_desc);
+         CORE_ADDR reg_position = (get_frame_base (fci)
+                                   + PROC_REG_OFFSET (proc_desc));
          if (inst & 0x20)
            reg_position -= MIPS_SAVED_REGSIZE;
 
-         /* Check if the s0 and s1 registers were pushed on the stack.  */
+         /* Check if the s0 and s1 registers were pushed on the
+             stack.  */
          for (reg = 16; reg < sreg_count + 16; reg++)
            {
-             get_frame_saved_regs (fci)[reg] = reg_position;
+             set_reg_offset (saved_regs, reg, reg_position);
              reg_position -= MIPS_SAVED_REGSIZE;
            }
        }
     }
 
-  /* Fill in the offsets for the registers which float_mask says
-     were saved.  */
-  reg_position = get_frame_base (fci) + PROC_FREG_OFFSET (proc_desc);
-
-  /* Apparently, the freg_offset gives the offset to the first 64 bit
-     saved.
-
-     When the ABI specifies 64 bit saved registers, the FREG_OFFSET
-     designates the first saved 64 bit register.
-
-     When the ABI specifies 32 bit saved registers, the ``64 bit saved
-     DOUBLE'' consists of two adjacent 32 bit registers, Hence
-     FREG_OFFSET, designates the address of the lower register of the
-     register pair.  Adjust the offset so that it designates the upper
-     register of the pair -- i.e., the address of the first saved 32
-     bit register.  */
-
-  if (MIPS_SAVED_REGSIZE == 4)
-    reg_position += MIPS_SAVED_REGSIZE;
-
-  /* Fill in the offsets for the float registers which float_mask says
-     were saved.  */
-  for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1)
-    if (float_mask & 0x80000000)
-      {
-       get_frame_saved_regs (fci)[FP0_REGNUM + ireg] = reg_position;
-       reg_position -= MIPS_SAVED_REGSIZE;
-      }
+  /* Fill in the offsets for the registers which float_mask says were
+     saved.  */
+  {
+    CORE_ADDR reg_position = (get_frame_base (fci)
+                             + PROC_FREG_OFFSET (proc_desc));
 
-  get_frame_saved_regs (fci)[PC_REGNUM] = get_frame_saved_regs (fci)[RA_REGNUM];
-}
+    /* Fill in the offsets for the float registers which float_mask
+       says were saved.  */
+    for (ireg = MIPS_NUMREGS - 1; float_mask; --ireg, float_mask <<= 1)
+      if (float_mask & 0x80000000)
+       {
+         if (MIPS_SAVED_REGSIZE == 4 && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+           {
+             /* On a big endian 32 bit ABI, floating point registers
+                are paired to form doubles such that the most
+                significant part is in $f[N+1] and the least
+                significant in $f[N] vis: $f[N+1] ||| $f[N].  The
+                registers are also spilled as a pair and stored as a
+                double.
+
+                When little-endian the least significant part is
+                stored first leading to the memory order $f[N] and
+                then $f[N+1].
+
+                Unfortunately, when big-endian the most significant
+                part of the double is stored first, and the least
+                significant is stored second.  This leads to the
+                registers being ordered in memory as firt $f[N+1] and
+                then $f[N].
+
+                For the big-endian case make certain that the
+                addresses point at the correct (swapped) locations
+                $f[N] and $f[N+1] pair (keep in mind that
+                reg_position is decremented each time through the
+                loop).  */
+             if ((ireg & 1))
+               set_reg_offset (saved_regs, mips_regnum (current_gdbarch)->fp0 + ireg,
+                               reg_position - MIPS_SAVED_REGSIZE);
+             else
+               set_reg_offset (saved_regs, mips_regnum (current_gdbarch)->fp0 + ireg,
+                               reg_position + MIPS_SAVED_REGSIZE);
+           }
+         else
+           set_reg_offset (saved_regs, mips_regnum (current_gdbarch)->fp0 + ireg, reg_position);
+         reg_position -= MIPS_SAVED_REGSIZE;
+       }
 
-/* Set up the 'saved_regs' array.  This is a data structure containing
-   the addresses on the stack where each register has been saved, for
-   each stack frame.  Registers that have not been saved will have
-   zero here.  The stack pointer register is special:  rather than the
-   address where the stack register has been saved, saved_regs[SP_REGNUM]
-   will have the actual value of the previous frame's stack register.  */
+    set_reg_offset (saved_regs, PC_REGNUM, saved_regs[RA_REGNUM]);
+  }
 
-static void
-mips_frame_init_saved_regs (struct frame_info *frame)
-{
-  if (get_frame_saved_regs (frame) == NULL)
-    {
-      mips_find_saved_regs (frame);
-    }
-  get_frame_saved_regs (frame)[SP_REGNUM] = get_frame_base (frame);
+  /* SP_REGNUM, contains the value and not the address.  */
+  set_reg_offset (saved_regs, SP_REGNUM, get_frame_base (fci));
 }
 
 static CORE_ADDR
 read_next_frame_reg (struct frame_info *fi, int regno)
 {
-  int optimized;
-  CORE_ADDR addr;
-  int realnum;
-  enum lval_type lval;
-  char raw_buffer[MAX_REGISTER_SIZE];
-
+  /* Always a pseudo.  */
+  gdb_assert (regno >= NUM_REGS);
   if (fi == NULL)
     {
-      regcache_cooked_read (current_regcache, regno, raw_buffer);
+      LONGEST val;
+      regcache_cooked_read_signed (current_regcache, regno, &val);
+      return val;
     }
+  else if ((regno % NUM_REGS) == SP_REGNUM)
+    /* The SP_REGNUM is special, its value is stored in saved_regs.
+       In fact, it is so special that it can even only be fetched
+       using a raw register number!  Once this code as been converted
+       to frame-unwind the problem goes away.  */
+    return frame_unwind_register_signed (fi, regno % NUM_REGS);
   else
-    {
-      frame_register_unwind (fi, regno, &optimized, &lval, &addr, &realnum,
-                            raw_buffer);
-      /* FIXME: cagney/2002-09-13: This is just soooo bad.  The MIPS
-        should have a pseudo register range that correspons to the ABI's,
-        rather than the ISA's, view of registers.  These registers would
-        then implicitly describe their size and hence could be used
-        without the below munging.  */
-      if (lval == lval_memory)
-       {
-         if (regno < 32)
-           {
-             /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
-                saved. */
-             return read_memory_integer (addr, MIPS_SAVED_REGSIZE);
-           }
-       }
-    }
+    return frame_unwind_register_signed (fi, regno);
 
-  return extract_signed_integer (raw_buffer, REGISTER_VIRTUAL_SIZE (regno));
 }
 
 /* mips_addr_bits_remove - remove useless address bits  */
@@ -1671,40 +1706,26 @@ read_next_frame_reg (struct frame_info *fi, int regno)
 static CORE_ADDR
 mips_addr_bits_remove (CORE_ADDR addr)
 {
-  if (GDB_TARGET_IS_MIPS64)
-    {
-      if (mips_mask_address_p () && (addr >> 32 == (CORE_ADDR) 0xffffffff))
-       {
-         /* This hack is a work-around for existing boards using
-            PMON, the simulator, and any other 64-bit targets that
-            doesn't have true 64-bit addressing.  On these targets,
-            the upper 32 bits of addresses are ignored by the
-            hardware.  Thus, the PC or SP are likely to have been
-            sign extended to all 1s by instruction sequences that
-            load 32-bit addresses.  For example, a typical piece of
-            code that loads an address is this:
-                lui $r2, <upper 16 bits>
-                ori $r2, <lower 16 bits>
-            But the lui sign-extends the value such that the upper 32
-            bits may be all 1s.  The workaround is simply to mask off
-            these bits.  In the future, gcc may be changed to support
-            true 64-bit addressing, and this masking will have to be
-            disabled.  */
-         addr &= (CORE_ADDR) 0xffffffff;
-       }
-    }
-  else if (mips_mask_address_p ())
-    {
-      /* FIXME: This is wrong!  mips_addr_bits_remove() shouldn't be
-         masking off bits, instead, the actual target should be asking
-         for the address to be converted to a valid pointer. */
-      /* Even when GDB is configured for some 32-bit targets
-        (e.g. mips-elf), BFD is configured to handle 64-bit targets,
-        so CORE_ADDR is 64 bits.  So we still have to mask off
-        useless bits from addresses.  */
-      addr &= (CORE_ADDR) 0xffffffff;
-    }
-  return addr;
+  if (mips_mask_address_p ()
+      && (((ULONGEST) addr) >> 32 == 0xffffffffUL))
+    /* This hack is a work-around for existing boards using PMON, the
+       simulator, and any other 64-bit targets that doesn't have true
+       64-bit addressing.  On these targets, the upper 32 bits of
+       addresses are ignored by the hardware.  Thus, the PC or SP are
+       likely to have been sign extended to all 1s by instruction
+       sequences that load 32-bit addresses.  For example, a typical
+       piece of code that loads an address is this:
+
+       lui $r2, <upper 16 bits>
+       ori $r2, <lower 16 bits>
+
+       But the lui sign-extends the value such that the upper 32 bits
+       may be all 1s.  The workaround is simply to mask off these
+       bits.  In the future, gcc may be changed to support true 64-bit
+       addressing, and this masking will have to be disabled.  */
+    return addr &= 0xffffffffUL;
+  else
+    return addr;
 }
 
 /* mips_software_single_step() is called just before we want to resume
@@ -1753,23 +1774,27 @@ static CORE_ADDR
 mips_frame_saved_pc (struct frame_info *frame)
 {
   CORE_ADDR saved_pc;
-  mips_extra_func_info_t proc_desc = get_frame_extra_info (frame)->proc_desc;
-  /* We have to get the saved pc from the sigcontext
-     if it is a signal handler frame.  */
-  int pcreg = (get_frame_type (frame) == SIGTRAMP_FRAME) ? PC_REGNUM
-  : (proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM);
 
   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), 0, 0))
     {
-      LONGEST tmp;
-      frame_unwind_signed_register (frame, PC_REGNUM, &tmp);
-      saved_pc = tmp;
+      /* Always unwind the cooked PC register value.  */
+      saved_pc = frame_unwind_register_signed (frame, NUM_REGS + PC_REGNUM);
     }
-  else if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
-    saved_pc = read_memory_integer (get_frame_base (frame) - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE);
   else
-    saved_pc = read_next_frame_reg (frame, pcreg);
-
+    {
+      mips_extra_func_info_t proc_desc
+       = get_frame_extra_info (frame)->proc_desc;
+      if (proc_desc && PROC_DESC_IS_DUMMY (proc_desc))
+       saved_pc = read_memory_integer (get_frame_base (frame) - MIPS_SAVED_REGSIZE, MIPS_SAVED_REGSIZE);
+      else
+       {
+         /* We have to get the saved pc from the sigcontext if it is
+            a signal handler frame.  */
+         int pcreg = (get_frame_type (frame) == SIGTRAMP_FRAME ? PC_REGNUM
+                      : proc_desc ? PROC_PC_REG (proc_desc) : RA_REGNUM);
+         saved_pc = read_next_frame_reg (frame, NUM_REGS + pcreg);
+       }
+    }
   return ADDR_BITS_REMOVE (saved_pc);
 }
 
@@ -1782,16 +1807,25 @@ static struct mips_extra_func_info temp_proc_desc;
    frames.  */
 static CORE_ADDR *temp_saved_regs;
 
-/* Set a register's saved stack address in temp_saved_regs.  If an address
-   has already been set for this register, do nothing; this way we will
-   only recognize the first save of a given register in a function prologue.
-   This is a helper function for mips{16,32}_heuristic_proc_desc.  */
+/* Set a register's saved stack address in temp_saved_regs.  If an
+   address has already been set for this register, do nothing; this
+   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.  */
 
 static void
-set_reg_offset (int regno, CORE_ADDR offset)
+set_reg_offset (CORE_ADDR *saved_regs, int regno, CORE_ADDR offset)
 {
-  if (temp_saved_regs[regno] == 0)
-    temp_saved_regs[regno] = offset;
+  if (saved_regs[regno] == 0)
+    {
+      saved_regs[regno + 0 * NUM_REGS] = offset;
+      saved_regs[regno + 1 * NUM_REGS] = offset;
+    }
 }
 
 
@@ -1987,26 +2021,26 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
          offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
          reg = mips16_to_32_reg[(inst & 0x700) >> 8];
          PROC_REG_MASK (&temp_proc_desc) |= (1 << reg);
-         set_reg_offset (reg, sp + offset);
+         set_reg_offset (temp_saved_regs, reg, sp + offset);
        }
       else if ((inst & 0xff00) == 0xf900)      /* sd reg,n($sp) */
        {
          offset = mips16_get_imm (prev_inst, inst, 5, 8, 0);
          reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
          PROC_REG_MASK (&temp_proc_desc) |= (1 << reg);
-         set_reg_offset (reg, sp + offset);
+         set_reg_offset (temp_saved_regs, reg, sp + offset);
        }
       else if ((inst & 0xff00) == 0x6200)      /* sw $ra,n($sp) */
        {
          offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
          PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM);
-         set_reg_offset (RA_REGNUM, sp + offset);
+         set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset);
        }
       else if ((inst & 0xff00) == 0xfa00)      /* sd $ra,n($sp) */
        {
          offset = mips16_get_imm (prev_inst, inst, 8, 8, 0);
          PROC_REG_MASK (&temp_proc_desc) |= (1 << RA_REGNUM);
-         set_reg_offset (RA_REGNUM, sp + offset);
+         set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset);
        }
       else if (inst == 0x673d) /* move $s1, $sp */
        {
@@ -2025,14 +2059,14 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
          offset = mips16_get_imm (prev_inst, inst, 5, 4, 0);
          reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
          PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
-         set_reg_offset (reg, frame_addr + offset);
+         set_reg_offset (temp_saved_regs, reg, frame_addr + offset);
        }
       else if ((inst & 0xFF00) == 0x7900)      /* sd reg,offset($s1) */
        {
          offset = mips16_get_imm (prev_inst, inst, 5, 8, 0);
          reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
          PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
-         set_reg_offset (reg, frame_addr + offset);
+         set_reg_offset (temp_saved_regs, reg, frame_addr + offset);
        }
       else if ((inst & 0xf81f) == 0xe809 && (inst & 0x700) != 0x700)   /* entry */
        entry_inst = inst;      /* save for later processing */
@@ -2062,7 +2096,7 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
       for (reg = 4, offset = 0; reg < areg_count + 4; reg++)
        {
          PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
-         set_reg_offset (reg, sp + offset);
+         set_reg_offset (temp_saved_regs, reg, sp + offset);
          offset += MIPS_SAVED_REGSIZE;
        }
 
@@ -2071,7 +2105,7 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
       if (entry_inst & 0x20)
        {
          PROC_REG_MASK (&temp_proc_desc) |= 1 << RA_REGNUM;
-         set_reg_offset (RA_REGNUM, sp + offset);
+         set_reg_offset (temp_saved_regs, RA_REGNUM, sp + offset);
          offset -= MIPS_SAVED_REGSIZE;
        }
 
@@ -2079,7 +2113,7 @@ mips16_heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
       for (reg = 16; reg < sreg_count + 16; reg++)
        {
          PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
-         set_reg_offset (reg, sp + offset);
+         set_reg_offset (temp_saved_regs, reg, sp + offset);
          offset -= MIPS_SAVED_REGSIZE;
        }
     }
@@ -2124,7 +2158,7 @@ restart:
       else if ((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */
        {
          PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
-         set_reg_offset (reg, sp + low_word);
+         set_reg_offset (temp_saved_regs, reg, sp + low_word);
        }
       else if ((high_word & 0xFFE0) == 0xffa0) /* sd reg,offset($sp) */
        {
@@ -2132,7 +2166,7 @@ restart:
             but the register size used is only 32 bits. Make the address
             for the saved register point to the lower 32 bits.  */
          PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
-         set_reg_offset (reg, sp + low_word + 8 - MIPS_REGSIZE);
+         set_reg_offset (temp_saved_regs, reg, sp + low_word + 8 - mips_regsize (current_gdbarch));
        }
       else if (high_word == 0x27be)    /* addiu $30,$sp,size */
        {
@@ -2143,7 +2177,7 @@ restart:
            {
              unsigned alloca_adjust;
              PROC_FRAME_REG (&temp_proc_desc) = 30;
-             frame_addr = read_next_frame_reg (next_frame, 30);
+             frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
              alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
              if (alloca_adjust > 0)
                {
@@ -2166,7 +2200,7 @@ restart:
            {
              unsigned alloca_adjust;
              PROC_FRAME_REG (&temp_proc_desc) = 30;
-             frame_addr = read_next_frame_reg (next_frame, 30);
+             frame_addr = read_next_frame_reg (next_frame, NUM_REGS + 30);
              alloca_adjust = (unsigned) (frame_addr - sp);
              if (alloca_adjust > 0)
                {
@@ -2182,7 +2216,7 @@ restart:
       else if ((high_word & 0xFFE0) == 0xafc0) /* sw reg,offset($30) */
        {
          PROC_REG_MASK (&temp_proc_desc) |= 1 << reg;
-         set_reg_offset (reg, frame_addr + low_word);
+         set_reg_offset (temp_saved_regs, reg, frame_addr + low_word);
        }
     }
 }
@@ -2194,7 +2228,7 @@ heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
   CORE_ADDR sp;
 
   if (cur_frame)
-    sp = read_next_frame_reg (next_frame, SP_REGNUM);
+    sp = read_next_frame_reg (next_frame, NUM_REGS + SP_REGNUM);
   else
     sp = 0;
 
@@ -2447,7 +2481,7 @@ find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame)
          to have their own proc_descs, and even if they don't,
          heuristic_proc_desc knows how to create them! */
 
-      register struct linked_proc_info *link;
+      struct linked_proc_info *link;
 
       for (link = linked_proc_desc_table; link; link = link->next)
        if (PROC_LOW_ADDR (&link->info) <= pc
@@ -2467,7 +2501,7 @@ static CORE_ADDR
 get_frame_pointer (struct frame_info *frame,
                   mips_extra_func_info_t proc_desc)
 {
-  return (read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
+  return (read_next_frame_reg (frame, NUM_REGS + PROC_FRAME_REG (proc_desc))
          + PROC_FRAME_OFFSET (proc_desc)
          - PROC_FRAME_ADJUST (proc_desc));
 }
@@ -2481,9 +2515,6 @@ mips_frame_chain (struct frame_info *frame)
   CORE_ADDR tmp;
   CORE_ADDR saved_pc = DEPRECATED_FRAME_SAVED_PC (frame);
 
-  if (saved_pc == 0 || inside_entry_file (saved_pc))
-    return 0;
-
   /* Check if the PC is inside a call stub.  If it is, fetch the
      PC of the caller of that stub.  */
   if ((tmp = SKIP_TRAMPOLINE_CODE (saved_pc)) != 0)
@@ -2542,7 +2573,6 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
 
   frame_extra_info_zalloc (fci, sizeof (struct frame_extra_info));
 
-  deprecated_set_frame_saved_regs_hack (fci, NULL);
   get_frame_extra_info (fci)->proc_desc =
     proc_desc == &temp_proc_desc ? 0 : proc_desc;
   if (proc_desc)
@@ -2553,7 +2583,7 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
          interrupted by a signal at it's very start.  */
       if (get_frame_pc (fci) == PROC_LOW_ADDR (proc_desc)
          && !PROC_DESC_IS_DUMMY (proc_desc))
-       deprecated_update_frame_base_hack (fci, read_next_frame_reg (get_next_frame (fci), SP_REGNUM));
+       deprecated_update_frame_base_hack (fci, read_next_frame_reg (get_next_frame (fci), NUM_REGS + SP_REGNUM));
       else if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (fci), 0, 0))
        /* Do not ``fix'' fci->frame.  It will have the value of the
            generic dummy frame's top-of-stack (since the draft
@@ -2581,15 +2611,18 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
          if (!PC_IN_SIGTRAMP (get_frame_pc (fci), name))
            {
              frame_saved_regs_zalloc (fci);
-             memcpy (get_frame_saved_regs (fci), temp_saved_regs, SIZEOF_FRAME_SAVED_REGS);
-             get_frame_saved_regs (fci)[PC_REGNUM]
-               = get_frame_saved_regs (fci)[RA_REGNUM];
-             /* Set value of previous frame's stack pointer.  Remember that
-                saved_regs[SP_REGNUM] is special in that it contains the
-                value of the stack pointer register.  The other saved_regs
-                values are addresses (in the inferior) at which a given
-                register's value may be found.  */
-             get_frame_saved_regs (fci)[SP_REGNUM] = get_frame_base (fci);
+             /* Set value of previous frame's stack pointer.
+                Remember that saved_regs[SP_REGNUM] is special in
+                that it contains the value of the stack pointer
+                register.  The other saved_regs values are addresses
+                (in the inferior) at which a given register's value
+                may be found.  */
+             set_reg_offset (temp_saved_regs, SP_REGNUM,
+                             get_frame_base (fci));
+             set_reg_offset (temp_saved_regs, PC_REGNUM,
+                             temp_saved_regs[RA_REGNUM]);
+             memcpy (deprecated_get_frame_saved_regs (fci), temp_saved_regs,
+                     SIZEOF_FRAME_SAVED_REGS);
            }
        }
 
@@ -2677,18 +2710,12 @@ mips_type_needs_double_align (struct type *type)
   return 0;
 }
 
-/* Macros to round N up or down to the next A boundary; 
-   A must be a power of two.  */
-
-#define ROUND_DOWN(n,a) ((n) & ~((a)-1))
-#define ROUND_UP(n,a) (((n)+(a)-1) & ~((a)-1))
-
 /* Adjust the address downward (direction of stack growth) so that it
    is correctly aligned for a new stack frame.  */
 static CORE_ADDR
 mips_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
-  return ROUND_DOWN (addr, 16);
+  return align_down (addr, 16);
 }
 
 static CORE_ADDR
@@ -2717,25 +2744,25 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
      aligned.  For n32 and n64, stack frames need to be 128-bit
      aligned, so we round to this widest known alignment.  */
 
-  sp = ROUND_DOWN (sp, 16);
-  struct_addr = ROUND_DOWN (struct_addr, 16);
+  sp = align_down (sp, 16);
+  struct_addr = align_down (struct_addr, 16);
 
   /* Now make space on the stack for the args.  We allocate more
      than necessary for EABI, because the first few arguments are
      passed in registers, but that's OK.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 
+    len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 
                     MIPS_STACK_ARGSIZE);
-  sp -= ROUND_UP (len, 16);
+  sp -= align_up (len, 16);
 
   if (mips_debug)
     fprintf_unfiltered (gdb_stdlog, 
-                       "mips_eabi_push_dummy_call: sp=0x%s allocated %d\n",
-                       paddr_nz (sp), ROUND_UP (len, 16));
+                       "mips_eabi_push_dummy_call: sp=0x%s allocated %ld\n",
+                       paddr_nz (sp), (long) align_up (len, 16));
 
   /* Initialize the integer and float register pointers.  */
   argreg = A0_REGNUM;
-  float_argreg = FPA0_REGNUM;
+  float_argreg = mips_fpa0_regnum (current_gdbarch);
 
   /* The struct_return pointer occupies the first parameter-passing reg.  */
   if (struct_return)
@@ -2843,10 +2870,11 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
          /* 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_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.  */
+         /* Note: structs whose size is not a multiple of
+            mips_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_SAVED_REGSIZE) &&
                                  (len % MIPS_SAVED_REGSIZE != 0));
 
@@ -2938,13 +2966,15 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                 only needs to be adjusted when it has been used.  */
 
              if (stack_used_p)
-               stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE);
+               stack_offset += align_up (partial_len, MIPS_STACK_ARGSIZE);
            }
        }
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
+  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+
   /* Return adjusted stack pointer.  */
   return sp;
 }
@@ -2977,23 +3007,23 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
      aligned.  For n32 and n64, stack frames need to be 128-bit
      aligned, so we round to this widest known alignment.  */
 
-  sp = ROUND_DOWN (sp, 16);
-  struct_addr = ROUND_DOWN (struct_addr, 16);
+  sp = align_down (sp, 16);
+  struct_addr = align_down (struct_addr, 16);
 
   /* Now make space on the stack for the args.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 
+    len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 
                     MIPS_STACK_ARGSIZE);
-  sp -= ROUND_UP (len, 16);
+  sp -= align_up (len, 16);
 
   if (mips_debug)
     fprintf_unfiltered (gdb_stdlog, 
-                       "mips_n32n64_push_dummy_call: sp=0x%s allocated %d\n",
-                       paddr_nz (sp), ROUND_UP (len, 16));
+                       "mips_n32n64_push_dummy_call: sp=0x%s allocated %ld\n",
+                       paddr_nz (sp), (long) align_up (len, 16));
 
   /* Initialize the integer and float register pointers.  */
   argreg = A0_REGNUM;
-  float_argreg = FPA0_REGNUM;
+  float_argreg = mips_fpa0_regnum (current_gdbarch);
 
   /* The struct_return pointer occupies the first parameter-passing reg.  */
   if (struct_return)
@@ -3048,10 +3078,11 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
          /* 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_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.  */
+         /* Note: structs whose size is not a multiple of
+            mips_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_SAVED_REGSIZE) &&
                                  (len % MIPS_SAVED_REGSIZE != 0));
          /* Note: Floating-point values that didn't fit into an FP
@@ -3167,13 +3198,15 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                 adjusted when it has been used.  */
 
              if (stack_used_p)
-               stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE);
+               stack_offset += align_up (partial_len, MIPS_STACK_ARGSIZE);
            }
        }
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
+  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+
   /* Return adjusted stack pointer.  */
   return sp;
 }
@@ -3206,23 +3239,23 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
      aligned.  For n32 and n64, stack frames need to be 128-bit
      aligned, so we round to this widest known alignment.  */
 
-  sp = ROUND_DOWN (sp, 16);
-  struct_addr = ROUND_DOWN (struct_addr, 16);
+  sp = align_down (sp, 16);
+  struct_addr = align_down (struct_addr, 16);
 
   /* Now make space on the stack for the args.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 
+    len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 
                     MIPS_STACK_ARGSIZE);
-  sp -= ROUND_UP (len, 16);
+  sp -= align_up (len, 16);
 
   if (mips_debug)
     fprintf_unfiltered (gdb_stdlog, 
-                       "mips_o32_push_dummy_call: sp=0x%s allocated %d\n",
-                       paddr_nz (sp), ROUND_UP (len, 16));
+                       "mips_o32_push_dummy_call: sp=0x%s allocated %ld\n",
+                       paddr_nz (sp), (long) align_up (len, 16));
 
   /* Initialize the integer and float register pointers.  */
   argreg = A0_REGNUM;
-  float_argreg = FPA0_REGNUM;
+  float_argreg = mips_fpa0_regnum (current_gdbarch);
 
   /* The struct_return pointer occupies the first parameter-passing reg.  */
   if (struct_return)
@@ -3329,17 +3362,18 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
              argreg += FP_REGISTER_DOUBLE ? 1 : 2;
            }
          /* Reserve space for the FP register.  */
-         stack_offset += ROUND_UP (len, MIPS_STACK_ARGSIZE);
+         stack_offset += align_up (len, MIPS_STACK_ARGSIZE);
        }
       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_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.  */
+         /* Note: structs whose size is not a multiple of
+            mips_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_SAVED_REGSIZE) &&
                                  (len % MIPS_SAVED_REGSIZE != 0));
          /* Structures should be aligned to eight bytes (even arg registers)
@@ -3415,8 +3449,8 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                  && !fp_register_arg_p (typecode, arg_type))
                {
                  LONGEST regval = extract_signed_integer (val, partial_len);
-                 /* Value may need to be sign extended, because 
-                    MIPS_REGSIZE != MIPS_SAVED_REGSIZE.  */
+                 /* Value may need to be sign extended, because
+                    mips_regsize() != MIPS_SAVED_REGSIZE.  */
 
                  /* A non-floating-point argument being passed in a
                     general register.  If a struct or union, and if
@@ -3473,13 +3507,15 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                 refered to as their "home".  Consequently, space is
                 always allocated.  */
 
-             stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE);
+             stack_offset += align_up (partial_len, MIPS_STACK_ARGSIZE);
            }
        }
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
+  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+
   /* Return adjusted stack pointer.  */
   return sp;
 }
@@ -3512,23 +3548,23 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
      aligned.  For n32 and n64, stack frames need to be 128-bit
      aligned, so we round to this widest known alignment.  */
 
-  sp = ROUND_DOWN (sp, 16);
-  struct_addr = ROUND_DOWN (struct_addr, 16);
+  sp = align_down (sp, 16);
+  struct_addr = align_down (struct_addr, 16);
 
   /* Now make space on the stack for the args.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 
+    len += align_up (TYPE_LENGTH (VALUE_TYPE (args[argnum])), 
                     MIPS_STACK_ARGSIZE);
-  sp -= ROUND_UP (len, 16);
+  sp -= align_up (len, 16);
 
   if (mips_debug)
     fprintf_unfiltered (gdb_stdlog, 
-                       "mips_o64_push_dummy_call: sp=0x%s allocated %d\n",
-                       paddr_nz (sp), ROUND_UP (len, 16));
+                       "mips_o64_push_dummy_call: sp=0x%s allocated %ld\n",
+                       paddr_nz (sp), (long) align_up (len, 16));
 
   /* Initialize the integer and float register pointers.  */
   argreg = A0_REGNUM;
-  float_argreg = FPA0_REGNUM;
+  float_argreg = mips_fpa0_regnum (current_gdbarch);
 
   /* The struct_return pointer occupies the first parameter-passing reg.  */
   if (struct_return)
@@ -3635,17 +3671,18 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
              argreg += FP_REGISTER_DOUBLE ? 1 : 2;
            }
          /* Reserve space for the FP register.  */
-         stack_offset += ROUND_UP (len, MIPS_STACK_ARGSIZE);
+         stack_offset += align_up (len, MIPS_STACK_ARGSIZE);
        }
       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_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.  */
+         /* Note: structs whose size is not a multiple of
+            mips_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_SAVED_REGSIZE) &&
                                  (len % MIPS_SAVED_REGSIZE != 0));
          /* Structures should be aligned to eight bytes (even arg registers)
@@ -3721,8 +3758,8 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                  && !fp_register_arg_p (typecode, arg_type))
                {
                  LONGEST regval = extract_signed_integer (val, partial_len);
-                 /* Value may need to be sign extended, because 
-                    MIPS_REGSIZE != MIPS_SAVED_REGSIZE.  */
+                 /* Value may need to be sign extended, because
+                    mips_regsize() != MIPS_SAVED_REGSIZE.  */
 
                  /* A non-floating-point argument being passed in a
                     general register.  If a struct or union, and if
@@ -3779,13 +3816,15 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
                 refered to as their "home".  Consequently, space is
                 always allocated.  */
 
-             stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE);
+             stack_offset += align_up (partial_len, MIPS_STACK_ARGSIZE);
            }
        }
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
+  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+
   /* Return adjusted stack pointer.  */
   return sp;
 }
@@ -3793,7 +3832,7 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
 static void
 mips_pop_frame (void)
 {
-  register int regnum;
+  int regnum;
   struct frame_info *frame = get_current_frame ();
   CORE_ADDR new_sp = get_frame_base (frame);
   mips_extra_func_info_t proc_desc;
@@ -3807,22 +3846,21 @@ mips_pop_frame (void)
 
   proc_desc = get_frame_extra_info (frame)->proc_desc;
   write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (frame));
-  if (get_frame_saved_regs (frame) == NULL)
-    DEPRECATED_FRAME_INIT_SAVED_REGS (frame);
+  mips_find_saved_regs (frame);
   for (regnum = 0; regnum < NUM_REGS; regnum++)
     if (regnum != SP_REGNUM && regnum != PC_REGNUM
-       && get_frame_saved_regs (frame)[regnum])
+       && deprecated_get_frame_saved_regs (frame)[regnum])
       {
        /* Floating point registers must not be sign extended, 
           in case MIPS_SAVED_REGSIZE = 4 but sizeof (FP0_REGNUM) == 8.  */
 
-       if (FP0_REGNUM <= regnum && regnum < FP0_REGNUM + 32)
+       if (mips_regnum (current_gdbarch)->fp0 <= regnum && regnum < mips_regnum (current_gdbarch)->fp0 + 32)
          write_register (regnum,
-                         read_memory_unsigned_integer (get_frame_saved_regs (frame)[regnum],
+                         read_memory_unsigned_integer (deprecated_get_frame_saved_regs (frame)[regnum],
                                                        MIPS_SAVED_REGSIZE));
        else
          write_register (regnum,
-                         read_memory_integer (get_frame_saved_regs (frame)[regnum],
+                         read_memory_integer (deprecated_get_frame_saved_regs (frame)[regnum],
                                               MIPS_SAVED_REGSIZE));
       }
 
@@ -3851,14 +3889,14 @@ mips_pop_frame (void)
 
       xfree (pi_ptr);
 
-      write_register (HI_REGNUM,
+      write_register (mips_regnum (current_gdbarch)->hi,
                      read_memory_integer (new_sp - 2 * MIPS_SAVED_REGSIZE,
                                           MIPS_SAVED_REGSIZE));
-      write_register (LO_REGNUM,
+      write_register (mips_regnum (current_gdbarch)->lo,
                      read_memory_integer (new_sp - 3 * MIPS_SAVED_REGSIZE,
                                           MIPS_SAVED_REGSIZE));
       if (MIPS_FPU_TYPE != MIPS_FPU_NONE)
-       write_register (FCRCS_REGNUM,
+       write_register (mips_regnum (current_gdbarch)->fp_control_status,
                        read_memory_integer (new_sp - 4 * MIPS_SAVED_REGSIZE,
                                             MIPS_SAVED_REGSIZE));
     }
@@ -3919,7 +3957,7 @@ static void
 mips_read_fp_register_single (struct frame_info *frame, int regno,
                              char *rare_buffer)
 {
-  int raw_size = REGISTER_RAW_SIZE (regno);
+  int raw_size = register_size (current_gdbarch, regno);
   char *raw_buffer = alloca (raw_size);
 
   if (!frame_register_read (frame, regno, raw_buffer))
@@ -3951,7 +3989,7 @@ static void
 mips_read_fp_register_double (struct frame_info *frame, int regno,
                              char *rare_buffer)
 {
-  int raw_size = REGISTER_RAW_SIZE (regno);
+  int raw_size = register_size (current_gdbarch, regno);
 
   if (raw_size == 8 && !mips2_fp_compat ())
     {
@@ -3962,7 +4000,7 @@ mips_read_fp_register_double (struct frame_info *frame, int regno,
     }
   else
     {
-      if ((regno - FP0_REGNUM) & 1)
+      if ((regno - mips_regnum (current_gdbarch)->fp0) & 1)
        internal_error (__FILE__, __LINE__,
                        "mips_read_fp_register_double: bad access to "
                        "odd-numbered FP register");
@@ -3990,13 +4028,13 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
   double doub, flt1, flt2;     /* doubles extracted from raw hex data */
   int inv1, inv2, namelen;
 
-  raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
+  raw_buffer = (char *) 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)),
                    "");
 
-  if (REGISTER_RAW_SIZE (regnum) == 4 || mips2_fp_compat ())
+  if (register_size (current_gdbarch, regnum) == 4 || mips2_fp_compat ())
     {
       /* 4-byte registers: Print hex and floating.  Also print even
          numbered registers as doubles.  */
@@ -4054,10 +4092,11 @@ static void
 mips_print_register (struct ui_file *file, struct frame_info *frame,
                     int regnum, int all)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   char raw_buffer[MAX_REGISTER_SIZE];
   int offset;
 
-  if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+  if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
     {
       mips_print_fp_register (file, frame, regnum);
       return;
@@ -4082,12 +4121,11 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
     fprintf_filtered (file, ": ");
 
   if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-    offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
+    offset = register_size (current_gdbarch, regnum) - register_size (current_gdbarch, regnum);
   else
     offset = 0;
 
-  print_scalar_formatted (raw_buffer + offset,
-                         REGISTER_VIRTUAL_TYPE (regnum),
+  print_scalar_formatted (raw_buffer + offset, gdbarch_register_type (gdbarch, regnum),
                          'x', 0, file);
 }
 
@@ -4109,54 +4147,61 @@ print_fp_register_row (struct ui_file *file, struct frame_info *frame,
 
 static int
 print_gp_register_row (struct ui_file *file, struct frame_info *frame,
-                      int regnum)
+                      int start_regnum)
 {
+  struct gdbarch *gdbarch = get_frame_arch (frame);
   /* do values for GP (int) regs */
   char raw_buffer[MAX_REGISTER_SIZE];
-  int ncols = (MIPS_REGSIZE == 8 ? 4 : 8);     /* display cols per row */
+  int ncols = (mips_regsize (gdbarch) == 8 ? 4 : 8);   /* display cols per row */
   int col, byte;
-  int start_regnum = regnum;
-  int numregs = NUM_REGS;
-
+  int regnum;
 
   /* For GP registers, we print a separate row of names above the vals */
   fprintf_filtered (file, "     ");
-  for (col = 0; col < ncols && regnum < numregs; regnum++)
+  for (col = 0, regnum = start_regnum;
+       col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS;
+       regnum++)
     {
       if (*REGISTER_NAME (regnum) == '\0')
        continue;               /* unused register */
-      if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+      if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
        break;                  /* end the row: reached FP register */
-      fprintf_filtered (file, MIPS_REGSIZE == 8 ? "%17s" : "%9s",
+      fprintf_filtered (file, mips_regsize (current_gdbarch) == 8 ? "%17s" : "%9s",
                        REGISTER_NAME (regnum));
       col++;
     }
-  fprintf_filtered (file,
-                   start_regnum < MIPS_NUMREGS ? "\n R%-4d" : "\n      ",
-                   start_regnum);      /* print the R0 to R31 names */
+  /* print the R0 to R31 names */
+  if ((start_regnum % NUM_REGS) < MIPS_NUMREGS)
+    fprintf_filtered (file, "\n R%-4d", start_regnum % NUM_REGS);
+  else
+    fprintf_filtered (file, "\n      ");
 
-  regnum = start_regnum;       /* go back to start of row */
   /* now print the values in hex, 4 or 8 to the row */
-  for (col = 0; col < ncols && regnum < numregs; regnum++)
+  for (col = 0, regnum = start_regnum;
+       col < ncols && regnum < NUM_REGS + NUM_PSEUDO_REGS;
+       regnum++)
     {
       if (*REGISTER_NAME (regnum) == '\0')
        continue;               /* unused register */
-      if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+      if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
        break;                  /* end row: reached FP 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));
       /* pad small registers */
-      for (byte = 0; byte < (MIPS_REGSIZE - REGISTER_VIRTUAL_SIZE (regnum)); byte++)
+      for (byte = 0;
+          byte < (mips_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)
-       for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
-            byte < REGISTER_RAW_SIZE (regnum);
+       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]);
       else
-       for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
+       for (byte = register_size (current_gdbarch, regnum) - 1;
             byte >= 0;
             byte--)
          fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
@@ -4177,6 +4222,7 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
 {
   if (regnum != -1)            /* do one specified register */
     {
+      gdb_assert (regnum >= NUM_REGS);
       if (*(REGISTER_NAME (regnum)) == '\0')
        error ("Not a valid register for the current processor type");
 
@@ -4186,10 +4232,10 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
   else
     /* do all (or most) registers */
     {
-      regnum = 0;
-      while (regnum < NUM_REGS)
+      regnum = NUM_REGS;
+      while (regnum < NUM_REGS + NUM_PSEUDO_REGS)
        {
-         if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+         if (TYPE_CODE (gdbarch_register_type (gdbarch, regnum)) == TYPE_CODE_FLT)
            {
              if (all)          /* true for "INFO ALL-REGISTERS" command */
                regnum = print_fp_register_row (file, frame, regnum);
@@ -4236,6 +4282,61 @@ mips_step_skips_delay (CORE_ADDR pc)
 }
 
 
+/* Given PC at the function's start address, attempt to find the
+   prologue end using SAL information.  Return zero if the skip fails.
+
+   A non-optimized prologue traditionally has one SAL for the function
+   and a second for the function body.  A single line function has
+   them both pointing at the same line.
+
+   An optimized prologue is similar but the prologue may contain
+   instructions (SALs) from the instruction body.  Need to skip those
+   while not getting into the function body.
+
+   The functions end point and an increasing SAL line are used as
+   indicators of the prologue's endpoint.
+
+   This code is based on the function refine_prologue_limit (versions
+   found in both ia64 and ppc).  */
+
+static CORE_ADDR
+skip_prologue_using_sal (CORE_ADDR func_addr)
+{
+  struct symtab_and_line prologue_sal;
+  CORE_ADDR start_pc;
+  CORE_ADDR end_pc;
+
+  /* Get an initial range for the function.  */
+  find_pc_partial_function (func_addr, NULL, &start_pc, &end_pc);
+  start_pc += FUNCTION_START_OFFSET;
+
+  prologue_sal = find_pc_line (start_pc, 0);
+  if (prologue_sal.line != 0)
+    {
+      while (prologue_sal.end < end_pc)
+       {
+         struct symtab_and_line sal;
+
+         sal = find_pc_line (prologue_sal.end, 0);
+         if (sal.line == 0)
+           break;
+         /* Assume that a consecutive SAL for the same (or larger)
+             line mark the prologue -> body transition.  */
+         if (sal.line >= prologue_sal.line)
+           break;
+         /* The case in which compiler's optimizer/scheduler has
+            moved instructions into the prologue.  We look ahead in
+            the function looking for address ranges whose
+            corresponding line number is less the first one that we
+            found for the function.  This is more conservative then
+            refine_prologue_limit which scans a large number of SALs
+            looking for any in the prologue */
+         prologue_sal = sal;
+       }
+    }
+  return prologue_sal.end;
+}
+
 /* Skip the PC past function prologue instructions (32-bit version).
    This is a helper function for mips_skip_prologue.  */
 
@@ -4247,10 +4348,15 @@ mips32_skip_prologue (CORE_ADDR pc)
   int seen_sp_adjust = 0;
   int load_immediate_bytes = 0;
 
+  /* Find an upper bound on the prologue.  */
+  end_pc = skip_prologue_using_sal (pc);
+  if (end_pc == 0)
+    end_pc = pc + 100; /* Magic.  */
+
   /* Skip the typical prologue instructions. These are the stack adjustment
      instruction and the instructions that save registers on the stack
      or in the gcc frame.  */
-  for (end_pc = pc + 100; pc < end_pc; pc += MIPS_INSTLEN)
+  for (; pc < end_pc; pc += MIPS_INSTLEN)
     {
       unsigned long high_word;
 
@@ -4392,10 +4498,15 @@ mips16_skip_prologue (CORE_ADDR pc)
     }                          /* end of table marker */
   };
 
+  /* Find an upper bound on the prologue.  */
+  end_pc = skip_prologue_using_sal (pc);
+  if (end_pc == 0)
+    end_pc = pc + 100; /* Magic.  */
+
   /* Skip the typical prologue instructions. These are the stack adjustment
      instruction and the instructions that save registers on the stack
      or in the gcc frame.  */
-  for (end_pc = pc + 100; pc < end_pc; pc += MIPS16_INSTLEN)
+  for (; pc < end_pc; pc += MIPS16_INSTLEN)
     {
       unsigned short inst;
       int i;
@@ -4490,11 +4601,11 @@ return_value_location (struct type *valtype,
          lo->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
          hi->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 0 : 4;
          lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-                            && REGISTER_RAW_SIZE (FP0_REGNUM) == 8)
+                            && register_size (current_gdbarch, mips_regnum (current_gdbarch)->fp0) == 8)
                            ? 4 : 0);
          hi->reg_offset = lo->reg_offset;
-         lo->reg = FP0_REGNUM + 0;
-         hi->reg = FP0_REGNUM + 1;
+         lo->reg = mips_regnum (current_gdbarch)->fp0 + 0;
+         hi->reg = mips_regnum (current_gdbarch)->fp0 + 1;
          lo->len = 4;
          hi->len = 4;
        }
@@ -4503,10 +4614,10 @@ return_value_location (struct type *valtype,
          /* The floating point value fits in a single floating-point
             register. */
          lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-                            && REGISTER_RAW_SIZE (FP0_REGNUM) == 8
+                            && register_size (current_gdbarch, mips_regnum (current_gdbarch)->fp0) == 8
                             && len == 4)
                            ? 4 : 0);
-         lo->reg = FP0_REGNUM;
+         lo->reg = mips_regnum (current_gdbarch)->fp0;
          lo->len = len;
          lo->buf_offset = 0;
          hi->len = 0;
@@ -4559,7 +4670,7 @@ return_value_location (struct type *valtype,
            }
        }
       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-         && REGISTER_RAW_SIZE (regnum) == 8
+         && register_size (current_gdbarch, regnum) == 8
          && MIPS_SAVED_REGSIZE == 4)
        {
          /* Account for the fact that only the least-signficant part
@@ -4585,12 +4696,12 @@ mips_eabi_extract_return_value (struct type *valtype,
   return_value_location (valtype, &hi, &lo);
 
   memcpy (valbuf + lo.buf_offset,
-         regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset,
+         regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) + lo.reg_offset,
          lo.len);
 
   if (hi.len > 0)
     memcpy (valbuf + hi.buf_offset,
-           regbuf + REGISTER_BYTE (hi.reg) + hi.reg_offset,
+           regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) + hi.reg_offset,
            hi.len);
 }
 
@@ -4604,12 +4715,12 @@ mips_o64_extract_return_value (struct type *valtype,
   return_value_location (valtype, &hi, &lo);
 
   memcpy (valbuf + lo.buf_offset,
-         regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset,
+         regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + lo.reg) + lo.reg_offset,
          lo.len);
 
   if (hi.len > 0)
     memcpy (valbuf + hi.buf_offset,
-           regbuf + REGISTER_BYTE (hi.reg) + hi.reg_offset,
+           regbuf + DEPRECATED_REGISTER_BYTE (NUM_REGS + hi.reg) + hi.reg_offset,
            hi.len);
 }
 
@@ -4626,15 +4737,15 @@ mips_eabi_store_return_value (struct type *valtype, char *valbuf)
 
   memset (raw_buffer, 0, sizeof (raw_buffer));
   memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
-  deprecated_write_register_bytes (REGISTER_BYTE (lo.reg), raw_buffer,
-                                  REGISTER_RAW_SIZE (lo.reg));
+  deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (lo.reg), raw_buffer,
+                                  register_size (current_gdbarch, lo.reg));
 
   if (hi.len > 0)
     {
       memset (raw_buffer, 0, sizeof (raw_buffer));
       memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len);
-      deprecated_write_register_bytes (REGISTER_BYTE (hi.reg), raw_buffer,
-                                      REGISTER_RAW_SIZE (hi.reg));
+      deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (hi.reg), raw_buffer,
+                                      register_size (current_gdbarch, hi.reg));
     }
 }
 
@@ -4648,63 +4759,76 @@ mips_o64_store_return_value (struct type *valtype, char *valbuf)
 
   memset (raw_buffer, 0, sizeof (raw_buffer));
   memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
-  deprecated_write_register_bytes (REGISTER_BYTE (lo.reg), raw_buffer,
-                                  REGISTER_RAW_SIZE (lo.reg));
+  deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (lo.reg), raw_buffer,
+                                  register_size (current_gdbarch, lo.reg));
 
   if (hi.len > 0)
     {
       memset (raw_buffer, 0, sizeof (raw_buffer));
       memcpy (raw_buffer + hi.reg_offset, valbuf + hi.buf_offset, hi.len);
-      deprecated_write_register_bytes (REGISTER_BYTE (hi.reg), raw_buffer,
-                                      REGISTER_RAW_SIZE (hi.reg));
+      deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (hi.reg), raw_buffer,
+                                      register_size (current_gdbarch, hi.reg));
     }
 }
 
 /* O32 ABI stuff.  */
 
-static void
-mips_o32_xfer_return_value (struct type *type,
-                           struct regcache *regcache,
-                           bfd_byte *in, const bfd_byte *out)
+static enum return_value_convention
+mips_o32_return_value (struct gdbarch *gdbarch, struct type *type,
+                      struct regcache *regcache,
+                      void *readbuf, const void *writebuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  if (TYPE_CODE (type) == TYPE_CODE_FLT
-      && TYPE_LENGTH (type) == 4
-      && tdep->mips_fpu_type != MIPS_FPU_NONE)
+
+  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 (TYPE_CODE (type) == TYPE_CODE_FLT
+          && TYPE_LENGTH (type) == 4
+          && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {
       /* A single-precision 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, FP0_REGNUM, TYPE_LENGTH (type),
-                         TARGET_BYTE_ORDER, in, out, 0);
+      mips_xfer_register (regcache,
+                         NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+                         TYPE_LENGTH (type),
+                         TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
   else if (TYPE_CODE (type) == TYPE_CODE_FLT
           && TYPE_LENGTH (type) == 8
           && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {
-      /* A double-precision floating-point value.  It fits in the
-         least significant part of FP0/FP1 but with byte ordering
-         based on the target (???).  */
+      /* A double-precision floating-point value.  The most
+         significant part goes in FP1, and the least significant in
+         FP0.  */
       if (mips_debug)
-       fprintf_unfiltered (gdb_stderr, "Return float in $fp0/$fp1\n");
+       fprintf_unfiltered (gdb_stderr, "Return float in $fp1/$fp0\n");
       switch (TARGET_BYTE_ORDER)
        {
        case BFD_ENDIAN_LITTLE:
-         mips_xfer_register (regcache, FP0_REGNUM + 0, 4,
-                             TARGET_BYTE_ORDER, in, out, 0);
-         mips_xfer_register (regcache, FP0_REGNUM + 1, 4,
-                             TARGET_BYTE_ORDER, in, out, 4);
+         mips_xfer_register (regcache,
+                             NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 0,
+                             4, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+         mips_xfer_register (regcache,
+                             NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 1,
+                             4, TARGET_BYTE_ORDER, readbuf, writebuf, 4);
          break;
        case BFD_ENDIAN_BIG:
-         mips_xfer_register (regcache, FP0_REGNUM + 1, 4,
-                             TARGET_BYTE_ORDER, in, out, 0);
-         mips_xfer_register (regcache, FP0_REGNUM + 0, 4,
-                             TARGET_BYTE_ORDER, in, out, 4);
+         mips_xfer_register (regcache,
+                             NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 1,
+                             4, TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+         mips_xfer_register (regcache,
+                             NUM_REGS + mips_regnum (current_gdbarch)->fp0 + 0,
+                             4, TARGET_BYTE_ORDER, readbuf, writebuf, 4);
          break;
        default:
          internal_error (__FILE__, __LINE__, "bad switch");
        }
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
 #if 0
   else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -4726,7 +4850,7 @@ mips_o32_xfer_return_value (struct type *type,
       bfd_byte reg[MAX_REGISTER_SIZE];
       int regnum;
       int field;
-      for (field = 0, regnum = FP0_REGNUM;
+      for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0;
           field < TYPE_NFIELDS (type);
           field++, regnum += 2)
        {
@@ -4734,9 +4858,11 @@ mips_o32_xfer_return_value (struct type *type,
                        / TARGET_CHAR_BIT);
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset);
-         mips_xfer_register (regcache, regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
-                             TARGET_BYTE_ORDER, in, out, offset);
+         mips_xfer_register (regcache, NUM_REGS + regnum,
+                             TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
+                             TARGET_BYTE_ORDER, readbuf, writebuf, offset);
        }
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
 #endif
 #if 0
@@ -4750,17 +4876,18 @@ mips_o32_xfer_return_value (struct type *type,
       int regnum;
       for (offset = 0, regnum = V0_REGNUM;
           offset < TYPE_LENGTH (type);
-          offset += REGISTER_RAW_SIZE (regnum), regnum++)
+          offset += register_size (current_gdbarch, regnum), regnum++)
        {
-         int xfer = REGISTER_RAW_SIZE (regnum);
+         int xfer = register_size (current_gdbarch, regnum);
          if (offset + xfer > TYPE_LENGTH (type))
            xfer = TYPE_LENGTH (type) - offset;
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
                                offset, xfer, regnum);
-         mips_xfer_register (regcache, regnum, xfer, BFD_ENDIAN_UNKNOWN,
-                             in, out, offset);
+         mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+                             BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
        }
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
 #endif
   else
@@ -4781,43 +4908,38 @@ mips_o32_xfer_return_value (struct type *type,
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return scalar+%d:%d in $%d\n",
                                offset, xfer, regnum);
-         mips_xfer_register (regcache, regnum, xfer, TARGET_BYTE_ORDER,
-                             in, out, offset);
+         mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+                             TARGET_BYTE_ORDER, readbuf, writebuf, offset);
        }
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
 }
 
-static void
-mips_o32_extract_return_value (struct type *type,
-                              struct regcache *regcache,
-                              void *valbuf)
-{
-  mips_o32_xfer_return_value (type, regcache, valbuf, NULL); 
-}
-
-static void
-mips_o32_store_return_value (struct type *type, char *valbuf)
-{
-  mips_o32_xfer_return_value (type, current_regcache, NULL, valbuf); 
-}
-
 /* N32/N44 ABI stuff.  */
 
-static void
-mips_n32n64_xfer_return_value (struct type *type,
-                              struct regcache *regcache,
-                              bfd_byte *in, const bfd_byte *out)
+static enum return_value_convention
+mips_n32n64_return_value (struct gdbarch *gdbarch,
+                         struct type *type, struct regcache *regcache,
+                         void *readbuf, const void *writebuf)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
-  if (TYPE_CODE (type) == TYPE_CODE_FLT
-      && tdep->mips_fpu_type != MIPS_FPU_NONE)
+  if (TYPE_CODE (type)== TYPE_CODE_STRUCT
+      || TYPE_CODE (type)== TYPE_CODE_UNION
+      || TYPE_CODE (type)== TYPE_CODE_ARRAY
+      || TYPE_LENGTH (type) > 2 * MIPS_SAVED_REGSIZE)
+    return RETURN_VALUE_STRUCT_CONVENTION;
+  else if (TYPE_CODE (type) == TYPE_CODE_FLT
+          && tdep->mips_fpu_type != MIPS_FPU_NONE)
     {
       /* A floating-point value belongs in the least significant part
          of FP0.  */
       if (mips_debug)
        fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
-      mips_xfer_register (regcache, FP0_REGNUM, TYPE_LENGTH (type),
-                         TARGET_BYTE_ORDER, in, out, 0);
+      mips_xfer_register (regcache,
+                         NUM_REGS + mips_regnum (current_gdbarch)->fp0,
+                         TYPE_LENGTH (type),
+                         TARGET_BYTE_ORDER, readbuf, writebuf, 0);
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
   else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
           && TYPE_NFIELDS (type) <= 2
@@ -4838,7 +4960,7 @@ mips_n32n64_xfer_return_value (struct type *type,
       bfd_byte reg[MAX_REGISTER_SIZE];
       int regnum;
       int field;
-      for (field = 0, regnum = FP0_REGNUM;
+      for (field = 0, regnum = mips_regnum (current_gdbarch)->fp0;
           field < TYPE_NFIELDS (type);
           field++, regnum += 2)
        {
@@ -4846,9 +4968,11 @@ mips_n32n64_xfer_return_value (struct type *type,
                        / TARGET_CHAR_BIT);
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return float struct+%d\n", offset);
-         mips_xfer_register (regcache, regnum, TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
-                             TARGET_BYTE_ORDER, in, out, offset);
+         mips_xfer_register (regcache, NUM_REGS + regnum,
+                             TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
+                             TARGET_BYTE_ORDER, readbuf, writebuf, offset);
        }
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
   else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
           || TYPE_CODE (type) == TYPE_CODE_UNION)
@@ -4860,17 +4984,18 @@ mips_n32n64_xfer_return_value (struct type *type,
       int regnum;
       for (offset = 0, regnum = V0_REGNUM;
           offset < TYPE_LENGTH (type);
-          offset += REGISTER_RAW_SIZE (regnum), regnum++)
+          offset += register_size (current_gdbarch, regnum), regnum++)
        {
-         int xfer = REGISTER_RAW_SIZE (regnum);
+         int xfer = register_size (current_gdbarch, regnum);
          if (offset + xfer > TYPE_LENGTH (type))
            xfer = TYPE_LENGTH (type) - offset;
          if (mips_debug)
            fprintf_unfiltered (gdb_stderr, "Return struct+%d:%d in $%d\n",
                                offset, xfer, regnum);
-         mips_xfer_register (regcache, regnum, xfer, BFD_ENDIAN_UNKNOWN,
-                             in, out, offset);
+         mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+                             BFD_ENDIAN_UNKNOWN, readbuf, writebuf, offset);
        }
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
   else
     {
@@ -4880,35 +5005,22 @@ mips_n32n64_xfer_return_value (struct type *type,
       int regnum;
       for (offset = 0, regnum = V0_REGNUM;
           offset < TYPE_LENGTH (type);
-          offset += REGISTER_RAW_SIZE (regnum), regnum++)
+          offset += register_size (current_gdbarch, regnum), regnum++)
        {
-         int xfer = REGISTER_RAW_SIZE (regnum);
+         int xfer = register_size (current_gdbarch, regnum);
          int pos = 0;
          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, regnum, xfer, TARGET_BYTE_ORDER,
-                             in, out, offset);
+         mips_xfer_register (regcache, NUM_REGS + regnum, xfer,
+                             TARGET_BYTE_ORDER, readbuf, writebuf, offset);
        }
+      return RETURN_VALUE_REGISTER_CONVENTION;
     }
 }
 
-static void
-mips_n32n64_extract_return_value (struct type *type,
-                                 struct regcache *regcache,
-                                 void *valbuf)
-{
-  mips_n32n64_xfer_return_value (type, regcache, valbuf, NULL);
-}
-
-static void
-mips_n32n64_store_return_value (struct type *type, char *valbuf)
-{
-  mips_n32n64_xfer_return_value (type, current_regcache, NULL, valbuf);
-}
-
 static CORE_ADDR
 mips_extract_struct_value_address (struct regcache *regcache)
 {
@@ -5013,76 +5125,22 @@ set_mipsfpu_auto_command (char *args, int from_tty)
   mips_fpu_type_auto = 1;
 }
 
-/* Command to set the processor type.  */
-
-void
-mips_set_processor_type_command (char *args, int from_tty)
-{
-  int i;
-
-  if (tmp_mips_processor_type == NULL || *tmp_mips_processor_type == '\0')
-    {
-      printf_unfiltered ("The known MIPS processor types are as follows:\n\n");
-      for (i = 0; mips_processor_type_table[i].name != NULL; ++i)
-       printf_unfiltered ("%s\n", mips_processor_type_table[i].name);
-
-      /* Restore the value.  */
-      tmp_mips_processor_type = xstrdup (mips_processor_type);
-
-      return;
-    }
-
-  if (!mips_set_processor_type (tmp_mips_processor_type))
-    {
-      error ("Unknown processor type `%s'.", tmp_mips_processor_type);
-      /* Restore its value.  */
-      tmp_mips_processor_type = xstrdup (mips_processor_type);
-    }
-}
-
-static void
-mips_show_processor_type_command (char *args, int from_tty)
-{
-}
-
-/* Modify the actual processor type. */
-
-static int
-mips_set_processor_type (char *str)
-{
-  int i;
-
-  if (str == NULL)
-    return 0;
-
-  for (i = 0; mips_processor_type_table[i].name != NULL; ++i)
-    {
-      if (strcasecmp (str, mips_processor_type_table[i].name) == 0)
-       {
-         mips_processor_type = str;
-         mips_processor_reg_names = mips_processor_type_table[i].regnames;
-         return 1;
-         /* FIXME tweak fpu flag too */
-       }
-    }
-
-  return 0;
-}
-
 /* Attempt to identify the particular processor model by reading the
-   processor id.  */
+   processor id.  NOTE: cagney/2003-11-15: Firstly it isn't clear that
+   the relevant processor still exists (it dates back to '94) and
+   secondly this is not the way to do this.  The processor type should
+   be set by forcing an architecture change.  */
 
-char *
-mips_read_processor_type (void)
+void
+deprecated_mips_set_processor_regs_hack (void)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   CORE_ADDR prid;
 
   prid = read_register (PRID_REGNUM);
 
   if ((prid & ~0xf) == 0x700)
-    return savestring ("r3041", strlen ("r3041"));
-
-  return NULL;
+    tdep->mips_processor_reg_names = mips_r3041_reg_names;
 }
 
 /* Just like reinit_frame_cache, but with the right arguments to be
@@ -5095,9 +5153,10 @@ reinit_frame_cache_sfunc (char *args, int from_tty,
   reinit_frame_cache ();
 }
 
-int
-gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info)
+static int
+gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info)
 {
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
   mips_extra_func_info_t proc_desc;
 
   /* Search for the function containing this address.  Set the low bit
@@ -5106,22 +5165,50 @@ gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info)
      the search would fail because the symbol table says the function
      starts at an odd address, i.e. 1 byte past the given address.  */
   memaddr = ADDR_BITS_REMOVE (memaddr);
-  proc_desc = non_heuristic_proc_desc (MAKE_MIPS16_ADDR (memaddr), NULL);
+  proc_desc = non_heuristic_proc_desc (make_mips16_addr (memaddr), NULL);
 
   /* Make an attempt to determine if this is a 16-bit function.  If
      the procedure descriptor exists and the address therein is odd,
      it's definitely a 16-bit function.  Otherwise, we have to just
      guess that if the address passed in is odd, it's 16-bits.  */
+  /* FIXME: cagney/2003-06-26: Is this even necessary?  The
+     disassembler needs to be able to locally determine the ISA, and
+     not rely on GDB.  Otherwize the stand-alone 'objdump -d' will not
+     work.  */
   if (proc_desc)
-    info->mach = pc_is_mips16 (PROC_LOW_ADDR (proc_desc)) ?
-      bfd_mach_mips16 : TM_PRINT_INSN_MACH;
+    {
+      if (pc_is_mips16 (PROC_LOW_ADDR (proc_desc)))
+       info->mach =  bfd_mach_mips16;
+    }
   else
-    info->mach = pc_is_mips16 (memaddr) ?
-      bfd_mach_mips16 : TM_PRINT_INSN_MACH;
+    {
+      if (pc_is_mips16 (memaddr))
+       info->mach = bfd_mach_mips16;
+    } 
 
   /* Round down the instruction address to the appropriate boundary.  */
   memaddr &= (info->mach == bfd_mach_mips16 ? ~1 : ~3);
 
+  /* Set the disassembler options.  */
+  if (tdep->mips_abi == MIPS_ABI_N32
+      || tdep->mips_abi == MIPS_ABI_N64)
+    {
+      /* Set up the disassembler info, so that we get the right
+        register names from libopcodes.  */
+      if (tdep->mips_abi == MIPS_ABI_N32)
+       info->disassembler_options = "gpr-names=n32";
+      else
+       info->disassembler_options = "gpr-names=64";
+      info->flavour = bfd_target_elf_flavour;
+    }
+  else
+    /* This string is not recognized explicitly by the disassembler,
+       but it tells the disassembler to not try to guess the ABI from
+       the bfd elf headers, such that, if the user overrides the ABI
+       of a program linked as NewABI, the disassembly will follow the
+       register naming conventions specified by the user.  */
+    info->disassembler_options = "gpr-names=32";
+
   /* Call the appropriate disassembler based on the target endian-ness.  */
   if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
     return print_insn_big_mips (memaddr, info);
@@ -5144,7 +5231,7 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
       if (pc_is_mips16 (*pcptr))
        {
          static unsigned char mips16_big_breakpoint[] = {0xe8, 0xa5};
-         *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
+         *pcptr = unmake_mips16_addr (*pcptr);
          *lenptr = sizeof (mips16_big_breakpoint);
          return mips16_big_breakpoint;
        }
@@ -5174,7 +5261,7 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
       if (pc_is_mips16 (*pcptr))
        {
          static unsigned char mips16_little_breakpoint[] = {0xa5, 0xe8};
-         *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
+         *pcptr = unmake_mips16_addr (*pcptr);
          *lenptr = sizeof (mips16_little_breakpoint);
          return mips16_little_breakpoint;
        }
@@ -5372,25 +5459,6 @@ mips_ignore_helper (CORE_ADDR pc)
 }
 
 
-/* Return a location where we can set a breakpoint that will be hit
-   when an inferior function call returns.  This is normally the
-   program's entry point.  Executables that don't have an entry
-   point (e.g. programs in ROM) should define a symbol __CALL_DUMMY_ADDRESS
-   whose address is the location where the breakpoint should be placed.  */
-
-static CORE_ADDR
-mips_call_dummy_address (void)
-{
-  struct minimal_symbol *sym;
-
-  sym = lookup_minimal_symbol ("__CALL_DUMMY_ADDRESS", NULL, NULL);
-  if (sym)
-    return SYMBOL_VALUE_ADDRESS (sym);
-  else
-    return entry_point_address ();
-}
-
-
 /* When debugging a 64 MIPS target running a 32 bit ABI, the size of
    the register stored on the stack (32) is different to its real raw
    size (64).  The below ensures that registers are fetched from the
@@ -5411,9 +5479,10 @@ mips_get_saved_register (char *raw_buffer,
   CORE_ADDR addrx;
   enum lval_type lvalx;
   int optimizedx;
+  int realnumx;
 
-  if (!target_has_registers)
-    error ("No registers.");
+  /* Always a pseudo.  */
+  gdb_assert (regnum >= NUM_REGS);
 
   /* Make certain that all needed parameters are present.  */
   if (addrp == NULL)
@@ -5422,26 +5491,20 @@ mips_get_saved_register (char *raw_buffer,
     lvalp = &lvalx;
   if (optimizedp == NULL)
     optimizedp = &optimizedx;
-  generic_unwind_get_saved_register (raw_buffer, optimizedp, addrp, frame,
-                                     regnum, lvalp);
-  /* FIXME: cagney/2002-09-13: This is just so bad.  The MIPS should
-     have a pseudo register range that correspons to the ABI's, rather
-     than the ISA's, view of registers.  These registers would then
-     implicitly describe their size and hence could be used without
-     the below munging.  */
-  if ((*lvalp) == lval_memory)
-    {
-      if (raw_buffer != NULL)
-       {
-         if (regnum < 32)
-           {
-             /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
-                saved. */
-             LONGEST val = read_memory_integer ((*addrp), MIPS_SAVED_REGSIZE);
-             store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
-           }
-       }
-    }
+
+  if ((regnum % NUM_REGS) == SP_REGNUM)
+    /* The SP_REGNUM is special, its value is stored in saved_regs.
+       In fact, it is so special that it can even only be fetched
+       using a raw register number!  Once this code as been converted
+       to frame-unwind the problem goes away.  */
+    frame_register_unwind (deprecated_get_next_frame_hack (frame),
+                          regnum % NUM_REGS, optimizedp, lvalp, addrp,
+                          &realnumx, raw_buffer);
+  else
+    /* Get it from the next frame.  */
+    frame_register_unwind (deprecated_get_next_frame_hack (frame),
+                          regnum, optimizedp, lvalp, addrp,
+                          &realnumx, raw_buffer);
 }
 
 /* Immediately after a function call, return the saved pc.
@@ -5456,48 +5519,64 @@ mips_saved_pc_after_call (struct frame_info *frame)
 }
 
 
-/* Convert a dbx stab register number (from `r' declaration) to a gdb
-   REGNUM */
+/* Convert a dbx stab register number (from `r' declaration) to a GDB
+   [1 * NUM_REGS .. 2 * NUM_REGS) REGNUM.  */
 
 static int
 mips_stab_reg_to_regnum (int num)
 {
+  int regnum;
   if (num >= 0 && num < 32)
-    return num;
+    regnum = num;
   else if (num >= 38 && num < 70)
-    return num + FP0_REGNUM - 38;
+    regnum = num + mips_regnum (current_gdbarch)->fp0 - 38;
   else if (num == 70)
-    return HI_REGNUM;
+    regnum = mips_regnum (current_gdbarch)->hi;
   else if (num == 71)
-    return LO_REGNUM;
+    regnum = mips_regnum (current_gdbarch)->lo;
   else
-    {
-      /* This will hopefully (eventually) provoke a warning.  Should
-         we be calling complaint() here?  */
-      return NUM_REGS + NUM_PSEUDO_REGS;
-    }
+    /* This will hopefully (eventually) provoke a warning.  Should
+       we be calling complaint() here?  */
+    return NUM_REGS + NUM_PSEUDO_REGS;
+  return NUM_REGS + regnum;
 }
 
 
-/* Convert a dwarf, dwarf2, or ecoff register number to a gdb REGNUM */
+/* Convert a dwarf, dwarf2, or ecoff register number to a GDB [1 *
+   NUM_REGS .. 2 * NUM_REGS) REGNUM.  */
 
 static int
 mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num)
 {
+  int regnum;
   if (num >= 0 && num < 32)
-    return num;
+    regnum = num;
   else if (num >= 32 && num < 64)
-    return num + FP0_REGNUM - 32;
+    regnum = num + mips_regnum (current_gdbarch)->fp0 - 32;
   else if (num == 64)
-    return HI_REGNUM;
+    regnum = mips_regnum (current_gdbarch)->hi;
   else if (num == 65)
-    return LO_REGNUM;
+    regnum = mips_regnum (current_gdbarch)->lo;
   else
-    {
-      /* This will hopefully (eventually) provoke a warning.  Should
-         we be calling complaint() here?  */
-      return NUM_REGS + NUM_PSEUDO_REGS;
-    }
+    /* This will hopefully (eventually) provoke a warning.  Should we
+       be calling complaint() here?  */
+    return NUM_REGS + NUM_PSEUDO_REGS;
+  return NUM_REGS + regnum;
+}
+
+static int
+mips_register_sim_regno (int regnum)
+{
+  /* Only makes sense to supply raw registers.  */
+  gdb_assert (regnum >= 0 && regnum < NUM_REGS);
+  /* 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')
+    return regnum;
+  else
+    return LEGACY_SIM_REGNO_IGNORE;    
 }
 
 
@@ -5564,12 +5643,7 @@ mips_gdbarch_init (struct gdbarch_info info,
   struct gdbarch_tdep *tdep;
   int elf_flags;
   enum mips_abi mips_abi, found_abi, wanted_abi;
-
-  /* Reset the disassembly info, in case it was set to something
-     non-default.  */
-  deprecated_tm_print_insn_info.flavour = bfd_target_unknown_flavour;
-  deprecated_tm_print_insn_info.arch = bfd_arch_unknown;
-  deprecated_tm_print_insn_info.mach = 0;
+  int num_regs;
 
   elf_flags = 0;
 
@@ -5650,34 +5724,6 @@ mips_gdbarch_init (struct gdbarch_info info,
   if (wanted_abi != MIPS_ABI_UNKNOWN)
     mips_abi = wanted_abi;
 
-  /* We have to set deprecated_tm_print_insn_info before looking for a
-     pre-existing architecture, otherwise we may return before we get
-     a chance to set it up.  */
-  if (mips_abi == MIPS_ABI_N32 || mips_abi == MIPS_ABI_N64)
-    {
-      /* Set up the disassembler info, so that we get the right
-        register names from libopcodes.  */
-      if (mips_abi == MIPS_ABI_N32)
-       deprecated_tm_print_insn_info.disassembler_options = "gpr-names=n32";
-      else
-       deprecated_tm_print_insn_info.disassembler_options = "gpr-names=64";
-      deprecated_tm_print_insn_info.flavour = bfd_target_elf_flavour;
-      deprecated_tm_print_insn_info.arch = bfd_arch_mips;
-      if (info.bfd_arch_info != NULL
-         && info.bfd_arch_info->arch == bfd_arch_mips
-         && info.bfd_arch_info->mach)
-       deprecated_tm_print_insn_info.mach = info.bfd_arch_info->mach;
-      else
-       deprecated_tm_print_insn_info.mach = bfd_mach_mips8000;
-    }
-  else
-    /* This string is not recognized explicitly by the disassembler,
-       but it tells the disassembler to not try to guess the ABI from
-       the bfd elf headers, such that, if the user overrides the ABI
-       of a program linked as NewABI, the disassembly will follow the
-       register naming conventions specified by the user.  */
-    deprecated_tm_print_insn_info.disassembler_options = "gpr-names=32";
-
   if (gdbarch_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
@@ -5702,6 +5748,11 @@ mips_gdbarch_init (struct gdbarch_info info,
        continue;
       if (gdbarch_tdep (arches->gdbarch)->mips_abi != mips_abi)
        continue;
+      /* Need to be pedantic about which register virtual size is
+         used.  */
+      if (gdbarch_tdep (arches->gdbarch)->mips64_transfers_32bit_regs_p
+         != mips64_transfers_32bit_regs_p)
+       continue;
       return arches->gdbarch;
     }
 
@@ -5709,6 +5760,7 @@ mips_gdbarch_init (struct gdbarch_info info,
   tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
   gdbarch = gdbarch_alloc (&info, tdep);
   tdep->elf_flags = elf_flags;
+  tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
 
   /* Initially set everything according to the default ABI/ISA.  */
   set_gdbarch_short_bit (gdbarch, 16);
@@ -5716,38 +5768,68 @@ mips_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_float_bit (gdbarch, 32);
   set_gdbarch_double_bit (gdbarch, 64);
   set_gdbarch_long_double_bit (gdbarch, 64);
-  set_gdbarch_register_raw_size (gdbarch, mips_register_raw_size);
+  set_gdbarch_register_reggroup_p (gdbarch, mips_register_reggroup_p);
+  set_gdbarch_pseudo_register_read (gdbarch, mips_pseudo_register_read);
+  set_gdbarch_pseudo_register_write (gdbarch, mips_pseudo_register_write);
   tdep->found_abi = found_abi;
   tdep->mips_abi = mips_abi;
 
   set_gdbarch_elf_make_msymbol_special (gdbarch, 
                                        mips_elf_make_msymbol_special);
 
-  if (info.osabi == GDB_OSABI_IRIX)
-    set_gdbarch_num_regs (gdbarch, 71);
-  else
-    set_gdbarch_num_regs (gdbarch, 90);
+  /* Fill in the OS dependant register numbers.  */
+  {
+    struct mips_regnum *regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch,
+                                                        struct mips_regnum);
+    tdep->regnum = regnum;
+    if (info.osabi == GDB_OSABI_IRIX)
+      {
+       regnum->fp0 = 32;
+       regnum->pc = 64;
+       regnum->cause = 65;
+       regnum->badvaddr = 66;
+       regnum->hi = 67;
+       regnum->lo = 68;
+       regnum->fp_control_status = 69;
+       regnum->fp_implementation_revision = 70;
+       num_regs = 71;
+      }
+    else
+      {
+       regnum->lo = MIPS_EMBED_LO_REGNUM;
+       regnum->hi = MIPS_EMBED_HI_REGNUM;
+       regnum->badvaddr = MIPS_EMBED_BADVADDR_REGNUM;
+       regnum->cause = MIPS_EMBED_CAUSE_REGNUM;
+       regnum->pc = MIPS_EMBED_PC_REGNUM;
+       regnum->fp0 = MIPS_EMBED_FP0_REGNUM;
+       regnum->fp_control_status = 70;
+       regnum->fp_implementation_revision = 71;
+       num_regs = 90;
+      }
+    /* FIXME: cagney/2003-11-15: For MIPS, hasn't PC_REGNUM been
+       replaced by read_pc?  */
+    set_gdbarch_pc_regnum (gdbarch, regnum->pc);
+    set_gdbarch_fp0_regnum (gdbarch, regnum->fp0);
+    set_gdbarch_num_regs (gdbarch, num_regs);
+    set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
+  }
 
   switch (mips_abi)
     {
     case MIPS_ABI_O32:
       set_gdbarch_push_dummy_call (gdbarch, mips_o32_push_dummy_call);
-      set_gdbarch_deprecated_store_return_value (gdbarch, mips_o32_store_return_value);
-      set_gdbarch_extract_return_value (gdbarch, mips_o32_extract_return_value);
+      set_gdbarch_return_value (gdbarch, mips_o32_return_value);
       tdep->mips_default_saved_regsize = 4;
       tdep->mips_default_stack_argsize = 4;
       tdep->mips_fp_register_double = 0;
       tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1;
-      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
-      tdep->gdb_target_is_mips64 = 0;
+      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 4 - 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
-      set_gdbarch_reg_struct_has_addr (gdbarch, 
-                                      mips_o32_reg_struct_has_addr);
-      set_gdbarch_use_struct_convention (gdbarch, 
-                                        mips_o32_use_struct_convention);
+      set_gdbarch_deprecated_reg_struct_has_addr
+       (gdbarch, mips_o32_reg_struct_has_addr);
       break;
     case MIPS_ABI_O64:
       set_gdbarch_push_dummy_call (gdbarch, mips_o64_push_dummy_call);
@@ -5757,16 +5839,14 @@ mips_gdbarch_init (struct gdbarch_info info,
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
       tdep->mips_last_arg_regnum = A0_REGNUM + 4 - 1;
-      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
-      tdep->gdb_target_is_mips64 = 1;
+      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 4 - 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
-      set_gdbarch_reg_struct_has_addr (gdbarch, 
-                                      mips_o32_reg_struct_has_addr);
-      set_gdbarch_use_struct_convention (gdbarch, 
-                                        mips_o32_use_struct_convention);
+      set_gdbarch_deprecated_reg_struct_has_addr
+       (gdbarch, mips_o32_reg_struct_has_addr);
+      set_gdbarch_use_struct_convention (gdbarch, always_use_struct_convention);
       break;
     case MIPS_ABI_EABI32:
       set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call);
@@ -5776,14 +5856,13 @@ mips_gdbarch_init (struct gdbarch_info info,
       tdep->mips_default_stack_argsize = 4;
       tdep->mips_fp_register_double = 0;
       tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
-      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
-      tdep->gdb_target_is_mips64 = 0;
+      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
-      set_gdbarch_reg_struct_has_addr (gdbarch, 
-                                      mips_eabi_reg_struct_has_addr);
+      set_gdbarch_deprecated_reg_struct_has_addr
+       (gdbarch, mips_eabi_reg_struct_has_addr);
       set_gdbarch_use_struct_convention (gdbarch, 
                                         mips_eabi_use_struct_convention);
       break;
@@ -5795,54 +5874,45 @@ mips_gdbarch_init (struct gdbarch_info info,
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
       tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
-      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
-      tdep->gdb_target_is_mips64 = 1;
+      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 64);
       set_gdbarch_ptr_bit (gdbarch, 64);
       set_gdbarch_long_long_bit (gdbarch, 64);
-      set_gdbarch_reg_struct_has_addr (gdbarch, 
-                                      mips_eabi_reg_struct_has_addr);
+      set_gdbarch_deprecated_reg_struct_has_addr
+       (gdbarch, mips_eabi_reg_struct_has_addr);
       set_gdbarch_use_struct_convention (gdbarch, 
                                         mips_eabi_use_struct_convention);
       break;
     case MIPS_ABI_N32:
       set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call);
-      set_gdbarch_deprecated_store_return_value (gdbarch, mips_n32n64_store_return_value);
-      set_gdbarch_extract_return_value (gdbarch, mips_n32n64_extract_return_value);
+      set_gdbarch_return_value (gdbarch, mips_n32n64_return_value);
       tdep->mips_default_saved_regsize = 8;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
       tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
-      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
-      tdep->gdb_target_is_mips64 = 1;
+      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
-      set_gdbarch_use_struct_convention (gdbarch, 
-                                        mips_n32n64_use_struct_convention);
-      set_gdbarch_reg_struct_has_addr (gdbarch, 
-                                      mips_n32n64_reg_struct_has_addr);
+      set_gdbarch_deprecated_reg_struct_has_addr
+       (gdbarch, mips_n32n64_reg_struct_has_addr);
       break;
     case MIPS_ABI_N64:
       set_gdbarch_push_dummy_call (gdbarch, mips_n32n64_push_dummy_call);
-      set_gdbarch_deprecated_store_return_value (gdbarch, mips_n32n64_store_return_value);
-      set_gdbarch_extract_return_value (gdbarch, mips_n32n64_extract_return_value);
+      set_gdbarch_return_value (gdbarch, mips_n32n64_return_value);
       tdep->mips_default_saved_regsize = 8;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
       tdep->mips_last_arg_regnum = A0_REGNUM + 8 - 1;
-      tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 8 - 1;
-      tdep->gdb_target_is_mips64 = 1;
+      tdep->mips_last_fp_arg_regnum = tdep->regnum->fp0 + 12 + 8 - 1;
       tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 64);
       set_gdbarch_ptr_bit (gdbarch, 64);
       set_gdbarch_long_long_bit (gdbarch, 64);
-      set_gdbarch_use_struct_convention (gdbarch, 
-                                        mips_n32n64_use_struct_convention);
-      set_gdbarch_reg_struct_has_addr (gdbarch, 
-                                      mips_n32n64_reg_struct_has_addr);
+      set_gdbarch_deprecated_reg_struct_has_addr
+       (gdbarch, mips_n32n64_reg_struct_has_addr);
       break;
     default:
       internal_error (__FILE__, __LINE__,
@@ -5892,19 +5962,18 @@ mips_gdbarch_init (struct gdbarch_info info,
   else
     tdep->mips_fpu_type = MIPS_FPU_DOUBLE;
 
-  /* MIPS version of register names.  NOTE: At present the MIPS
-     register name management is part way between the old -
-     #undef/#define REGISTER_NAMES and the new REGISTER_NAME(nr).
-     Further work on it is required.  */
-  /* NOTE: many targets (esp. embedded) do not go thru the
-     gdbarch_register_name vector at all, instead bypassing it
-     by defining REGISTER_NAMES.  */
+  /* MIPS version of register names.  */
   set_gdbarch_register_name (gdbarch, mips_register_name);
+  if (info.osabi == GDB_OSABI_IRIX)
+    tdep->mips_processor_reg_names = mips_irix_reg_names;
+  else if (info.bfd_arch_info != NULL && info.bfd_arch_info->mach == bfd_mach_mips3900)
+    tdep->mips_processor_reg_names = mips_tx39_reg_names;
+  else
+    tdep->mips_processor_reg_names = mips_generic_reg_names;
   set_gdbarch_read_pc (gdbarch, mips_read_pc);
   set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
   set_gdbarch_deprecated_target_read_fp (gdbarch, mips_read_sp); /* Draft FRAME base.  */
   set_gdbarch_read_sp (gdbarch, mips_read_sp);
-  set_gdbarch_deprecated_dummy_write_sp (gdbarch, generic_target_write_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.  */
@@ -5913,35 +5982,32 @@ mips_gdbarch_init (struct gdbarch_info info,
   /* There's a mess in stack frame creation.  See comments in
      blockframe.c near reference to DEPRECATED_INIT_FRAME_PC_FIRST.  */
   set_gdbarch_deprecated_init_frame_pc_first (gdbarch, mips_init_frame_pc_first);
-  set_gdbarch_deprecated_init_frame_pc (gdbarch, init_frame_pc_noop);
 
   /* Map debug register numbers onto internal register numbers.  */
   set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum);
   set_gdbarch_ecoff_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum);
   set_gdbarch_dwarf_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum);
   set_gdbarch_dwarf2_reg_to_regnum (gdbarch, mips_dwarf_dwarf2_ecoff_reg_to_regnum);
+  set_gdbarch_register_sim_regno (gdbarch, mips_register_sim_regno);
 
   /* Initialize a frame */
-  set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, mips_frame_init_saved_regs);
+  set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, mips_find_saved_regs);
   set_gdbarch_deprecated_init_extra_frame_info (gdbarch, mips_init_extra_frame_info);
 
   /* MIPS version of CALL_DUMMY */
 
-  set_gdbarch_call_dummy_address (gdbarch, mips_call_dummy_address);
+  /* NOTE: cagney/2003-08-05: Eventually call dummy location will be
+     replaced by a command, and all targets will default to on stack
+     (regardless of the stack's execute status).  */
+  set_gdbarch_call_dummy_location (gdbarch, AT_SYMBOL);
   set_gdbarch_deprecated_pop_frame (gdbarch, mips_pop_frame);
   set_gdbarch_frame_align (gdbarch, mips_frame_align);
-  set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
-  set_gdbarch_register_convertible (gdbarch, mips_register_convertible);
-  set_gdbarch_register_convert_to_virtual (gdbarch, 
-                                          mips_register_convert_to_virtual);
-  set_gdbarch_register_convert_to_raw (gdbarch, 
-                                      mips_register_convert_to_raw);
+  set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
 
   set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
   set_gdbarch_frameless_function_invocation (gdbarch, 
                                             generic_frameless_function_invocation_not);
   set_gdbarch_deprecated_frame_saved_pc (gdbarch, mips_frame_saved_pc);
-  set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
   set_gdbarch_frame_args_skip (gdbarch, 0);
 
   set_gdbarch_deprecated_get_saved_register (gdbarch, mips_get_saved_register);
@@ -5959,13 +6025,21 @@ mips_gdbarch_init (struct gdbarch_info info,
 
   set_gdbarch_function_start_offset (gdbarch, 0);
 
-  /* There are MIPS targets which do not yet use this since they still
-     define REGISTER_VIRTUAL_TYPE.  */
-  set_gdbarch_register_virtual_type (gdbarch, mips_register_virtual_type);
+  set_gdbarch_register_type (gdbarch, mips_register_type);
 
   set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info);
   set_gdbarch_pc_in_sigtramp (gdbarch, mips_pc_in_sigtramp);
 
+  set_gdbarch_print_insn (gdbarch, gdb_print_insn_mips);
+
+  /* FIXME: cagney/2003-08-29: The macros HAVE_STEPPABLE_WATCHPOINT,
+     HAVE_NONSTEPPABLE_WATCHPOINT, and HAVE_CONTINUABLE_WATCHPOINT
+     need to all be folded into the target vector.  Since they are
+     being used as guards for STOPPED_BY_WATCHPOINT, why not have
+     STOPPED_BY_WATCHPOINT return the type of watchpoint that the code
+     is sitting on?  */
+  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);
+
   /* Hook in OS ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
@@ -6084,10 +6158,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS_EABI = %d\n",
                      MIPS_EABI);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MIPS_LAST_FP_ARG_REGNUM = %d (%d regs)\n",
-                     MIPS_LAST_FP_ARG_REGNUM,
-                     MIPS_LAST_FP_ARG_REGNUM - FPA0_REGNUM + 1);
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
                      MIPS_FPU_TYPE,
@@ -6107,9 +6177,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS_STACK_ARGSIZE = %d\n",
                      MIPS_STACK_ARGSIZE);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MIPS_REGSIZE = %d\n",
-                     MIPS_REGSIZE);
   fprintf_unfiltered (file,
                      "mips_dump_tdep: A0_REGNUM = %d\n",
                      A0_REGNUM);
@@ -6119,39 +6186,15 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: ATTACH_DETACH # %s\n",
                      XSTRING (ATTACH_DETACH));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: BADVADDR_REGNUM = %d\n",
-                     BADVADDR_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: CAUSE_REGNUM = %d\n",
-                     CAUSE_REGNUM);
   fprintf_unfiltered (file,
                      "mips_dump_tdep: DWARF_REG_TO_REGNUM # %s\n",
                      XSTRING (DWARF_REG_TO_REGNUM (REGNUM)));
   fprintf_unfiltered (file,
                      "mips_dump_tdep: ECOFF_REG_TO_REGNUM # %s\n",
                      XSTRING (ECOFF_REG_TO_REGNUM (REGNUM)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: FCRCS_REGNUM = %d\n",
-                     FCRCS_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: FCRIR_REGNUM = %d\n",
-                     FCRIR_REGNUM);
   fprintf_unfiltered (file,
                      "mips_dump_tdep: FIRST_EMBED_REGNUM = %d\n",
                      FIRST_EMBED_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: FPA0_REGNUM = %d\n",
-                     FPA0_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: GDB_TARGET_IS_MIPS64 = %d\n",
-                     GDB_TARGET_IS_MIPS64);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: HAVE_NONSTEPPABLE_WATCHPOINT # %s\n",
-                     XSTRING (HAVE_NONSTEPPABLE_WATCHPOINT));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep:  HI_REGNUM = %d\n",
-                     HI_REGNUM);
   fprintf_unfiltered (file,
                      "mips_dump_tdep: IGNORE_HELPER_CALL # %s\n",
                      XSTRING (IGNORE_HELPER_CALL (PC)));
@@ -6161,14 +6204,9 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: IN_SOLIB_RETURN_TRAMPOLINE # %s\n",
                      XSTRING (IN_SOLIB_RETURN_TRAMPOLINE (PC, NAME)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: IS_MIPS16_ADDR = FIXME!\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: LAST_EMBED_REGNUM = %d\n",
                      LAST_EMBED_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: LO_REGNUM = %d\n",
-                     LO_REGNUM);
 #ifdef MACHINE_CPROC_FP_OFFSET
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MACHINE_CPROC_FP_OFFSET = %d\n",
@@ -6184,8 +6222,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
                      "mips_dump_tdep: MACHINE_CPROC_SP_OFFSET = %d\n",
                      MACHINE_CPROC_SP_OFFSET);
 #endif
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MAKE_MIPS16_ADDR = FIXME!\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS16_INSTLEN = %d\n",
                      MIPS16_INSTLEN);
@@ -6203,21 +6239,12 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS_NUMREGS = %d\n",
                      MIPS_NUMREGS);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MIPS_REGISTER_NAMES = delete?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS_SAVED_REGSIZE = %d\n",
                      MIPS_SAVED_REGSIZE);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: OP_LDFPR = used?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: OP_LDGPR = used?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: PRID_REGNUM = %d\n",
                      PRID_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: PRINT_EXTRA_FRAME_INFO # %s\n",
-                     XSTRING (PRINT_EXTRA_FRAME_INFO (FRAME)));
   fprintf_unfiltered (file,
                      "mips_dump_tdep: PROC_DESC_IS_DUMMY = function?\n");
   fprintf_unfiltered (file,
@@ -6248,18 +6275,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: RA_REGNUM = %d\n",
                      RA_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: REGISTER_CONVERT_FROM_TYPE # %s\n",
-                     XSTRING (REGISTER_CONVERT_FROM_TYPE (REGNUM, VALTYPE, RAW_BUFFER)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: REGISTER_CONVERT_TO_TYPE # %s\n",
-                     XSTRING (REGISTER_CONVERT_TO_TYPE (REGNUM, VALTYPE, RAW_BUFFER)));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: REGISTER_NAMES = delete?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: ROUND_DOWN = function?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: ROUND_UP = function?\n");
 #ifdef SAVED_BYTES
   fprintf_unfiltered (file,
                      "mips_dump_tdep: SAVED_BYTES = %d\n",
@@ -6292,9 +6307,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: SIGFRAME_REGSAVE_OFF = %d\n",
                      SIGFRAME_REGSAVE_OFF);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: SIGFRAME_REG_SIZE = %d\n",
-                     SIGFRAME_REG_SIZE);
   fprintf_unfiltered (file,
                      "mips_dump_tdep: SKIP_TRAMPOLINE_CODE # %s\n",
                      XSTRING (SKIP_TRAMPOLINE_CODE (PC)));
@@ -6332,11 +6344,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: TARGET_HAS_HARDWARE_WATCHPOINTS # %s\n",
                      XSTRING (TARGET_HAS_HARDWARE_WATCHPOINTS));
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: TARGET_MIPS = used?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: TM_PRINT_INSN_MACH # %s\n",
-                     XSTRING (TM_PRINT_INSN_MACH));
 #ifdef TRACE_CLEAR
   fprintf_unfiltered (file,
                      "mips_dump_tdep: TRACE_CLEAR # %s\n",
@@ -6357,8 +6364,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
                      "mips_dump_tdep: TRACE_SET # %s\n",
                      XSTRING (TRACE_SET (X,STATE)));
 #endif
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: UNMAKE_MIPS16_ADDR = function?\n");
 #ifdef UNUSED_REGNUM
   fprintf_unfiltered (file,
                      "mips_dump_tdep: UNUSED_REGNUM = %d\n",
@@ -6370,11 +6375,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: VM_MIN_ADDRESS = %ld\n",
                      (long) VM_MIN_ADDRESS);
-#ifdef VX_NUM_REGS
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: VX_NUM_REGS = %d (used?)\n",
-                     VX_NUM_REGS);
-#endif
   fprintf_unfiltered (file,
                      "mips_dump_tdep: ZERO_REGNUM = %d\n",
                      ZERO_REGNUM);
@@ -6383,6 +6383,8 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
                      _PROC_MAGIC_);
 }
 
+extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */
+
 void
 _initialize_mips_tdep (void)
 {
@@ -6395,8 +6397,6 @@ _initialize_mips_tdep (void)
     internal_error (__FILE__, __LINE__, "mips_abi_strings out of sync");
 
   gdbarch_register (bfd_arch_mips, mips_gdbarch_init, mips_dump_tdep);
-  if (!deprecated_tm_print_insn)        /* Someone may have already set it */
-    deprecated_tm_print_insn = gdb_print_insn_mips;
 
   /* Add root prefix command for all "set mips"/"show mips" commands */
   add_prefix_cmd ("mips", no_class, set_mips_command,
@@ -6509,16 +6509,18 @@ Show zeroing of upper 32 bits of 64-bit addresses.",
 
   /* Allow the user to control the size of 32 bit registers within the
      raw remote packet.  */
-  add_show_from_set (add_set_cmd ("remote-mips64-transfers-32bit-regs",
-                                 class_obscure,
-                                 var_boolean,
-                                 (char *)&mips64_transfers_32bit_regs_p, "\
-Set compatibility with MIPS targets that transfers 32 and 64 bit quantities.\n\
+  add_setshow_cmd ("remote-mips64-transfers-32bit-regs", class_obscure,
+                  var_boolean, &mips64_transfers_32bit_regs_p, "\
+Set compatibility with 64-bit MIPS targets that transfer 32-bit quantities.\n\
+Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
+that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
+64 bits for others.  Use \"off\" to disable compatibility mode",  "\
+Show compatibility with 64-bit MIPS targets that transfer 32-bit quantities.\n\
 Use \"on\" to enable backward compatibility with older MIPS 64 GDB+target\n\
 that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
 64 bits for others.  Use \"off\" to disable compatibility mode",
-                                 &setlist),
-                    &showlist);
+                  set_mips64_transfers_32bit_regs, NULL,
+                  &setlist, &showlist);
 
   /* Debug this files internals. */
   add_show_from_set (add_set_cmd ("mips", class_maintenance, var_zinteger,
This page took 0.071405 seconds and 4 git commands to generate.