2003-06-21 Andrew Cagney <cagney@redhat.com>
authorAndrew Cagney <cagney@redhat.com>
Sat, 21 Jun 2003 23:14:44 +0000 (23:14 +0000)
committerAndrew Cagney <cagney@redhat.com>
Sat, 21 Jun 2003 23:14:44 +0000 (23:14 +0000)
* mips-tdep.c: Include "reggroups.h" and "sim-regno.h".
(mips_register_name): Return names for NUM_REGS..2*NUM_REGS
instead of 0..NUM_REGS.
(mips_register_reggroup_p): New function.
(mips_pseudo_register_write): New function.
(mips_pseudo_register_read): New function.
(mips_register_raw_size): For NUM_REGS..2*NUM_REGS return the size
based on the register's type.
(read_next_frame_reg): Simplify.  Assert that REGNO is a pseudo /
cooked.
(mips_get_saved_register): Simplify.  Assert that REGNO is a
pseudo / cooked.
(mips_register_byte): New function.  Use MIPS_REGISTER_BYTE.
(mips_register_type): Replace mips_register_virtual_type.  Map
NUM_REGS..2*NUM_REGS onto 0..NUM_REGS.  Use MIPS_REGISTER_TYPE
when available.
(read_next_frame_reg): Simplify, but handle SP_REGNUM.  Assert
that the register is cooked / virtual.
(mips_frame_saved_pc): Fetch the cooked PC, and not the raw PC.
Only get the extra info when needed.
(set_reg_offset): Save the offset in NUM_REGS..2*NUM_REGS as well.
(mips32_heuristic_proc_desc): Fetch the cooked register.
(heuristic_proc_desc, mips_pop_frame, get_frame_pointer): Ditto.
(mips_init_extra_frame_info, get_frame_pointer): Ditto.
(mips_print_register): Use gdbarch_register_type, instead of
REGISTER_VIRTUAL_TYPE.
(print_gp_register_row): Use gdbarch_register_type, instead of
REGISTER_VIRTUAL_TYPE.  Allow for a pseudo / cooked REGNUM.
(mips_print_registers_info): Assert REGNO is pseodo / cooked.
Print the pseudo / cooked registers.
(mips_print_registers_info): Assert REGNO is pseodo / cooked.
Print the pseudo / cooked registers.
(mips_xfer_register): Use regcache_cooked_read_part.  Assert that
REG_NUM is pseudo / cooked.
(mips_o32_xfer_return_value): Xfer the pseudo / cooked register.
(mips_n32n64_xfer_return_value): Ditto.
(mips_stab_reg_to_regnum): Map onto NUM_REGS..2*NUM_REGS.
(mips_dwarf_dwarf2_ecoff_reg_to_regnum): Ditto.
(mips_register_sim_regno): New function.
(mips_gdbarch_init): Set deprecated_register_byte,
register_group_p, pseudo_register_write, pseudo_register_read,
register_sim_regno, and num_pseudo_regs.  Set register_type,
instead of register_virtual_type.
* Makefile.in (mips-tdep.o): Update dependencies.
* config/mips/tm-mips64.h (MIPS_REGISTER_TYPE): Rename
REGISTER_VIRTUAL_TYPE.
* config/mips/tm-mips.h (MIPS_REGISTER_TYPE): Ditto.
* config/mips/tm-irix5.h (MIPS_REGISTER_TYPE): Ditto.
* config/mips/tm-mips.h (MIPS_REGISTER_BYTE): Rename REGISTER_BYTE.
* config/mips/tm-irix6.h (MIPS_REGISTER_BYTE): Ditto.
* config/mips/tm-irix5.h (MIPS_REGISTER_BYTE): Ditto.

gdb/ChangeLog
gdb/Makefile.in
gdb/config/mips/tm-irix5.h
gdb/config/mips/tm-irix6.h
gdb/config/mips/tm-mips.h
gdb/config/mips/tm-mips64.h
gdb/mips-tdep.c

index 624d14f7016f461e49ee2181d01223e0335cb39b..6b1da4488c2f739c12cb3a7e4abbc0a8fbe6b830 100644 (file)
@@ -1,3 +1,57 @@
+2003-06-21  Andrew Cagney  <cagney@redhat.com>
+
+       * mips-tdep.c: Include "reggroups.h" and "sim-regno.h".
+       (mips_register_name): Return names for NUM_REGS..2*NUM_REGS
+       instead of 0..NUM_REGS.
+       (mips_register_reggroup_p): New function.
+       (mips_pseudo_register_write): New function.
+       (mips_pseudo_register_read): New function.
+       (mips_register_raw_size): For NUM_REGS..2*NUM_REGS return the size
+       based on the register's type.
+       (read_next_frame_reg): Simplify.  Assert that REGNO is a pseudo /
+       cooked.
+       (mips_get_saved_register): Simplify.  Assert that REGNO is a
+       pseudo / cooked.
+       (mips_register_byte): New function.  Use MIPS_REGISTER_BYTE.
+       (mips_register_type): Replace mips_register_virtual_type.  Map
+       NUM_REGS..2*NUM_REGS onto 0..NUM_REGS.  Use MIPS_REGISTER_TYPE
+       when available.
+       (read_next_frame_reg): Simplify, but handle SP_REGNUM.  Assert
+       that the register is cooked / virtual.
+       (mips_frame_saved_pc): Fetch the cooked PC, and not the raw PC.
+       Only get the extra info when needed.
+       (set_reg_offset): Save the offset in NUM_REGS..2*NUM_REGS as well.
+       (mips32_heuristic_proc_desc): Fetch the cooked register.
+       (heuristic_proc_desc, mips_pop_frame, get_frame_pointer): Ditto.
+       (mips_init_extra_frame_info, get_frame_pointer): Ditto.
+       (mips_print_register): Use gdbarch_register_type, instead of
+       REGISTER_VIRTUAL_TYPE.
+       (print_gp_register_row): Use gdbarch_register_type, instead of
+       REGISTER_VIRTUAL_TYPE.  Allow for a pseudo / cooked REGNUM.
+       (mips_print_registers_info): Assert REGNO is pseodo / cooked.
+       Print the pseudo / cooked registers.
+       (mips_print_registers_info): Assert REGNO is pseodo / cooked.
+       Print the pseudo / cooked registers.
+       (mips_xfer_register): Use regcache_cooked_read_part.  Assert that
+       REG_NUM is pseudo / cooked.
+       (mips_o32_xfer_return_value): Xfer the pseudo / cooked register.
+       (mips_n32n64_xfer_return_value): Ditto.
+       (mips_stab_reg_to_regnum): Map onto NUM_REGS..2*NUM_REGS.
+       (mips_dwarf_dwarf2_ecoff_reg_to_regnum): Ditto.
+       (mips_register_sim_regno): New function.
+       (mips_gdbarch_init): Set deprecated_register_byte,
+       register_group_p, pseudo_register_write, pseudo_register_read,
+       register_sim_regno, and num_pseudo_regs.  Set register_type,
+       instead of register_virtual_type.
+       * Makefile.in (mips-tdep.o): Update dependencies.
+       * config/mips/tm-mips64.h (MIPS_REGISTER_TYPE): Rename
+       REGISTER_VIRTUAL_TYPE.
+       * config/mips/tm-mips.h (MIPS_REGISTER_TYPE): Ditto.
+       * config/mips/tm-irix5.h (MIPS_REGISTER_TYPE): Ditto.
+       * config/mips/tm-mips.h (MIPS_REGISTER_BYTE): Rename REGISTER_BYTE.
+       * config/mips/tm-irix6.h (MIPS_REGISTER_BYTE): Ditto.
+       * config/mips/tm-irix5.h (MIPS_REGISTER_BYTE): Ditto.
+
 2003-06-21  Daniel Jacobowitz  <drow@mvista.com>
 
        * Makefile.in (cli-cmds.o): Depend on $(gdb_vfork_h)
index 22c7aa91a394fcda495d3b0d421afe5ddbd0fe5b..28433cd09af490f720dccf109ea09dd610c66aba 100644 (file)
@@ -2001,10 +2001,10 @@ mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
 mips-nat.o: mips-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) $(regcache_h)
 mips-tdep.o: mips-tdep.c $(defs_h) $(gdb_string_h) $(gdb_assert_h) \
        $(frame_h) $(inferior_h) $(symtab_h) $(value_h) $(gdbcmd_h) \
-       $(language_h) $(gdbcore_h) $(symfile_h) $(objfiles_h) \
-       $(gdbtypes_h) $(target_h) $(arch_utils_h) $(regcache_h) \
-       $(osabi_h) $(mips_tdep_h) $(block_h) $(opcode_mips_h) \
-       $(elf_mips_h) $(elf_bfd_h) $(symcat_h)
+       $(language_h) $(gdbcore_h) $(symfile_h) $(objfiles_h) $(gdbtypes_h) \
+       $(target_h) $(arch_utils_h) $(regcache_h) $(osabi_h) $(mips_tdep_h) \
+       $(block_h) $(reggroups_h) $(opcode_mips_h) $(elf_mips_h) \
+       $(elf_bfd_h) $(symcat_h)
 mipsm3-nat.o: mipsm3-nat.c $(defs_h) $(inferior_h) $(regcache_h)
 mipsnbsd-nat.o: mipsnbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
        $(mipsnbsd_tdep_h)
index 3d598c9dae1a7611f3d215df270f6b32f31a3c43..932852ea4878167cda4cf413b4e85484321eede3 100644 (file)
  * Irix 6 (n32 ABI) has 32-bit GP regs and 64-bit FP regs
  */
 
-#undef  REGISTER_BYTE
-#define REGISTER_BYTE(N) \
+#undef  MIPS_REGISTER_BYTE
+#define MIPS_REGISTER_BYTE(N) \
      (((N) < FP0_REGNUM) ? (N) * MIPS_REGSIZE : \
       ((N) < FP0_REGNUM + 32) ?     \
       FP0_REGNUM * MIPS_REGSIZE + \
       ((N) - FP0_REGNUM) * sizeof(double) : \
       32 * sizeof(double) + ((N) - 32) * MIPS_REGSIZE)
 
-#undef  REGISTER_VIRTUAL_TYPE
-#define REGISTER_VIRTUAL_TYPE(N) \
+#undef  MIPS_REGISTER_TYPE
+#define MIPS_REGISTER_TYPE(N) \
        (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_double \
         : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
         : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
index 14de12e4c4f04fd5025ecde268ba5e41b4469bf9..e6395ae6ef942bf9da18749eb80c2ee56042052c 100644 (file)
@@ -62,8 +62,8 @@
 #define FCRIR_REGNUM 70                /* FP implementation/revision */
 
 
-#undef  REGISTER_BYTE
-#define REGISTER_BYTE(N) \
+#undef  MIPS_REGISTER_BYTE
+#define MIPS_REGISTER_BYTE(N) \
      (((N) < FP0_REGNUM) ? (N) * MIPS_REGSIZE : \
       ((N) < FP0_REGNUM + 32) ?     \
       FP0_REGNUM * MIPS_REGSIZE + \
@@ -94,4 +94,4 @@
 #define SIGFRAME_REG_SIZE      8
 
 /* Undefine those methods which have been multiarched.  */
-#undef REGISTER_VIRTUAL_TYPE
+#undef MIPS_REGISTER_TYPE
index 39421fd3a6f3952a8ac371399104cc9436f2f408..51a6a7dbaeb9c8e9a405d8208e2c3b6b5201a789 100644 (file)
@@ -98,13 +98,13 @@ extern int mips_step_skips_delay (CORE_ADDR);
 /* Index within `registers' of the first byte of the space for
    register N.  */
 
-#define REGISTER_BYTE(N) ((N) * MIPS_REGSIZE)
+#define MIPS_REGISTER_BYTE(N) ((N) * MIPS_REGSIZE)
 
 /* Return the GDB type object for the "standard" data type of data in
    register N.  */
 
-#ifndef REGISTER_VIRTUAL_TYPE
-#define REGISTER_VIRTUAL_TYPE(N) \
+#ifndef MIPS_REGISTER_TYPE
+#define MIPS_REGISTER_TYPE(N) \
        (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_float \
         : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
         : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
index 13e62d2acf31b98fa91813bd3d5b895202512564..2547e86f482eb8bf508c7fc847abb48af2d7e2d6 100644 (file)
@@ -23,7 +23,7 @@
 #define MIPS_REGSIZE 8
 
 /* define 8 byte register type */
-#define REGISTER_VIRTUAL_TYPE(N) \
+#define MIPS_REGISTER_TYPE(N) \
         (((N) >= FP0_REGNUM && (N) < FP0_REGNUM+32) ? builtin_type_double \
         : ((N) == 32 /*SR*/) ? builtin_type_uint32 \
         : ((N) >= 70 && (N) <= 89) ? builtin_type_uint32 \
index c5dccc90b5911a254be78714a570145c9b402eeb..4009ca542abd8a556a42feb02e6372a87adb10d5 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"
 
 static void set_reg_offset (CORE_ADDR *saved_regs, int regnum, CORE_ADDR off);
 
@@ -270,6 +271,7 @@ 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)
@@ -298,9 +300,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;
@@ -440,21 +442,27 @@ 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 <= regno && regno < NUM_REGS)
-    return mips_processor_reg_names[regno - 32];
+  else if (32 <= rawnum && rawnum < NUM_REGS)
+    return mips_processor_reg_names[rawnum - 32];
   else
     internal_error (__FILE__, __LINE__,
-                   "mips_register_name: bad register number %d", regno);
+                   "mips_register_name: bad register number %d", rawnum);
 }
 
 /* *INDENT-OFF* */
@@ -524,8 +532,63 @@ struct {
 };
 /* *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.  */
 
+static void
+mips_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache,
+                          int cookednum, void *buf)
+{
+  gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
+  return regcache_raw_read (regcache, cookednum % NUM_REGS, buf);
+}
+
+static void
+mips_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache,
+                           int cookednum, const void *buf)
+{
+  gdb_assert (cookednum >= NUM_REGS && cookednum < 2 * NUM_REGS);
+  return regcache_raw_write (regcache, cookednum % NUM_REGS, buf);
+}
 
 /* Table to translate MIPS16 register field to actual register number.  */
 static int mips16_to_32_reg[8] =
@@ -575,22 +638,73 @@ mips_print_extra_frame_info (struct frame_info *fi)
 
 /* 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. */
+   transfered by the GDB protocol.  */
 
 static int mips64_transfers_32bit_regs_p = 0;
 
 static int
-mips_register_raw_size (int reg_nr)
+mips_register_raw_size (int regnum)
 {
-  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;
+  gdb_assert (regnum >= 0);
+  if (regnum < NUM_REGS)
+    {
+      /* For compatibility with old code, implemnt the broken register raw
+        size map for the raw registers.
+
+        NOTE: cagney/2003-06-15: This is so bogus.  The register's
+        raw size is changing according to the ABI
+        (FP_REGISTER_DOUBLE).  Also, GDB's protocol is defined by a
+        combination of REGISTER_RAW_SIZE and REGISTER_BYTE.  */
+      if (mips64_transfers_32bit_regs_p)
+       return REGISTER_VIRTUAL_SIZE (regnum);
+      else if (regnum >= FP0_REGNUM && regnum < 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;
+    }
+  else if (regnum < 2 * NUM_REGS)
+    {
+      /* For the moment map [NUM_REGS .. 2*NUM_REGS) onto the same raw
+        registers, but always return the virtual size.  */
+      int rawnum = regnum % NUM_REGS;
+      return TYPE_LENGTH (MIPS_REGISTER_TYPE (rawnum));
+    }
   else
-    return MIPS_REGSIZE;
+    internal_error (__FILE__, __LINE__, "Register %d out of range", regnum);
+}
+
+/* Register offset in a buffer for each register.
+
+   FIXME: cagney/2003-06-15: This is so bogus.  Instead REGISTER_TYPE
+   should strictly return the layout of the buffer.  Unfortunatly
+   remote.c and the MIPS have come to rely on a custom layout that
+   doesn't 1:1 map onto the register type.  */
+
+static int
+mips_register_byte (int regnum)
+{
+  gdb_assert (regnum >= 0);
+  if (regnum < NUM_REGS)
+    /* Pick up the relevant per-tm file register byte method.  */
+    return MIPS_REGISTER_BYTE (regnum);
+  else if (regnum < 2 * NUM_REGS)
+    {
+      int reg;
+      int byte;
+      /* Start with the end of the raw register buffer - assum that
+        MIPS_REGISTER_BYTE (NUM_REGS) returns that end.  */
+      byte = MIPS_REGISTER_BYTE (NUM_REGS);
+      /* Add space for all the proceeding registers based on their
+         real size.  */
+      for (reg = NUM_REGS; reg < regnum; reg++)
+       byte += TYPE_LENGTH (MIPS_REGISTER_TYPE ((reg % NUM_REGS)));
+      return byte;
+    }
+  else
+    internal_error (__FILE__, __LINE__, "Register %d out of range", regnum);
 }
 
 /* Convert between RAW and VIRTUAL registers.  The RAW register size
@@ -660,20 +774,20 @@ mips_value_to_register (struct frame_info *frame, int regnum,
   put_frame_register (frame, regnum + 1, (const char *) from + 0);
 }
 
-/* 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)
-{
-  if (FP0_REGNUM <= reg && reg < FP0_REGNUM + 32)
+mips_register_type (struct gdbarch *gdbarch, int regnum)
+{
+  /* For moment, map [NUM_REGS .. 2*NUM_REGS) onto the same raw
+     registers.  Even return the same type.  */
+  int rawnum = regnum % NUM_REGS;
+  gdb_assert (rawnum >= 0 && rawnum < NUM_REGS);
+#ifdef MIPS_REGISTER_TYPE
+  return MIPS_REGISTER_TYPE (rawnum);
+#else
+  if (FP0_REGNUM <= rawnum && rawnum < FP0_REGNUM + 32)
     {
       /* Floating point registers...  */
       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
@@ -681,9 +795,9 @@ mips_register_virtual_type (int reg)
       else
        return builtin_type_ieee_double_little;
     }
-  else if (reg == PS_REGNUM /* CR */)
+  else if (rawnum == PS_REGNUM /* CR */)
     return builtin_type_uint32;
-  else if (FCRCS_REGNUM <= reg && reg <= LAST_EMBED_REGNUM)
+  else if (FCRCS_REGNUM <= rawnum && rawnum <= LAST_EMBED_REGNUM)
     return builtin_type_uint32;
   else
     {
@@ -694,6 +808,7 @@ mips_register_virtual_type (int reg)
       else
        return builtin_type_uint32;
     }
+#endif
 }
 
 /* TARGET_READ_SP -- Remove useless bits from the stack pointer.  */
@@ -1658,37 +1773,23 @@ mips_find_saved_regs (struct frame_info *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  */
@@ -1778,23 +1879,29 @@ 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);
+      /* Always unwind the cooked PC register value.  */
+      frame_unwind_signed_register (frame, NUM_REGS + PC_REGNUM, &tmp);
       saved_pc = tmp;
     }
-  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);
 }
 
@@ -1810,13 +1917,22 @@ 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.  */
+   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 (CORE_ADDR *saved_regs, int regno, CORE_ADDR offset)
 {
   if (saved_regs[regno] == 0)
-    saved_regs[regno] = offset;
+    {
+      saved_regs[regno + 0 * NUM_REGS] = offset;
+      saved_regs[regno + 1 * NUM_REGS] = offset;
+    }
 }
 
 
@@ -2168,7 +2284,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)
                {
@@ -2191,7 +2307,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)
                {
@@ -2219,7 +2335,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;
 
@@ -2492,7 +2608,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));
 }
@@ -2578,7 +2694,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
@@ -4089,10 +4205,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;
@@ -4121,8 +4238,7 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
   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);
 }
 
@@ -4144,39 +4260,43 @@ 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 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",
                        REGISTER_NAME (regnum));
       col++;
     }
+  /* print the R0 to R31 names */
   fprintf_filtered (file,
-                   start_regnum < MIPS_NUMREGS ? "\n R%-4d" : "\n      ",
-                   start_regnum);      /* print the R0 to R31 names */
+                   (start_regnum % NUM_REGS) < MIPS_NUMREGS
+                   ? "\n R%-4d" : "\n      ",
+                   start_regnum);
 
-  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))
@@ -4212,6 +4332,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");
 
@@ -4221,10 +4342,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);
@@ -4711,30 +4832,30 @@ mips_o32_xfer_return_value (struct type *type,
          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),
+      mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM, TYPE_LENGTH (type),
                          TARGET_BYTE_ORDER, in, out, 0);
     }
   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,
+         mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 0, 4,
                              TARGET_BYTE_ORDER, in, out, 0);
-         mips_xfer_register (regcache, FP0_REGNUM + 1, 4,
+         mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 1, 4,
                              TARGET_BYTE_ORDER, in, out, 4);
          break;
        case BFD_ENDIAN_BIG:
-         mips_xfer_register (regcache, FP0_REGNUM + 1, 4,
+         mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 1, 4,
                              TARGET_BYTE_ORDER, in, out, 0);
-         mips_xfer_register (regcache, FP0_REGNUM + 0, 4,
+         mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM + 0, 4,
                              TARGET_BYTE_ORDER, in, out, 4);
          break;
        default:
@@ -4769,7 +4890,8 @@ 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)),
+         mips_xfer_register (regcache, NUM_REGS + regnum,
+                             TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
                              TARGET_BYTE_ORDER, in, out, offset);
        }
     }
@@ -4793,8 +4915,8 @@ mips_o32_xfer_return_value (struct type *type,
          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, in, out, offset);
        }
     }
 #endif
@@ -4816,8 +4938,8 @@ 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, in, out, offset);
        }
     }
 }
@@ -4851,7 +4973,7 @@ mips_n32n64_xfer_return_value (struct type *type,
          of FP0.  */
       if (mips_debug)
        fprintf_unfiltered (gdb_stderr, "Return float in $fp0\n");
-      mips_xfer_register (regcache, FP0_REGNUM, TYPE_LENGTH (type),
+      mips_xfer_register (regcache, NUM_REGS + FP0_REGNUM, TYPE_LENGTH (type),
                          TARGET_BYTE_ORDER, in, out, 0);
     }
   else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
@@ -4881,7 +5003,8 @@ 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)),
+         mips_xfer_register (regcache, NUM_REGS + regnum,
+                             TYPE_LENGTH (TYPE_FIELD_TYPE (type, field)),
                              TARGET_BYTE_ORDER, in, out, offset);
        }
     }
@@ -4903,8 +5026,8 @@ mips_n32n64_xfer_return_value (struct type *type,
          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, in, out, offset);
        }
     }
   else
@@ -4924,8 +5047,8 @@ mips_n32n64_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, in, out, offset);
        }
     }
 }
@@ -5448,8 +5571,8 @@ mips_get_saved_register (char *raw_buffer,
   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)
@@ -5458,28 +5581,20 @@ mips_get_saved_register (char *raw_buffer,
     lvalp = &lvalx;
   if (optimizedp == NULL)
     optimizedp = &optimizedx;
-  frame_register_unwind (deprecated_get_next_frame_hack (frame),
-                        regnum, optimizedp, lvalp, addrp,
-                        &realnumx, raw_buffer);
-
-  /* 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.
@@ -5494,48 +5609,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 + FP0_REGNUM - 38;
   else if (num == 70)
-    return HI_REGNUM;
+    regnum = HI_REGNUM;
   else if (num == 71)
-    return LO_REGNUM;
+    regnum = LO_REGNUM;
   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 + FP0_REGNUM - 32;
   else if (num == 64)
-    return HI_REGNUM;
+    regnum = HI_REGNUM;
   else if (num == 65)
-    return LO_REGNUM;
+    regnum = LO_REGNUM;
   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;    
 }
 
 
@@ -5602,6 +5733,7 @@ mips_gdbarch_init (struct gdbarch_info info,
   struct gdbarch_tdep *tdep;
   int elf_flags;
   enum mips_abi mips_abi, found_abi, wanted_abi;
+  int num_regs;
 
   /* Reset the disassembly info, in case it was set to something
      non-default.  */
@@ -5755,16 +5887,23 @@ mips_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_double_bit (gdbarch, 64);
   set_gdbarch_long_double_bit (gdbarch, 64);
   set_gdbarch_deprecated_register_raw_size (gdbarch, mips_register_raw_size);
+  set_gdbarch_deprecated_register_byte (gdbarch, mips_register_byte);
+  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);
+    num_regs = 71;
   else
-    set_gdbarch_num_regs (gdbarch, 90);
+    num_regs = 90;
+  set_gdbarch_num_regs (gdbarch, num_regs);
+  set_gdbarch_num_pseudo_regs (gdbarch, num_regs);
 
   switch (mips_abi)
     {
@@ -5956,6 +6095,7 @@ mips_gdbarch_init (struct gdbarch_info info,
   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_find_saved_regs);
@@ -5992,9 +6132,7 @@ 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_deprecated_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);