2003-06-14 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index 04db9378e1f54c2392cd0e8985a5b643b59179c6..dd0b176fe83ea7f9bcb42f4145f6ce084331519b 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "defs.h"
 #include "gdb_string.h"
+#include "gdb_assert.h"
 #include "frame.h"
 #include "inferior.h"
 #include "symtab.h"
 #include "regcache.h"
 #include "osabi.h"
 #include "mips-tdep.h"
+#include "block.h"
 
 #include "opcode/mips.h"
 #include "elf/mips.h"
 #include "elf-bfd.h"
 #include "symcat.h"
 
+static void set_reg_offset (CORE_ADDR *saved_regs, int regnum, CORE_ADDR off);
+
 /* 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.  */
 #define ST0_FR (1 << 26)
@@ -148,6 +152,57 @@ 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));
+  deprecated_read_register_gen (regnum, buf);
+  return (extract_signed_integer (buf, REGISTER_RAW_SIZE (regnum)));
+}
+
+static LONGEST
+read_signed_register_pid (int regnum, ptid_t ptid)
+{
+  ptid_t save_ptid;
+  LONGEST retval;
+
+  if (ptid_equal (ptid, inferior_ptid))
+    return read_signed_register (regnum);
+
+  save_ptid = inferior_ptid;
+
+  inferior_ptid = ptid;
+
+  retval = read_signed_register (regnum);
+
+  inferior_ptid = save_ptid;
+
+  return retval;
+}
+
 /* Return the MIPS ABI associated with GDBARCH.  */
 enum mips_abi
 mips_abi (struct gdbarch *gdbarch)
@@ -213,7 +268,7 @@ mips_xfer_register (struct regcache *regcache, int reg_num, int length,
                    enum bfd_endian endian, bfd_byte *in, const bfd_byte *out,
                    int buf_offset)
 {
-  bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE);
+  bfd_byte reg[MAX_REGISTER_SIZE];
   int reg_offset = 0;
   /* Need to transfer the left or right part of the register, based on
      the targets byte order.  */
@@ -318,8 +373,6 @@ mips_stack_argsize (void)
 
 int gdb_print_insn_mips (bfd_vma, disassemble_info *);
 
-static void mips_print_register (int, int);
-
 static mips_extra_func_info_t heuristic_proc_desc (CORE_ADDR, CORE_ADDR,
                                                   struct frame_info *, int);
 
@@ -340,9 +393,6 @@ static mips_extra_func_info_t find_proc_desc (CORE_ADDR pc,
 static CORE_ADDR after_prologue (CORE_ADDR pc,
                                 mips_extra_func_info_t proc_desc);
 
-static void mips_read_fp_register_single (int regno, char *rare_buffer);
-static void mips_read_fp_register_double (int regno, char *rare_buffer);
-
 static struct type *mips_float_register_type (void);
 static struct type *mips_double_register_type (void);
 
@@ -360,23 +410,57 @@ 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;
 
-char *mips_generic_reg_names[] = MIPS_REGISTER_NAMES;
-char **mips_processor_reg_names = mips_generic_reg_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;
 
+/* Return the name of the register corresponding to REGNO.  */
 static const char *
-mips_register_name (int i)
-{
-  return mips_processor_reg_names[i];
+mips_register_name (int regno)
+{
+  /* GPR names for all ABIs other than n32/n64.  */
+  static char *mips_gpr_names[] = {
+    "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
+    "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
+    "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
+    "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra",
+  };
+
+  /* GPR names for n32 and n64 ABIs.  */
+  static char *mips_n32_n64_gpr_names[] = {
+    "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3", 
+    "a4",   "a5",   "a6",   "a7",   "t0",   "t1",   "t2",   "t3", 
+    "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7", 
+    "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra"
+  };
+
+  enum mips_abi abi = mips_abi (current_gdbarch);
+
+  /* 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 (abi == MIPS_ABI_N32 || abi == MIPS_ABI_N64)
+       return mips_n32_n64_gpr_names[regno];
+      else
+       return mips_gpr_names[regno];
+    }
+  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);
 }
+
 /* *INDENT-OFF* */
 /* Names of IDT R3041 registers.  */
 
 char *mips_r3041_reg_names[] = {
-       "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
-       "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
-       "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
-       "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra",
        "sr",   "lo",   "hi",   "bad",  "cause","pc",
        "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
        "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
@@ -390,10 +474,6 @@ char *mips_r3041_reg_names[] = {
 /* Names of IDT R3051 registers.  */
 
 char *mips_r3051_reg_names[] = {
-       "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
-       "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
-       "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
-       "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra",
        "sr",   "lo",   "hi",   "bad",  "cause","pc",
        "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
        "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
@@ -407,10 +487,6 @@ char *mips_r3051_reg_names[] = {
 /* Names of IDT R3081 registers.  */
 
 char *mips_r3081_reg_names[] = {
-       "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
-       "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
-       "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
-       "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra",
        "sr",   "lo",   "hi",   "bad",  "cause","pc",
        "f0",   "f1",   "f2",   "f3",   "f4",   "f5",   "f6",   "f7",
        "f8",   "f9",   "f10",  "f11",  "f12",  "f13",  "f14",  "f15",
@@ -424,10 +500,6 @@ char *mips_r3081_reg_names[] = {
 /* Names of LSI 33k registers.  */
 
 char *mips_lsi33k_reg_names[] = {
-       "zero", "at",   "v0",   "v1",   "a0",   "a1",   "a2",   "a3",
-       "t0",   "t1",   "t2",   "t3",   "t4",   "t5",   "t6",   "t7",
-       "s0",   "s1",   "s2",   "s3",   "s4",   "s5",   "s6",   "s7",
-       "t8",   "t9",   "k0",   "k1",   "gp",   "sp",   "s8",   "ra",
        "epc",  "hi",   "lo",   "sr",   "cause","badvaddr",
        "dcic", "bpc",  "bda",  "",     "",     "",     "",      "",
        "",     "",     "",     "",     "",     "",     "",      "",
@@ -549,7 +621,7 @@ mips_register_convert_to_virtual (int n, struct type *virtual_type,
 
 static void
 mips_register_convert_to_raw (struct type *virtual_type, int n,
-                             char *virt_buf, char *raw_buf)
+                             const char *virt_buf, char *raw_buf)
 {
   memset (raw_buf, 0, REGISTER_RAW_SIZE (n));
   if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
@@ -562,36 +634,30 @@ mips_register_convert_to_raw (struct type *virtual_type, int n,
            TYPE_LENGTH (virtual_type));
 }
 
+static int
+mips_convert_register_p (int regnum, struct type *type)
+{
+  return (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);
+}
+
 void
-mips_register_convert_to_type (int regnum, struct type *type, char *buffer)
+mips_register_to_value (struct frame_info *frame, int regnum,
+                       struct type *type, void *to)
 {
-  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); 
-    }
+  frame_read_register (frame, regnum + 0, (char *) to + 4);
+  frame_read_register (frame, regnum + 1, (char *) to + 0);
 }
 
 void
-mips_register_convert_from_type (int regnum, struct type *type, char *buffer)
+mips_value_to_register (struct frame_info *frame, int regnum,
+                       struct type *type, const void *from)
 {
-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);
-  }
+  put_frame_register (frame, regnum + 0, (const char *) from + 4);
+  put_frame_register (frame, regnum + 1, (const char *) from + 0);
 }
 
 /* Return the GDB type object for the "standard" data type
@@ -599,9 +665,9 @@ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
    
    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 FP_REGNUM is in this range, and I doubt
+   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.  */
 
 static struct type *
@@ -635,7 +701,7 @@ mips_register_virtual_type (int reg)
 static CORE_ADDR
 mips_read_sp (void)
 {
-  return ADDR_BITS_REMOVE (read_register (SP_REGNUM));
+  return read_signed_register (SP_REGNUM);
 }
 
 /* Should the upper word of 64-bit addresses be zeroed? */
@@ -696,12 +762,6 @@ 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.  */
@@ -738,7 +798,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
@@ -871,7 +931,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;
@@ -1374,38 +1434,37 @@ 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 (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.  */
+  /* To satisfy alignment restrictions, sigcontext is located 4 bytes
+     above the sigtramp frame.  */
 #define SIGFRAME_BASE          MIPS_REGSIZE
 /* FIXME!  Are these correct?? */
 #define SIGFRAME_PC_OFF                (SIGFRAME_BASE + 2 * MIPS_REGSIZE)
@@ -1414,61 +1473,65 @@ mips_find_saved_regs (struct frame_info *fci)
         (SIGFRAME_REGSAVE_OFF + MIPS_NUMREGS * MIPS_REGSIZE + 3 * MIPS_REGSIZE)
 #endif
 #ifndef SIGFRAME_REG_SIZE
-/* FIXME!  Is this correct?? */
+  /* FIXME!  Is this correct?? */
 #define SIGFRAME_REG_SIZE      MIPS_REGSIZE
 #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 * SIGFRAME_REG_SIZE);
+         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 * SIGFRAME_REG_SIZE);
+         set_reg_offset (saved_regs, FP0_REGNUM + 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;
 
@@ -1481,8 +1544,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);
@@ -1496,89 +1559,84 @@ 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);
+  /* 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));
 
-  /* Apparently, the freg_offset gives the offset to the first 64 bit
-     saved.
+    /* 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 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.  */
+       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;
+    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;
-      }
-
-  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)
+       {
+         set_reg_offset (saved_regs, FP0_REGNUM + 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
@@ -1588,21 +1646,29 @@ read_next_frame_reg (struct frame_info *fi, int regno)
   CORE_ADDR addr;
   int realnum;
   enum lval_type lval;
-  void *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
-  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)
+  char raw_buffer[MAX_REGISTER_SIZE];
+
+  if (fi == NULL)
+    {
+      regcache_cooked_read (current_regcache, regno, raw_buffer);
+    }
+  else
     {
-      if (regno < 32)
+      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)
        {
-         /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
-            saved. */
-         return read_memory_integer (addr, MIPS_SAVED_REGSIZE);
+         if (regno < 32)
+           {
+             /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
+                saved. */
+             return read_memory_integer (addr, MIPS_SAVED_REGSIZE);
+           }
        }
     }
 
@@ -1683,9 +1749,9 @@ mips_init_frame_pc_first (int fromleaf, struct frame_info *prev)
   CORE_ADDR pc, tmp;
 
   pc = ((fromleaf)
-       ? SAVED_PC_AFTER_CALL (get_next_frame (prev))
+       ? DEPRECATED_SAVED_PC_AFTER_CALL (get_next_frame (prev))
        : get_next_frame (prev)
-       ? FRAME_SAVED_PC (get_next_frame (prev))
+       ? DEPRECATED_FRAME_SAVED_PC (get_next_frame (prev))
        : read_pc ());
   tmp = SKIP_TRAMPOLINE_CODE (pc);
   return tmp ? tmp : pc;
@@ -1725,16 +1791,16 @@ 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.  */
 
 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] = offset;
 }
 
 
@@ -1786,10 +1852,10 @@ heuristic_proc_start (CORE_ADDR pc)
     if (start_pc < fence)
       {
        /* It's not clear to me why we reach this point when
-          stop_soon_quietly, but with this test, at least we
+          stop_soon, but with this test, at least we
           don't print out warnings for every child forked (eg, on
           decstation).  22apr93 rich@cygnus.com.  */
-       if (!stop_soon_quietly)
+       if (stop_soon == NO_STOP_QUIETLY)
          {
            static int blurb_printed = 0;
 
@@ -1930,26 +1996,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 */
        {
@@ -1968,14 +2034,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 */
@@ -2005,7 +2071,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;
        }
 
@@ -2014,7 +2080,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;
        }
 
@@ -2022,7 +2088,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;
        }
     }
@@ -2067,7 +2133,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) */
        {
@@ -2075,7 +2141,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);
        }
       else if (high_word == 0x27be)    /* addiu $30,$sp,size */
        {
@@ -2125,7 +2191,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);
        }
     }
 }
@@ -2327,7 +2393,7 @@ non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr)
       return NULL;
     }
 
-  sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_NAMESPACE, 0, NULL);
+  sym = lookup_symbol (MIPS_EFI_SYMBOL_NAME, b, LABEL_DOMAIN, 0, NULL);
 
   /* If we never found a PDR for this function in symbol reading, then
      examine prologues to find the information.  */
@@ -2410,10 +2476,9 @@ static CORE_ADDR
 get_frame_pointer (struct frame_info *frame,
                   mips_extra_func_info_t proc_desc)
 {
-  return ADDR_BITS_REMOVE (read_next_frame_reg (frame, 
-                                               PROC_FRAME_REG (proc_desc)) +
-                          PROC_FRAME_OFFSET (proc_desc) - 
-                          PROC_FRAME_ADJUST (proc_desc));
+  return (read_next_frame_reg (frame, PROC_FRAME_REG (proc_desc))
+         + PROC_FRAME_OFFSET (proc_desc)
+         - PROC_FRAME_ADJUST (proc_desc));
 }
 
 static mips_extra_func_info_t cached_proc_desc;
@@ -2423,7 +2488,7 @@ mips_frame_chain (struct frame_info *frame)
 {
   mips_extra_func_info_t proc_desc;
   CORE_ADDR tmp;
-  CORE_ADDR saved_pc = FRAME_SAVED_PC (frame);
+  CORE_ADDR saved_pc = DEPRECATED_FRAME_SAVED_PC (frame);
 
   if (saved_pc == 0 || inside_entry_file (saved_pc))
     return 0;
@@ -2468,12 +2533,21 @@ static void
 mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
 {
   int regnum;
+  mips_extra_func_info_t proc_desc;
 
-  /* Use proc_desc calculated in frame_chain */
-  mips_extra_func_info_t proc_desc =
+  if (get_frame_type (fci) == DUMMY_FRAME)
+    return;
+
+  /* Use proc_desc calculated in frame_chain.  When there is no
+     next frame, i.e, get_next_frame (fci) == NULL, we call
+     find_proc_desc () to calculate it, passing an explicit
+     NULL as the frame parameter.  */
+  proc_desc =
     get_next_frame (fci)
     ? cached_proc_desc
-    : find_proc_desc (get_frame_pc (fci), get_next_frame (fci), 1);
+    : find_proc_desc (get_frame_pc (fci),
+                      NULL /* i.e, get_next_frame (fci) */,
+                     1);
 
   frame_extra_info_zalloc (fci, sizeof (struct frame_extra_info));
 
@@ -2516,15 +2590,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 (get_frame_saved_regs (fci), temp_saved_regs,
+                     SIZEOF_FRAME_SAVED_REGS);
            }
        }
 
@@ -2627,11 +2704,10 @@ mips_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
 }
 
 static CORE_ADDR
-mips_eabi_push_arguments (int nargs,
-                         struct value **args,
-                         CORE_ADDR sp,
-                         int struct_return,
-                         CORE_ADDR struct_addr)
+mips_eabi_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+                          struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+                          struct value **args, CORE_ADDR sp, int struct_return,
+                          CORE_ADDR struct_addr)
 {
   int argreg;
   int float_argreg;
@@ -2639,6 +2715,14 @@ mips_eabi_push_arguments (int nargs,
   int len = 0;
   int stack_offset = 0;
 
+  /* For shared libraries, "t9" needs to point at the function
+     address.  */
+  regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr);
+
+  /* Set the return address register to point to the entry point of
+     the program, where a breakpoint lies in wait.  */
+  regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr);
+
   /* First ensure that the stack and structure return address (if any)
      are properly aligned.  The stack has to be at least 64-bit
      aligned even on 32-bit machines, because doubles must be 64-bit
@@ -2658,7 +2742,7 @@ mips_eabi_push_arguments (int nargs,
 
   if (mips_debug)
     fprintf_unfiltered (gdb_stdlog, 
-                       "mips_eabi_push_arguments: sp=0x%s allocated %d\n",
+                       "mips_eabi_push_dummy_call: sp=0x%s allocated %d\n",
                        paddr_nz (sp), ROUND_UP (len, 16));
 
   /* Initialize the integer and float register pointers.  */
@@ -2670,7 +2754,7 @@ mips_eabi_push_arguments (int nargs,
     {
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog,
-                           "mips_eabi_push_arguments: struct_return reg=%d 0x%s\n",
+                           "mips_eabi_push_dummy_call: struct_return reg=%d 0x%s\n",
                            argreg, paddr_nz (struct_addr));
       write_register (argreg++, struct_addr);
     }
@@ -2681,7 +2765,7 @@ mips_eabi_push_arguments (int nargs,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       char *val;
-      char *valbuf = alloca (MAX_REGISTER_RAW_SIZE);
+      char valbuf[MAX_REGISTER_SIZE];
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (VALUE_TYPE (arg));
       int len = TYPE_LENGTH (arg_type);
@@ -2689,7 +2773,7 @@ mips_eabi_push_arguments (int nargs,
 
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog,
-                           "mips_eabi_push_arguments: %d len=%d type=%d",
+                           "mips_eabi_push_dummy_call: %d len=%d type=%d",
                            argnum + 1, len, (int) typecode);
 
       /* The EABI passes structures that do not fit in a register by
@@ -2697,7 +2781,7 @@ mips_eabi_push_arguments (int nargs,
       if (len > MIPS_SAVED_REGSIZE
          && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
        {
-         store_address (valbuf, MIPS_SAVED_REGSIZE, VALUE_ADDRESS (arg));
+         store_unsigned_integer (valbuf, MIPS_SAVED_REGSIZE, VALUE_ADDRESS (arg));
          typecode = TYPE_CODE_PTR;
          len = MIPS_SAVED_REGSIZE;
          val = valbuf;
@@ -2873,18 +2957,19 @@ mips_eabi_push_arguments (int nargs,
        fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
+  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+
   /* Return adjusted stack pointer.  */
   return sp;
 }
 
-/* N32/N64 version of push_arguments.  */
+/* N32/N64 version of push_dummy_call.  */
 
 static CORE_ADDR
-mips_n32n64_push_arguments (int nargs,
-                           struct value **args,
-                           CORE_ADDR sp,
-                           int struct_return,
-                           CORE_ADDR struct_addr)
+mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+                            struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+                            struct value **args, CORE_ADDR sp, int struct_return,
+                            CORE_ADDR struct_addr)
 {
   int argreg;
   int float_argreg;
@@ -2892,6 +2977,14 @@ mips_n32n64_push_arguments (int nargs,
   int len = 0;
   int stack_offset = 0;
 
+  /* For shared libraries, "t9" needs to point at the function
+     address.  */
+  regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr);
+
+  /* Set the return address register to point to the entry point of
+     the program, where a breakpoint lies in wait.  */
+  regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr);
+
   /* First ensure that the stack and structure return address (if any)
      are properly aligned.  The stack has to be at least 64-bit
      aligned even on 32-bit machines, because doubles must be 64-bit
@@ -2909,7 +3002,7 @@ mips_n32n64_push_arguments (int nargs,
 
   if (mips_debug)
     fprintf_unfiltered (gdb_stdlog, 
-                       "mips_n32n64_push_arguments: sp=0x%s allocated %d\n",
+                       "mips_n32n64_push_dummy_call: sp=0x%s allocated %d\n",
                        paddr_nz (sp), ROUND_UP (len, 16));
 
   /* Initialize the integer and float register pointers.  */
@@ -2921,7 +3014,7 @@ mips_n32n64_push_arguments (int nargs,
     {
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog,
-                           "mips_n32n64_push_arguments: struct_return reg=%d 0x%s\n",
+                           "mips_n32n64_push_dummy_call: struct_return reg=%d 0x%s\n",
                            argreg, paddr_nz (struct_addr));
       write_register (argreg++, struct_addr);
     }
@@ -2932,7 +3025,7 @@ mips_n32n64_push_arguments (int nargs,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       char *val;
-      char *valbuf = alloca (MAX_REGISTER_RAW_SIZE);
+      char valbuf[MAX_REGISTER_SIZE];
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (VALUE_TYPE (arg));
       int len = TYPE_LENGTH (arg_type);
@@ -2940,7 +3033,7 @@ mips_n32n64_push_arguments (int nargs,
 
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog,
-                           "mips_n32n64_push_arguments: %d len=%d type=%d",
+                           "mips_n32n64_push_dummy_call: %d len=%d type=%d",
                            argnum + 1, len, (int) typecode);
 
       val = (char *) VALUE_CONTENTS (arg);
@@ -3095,18 +3188,19 @@ mips_n32n64_push_arguments (int nargs,
        fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
+  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+
   /* Return adjusted stack pointer.  */
   return sp;
 }
 
-/* O32 version of push_arguments.  */
+/* O32 version of push_dummy_call.  */
 
 static CORE_ADDR
-mips_o32_push_arguments (int nargs,
-                        struct value **args,
-                        CORE_ADDR sp,
-                        int struct_return,
-                        CORE_ADDR struct_addr)
+mips_o32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+                         struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+                         struct value **args, CORE_ADDR sp, int struct_return,
+                         CORE_ADDR struct_addr)
 {
   int argreg;
   int float_argreg;
@@ -3114,6 +3208,14 @@ mips_o32_push_arguments (int nargs,
   int len = 0;
   int stack_offset = 0;
 
+  /* For shared libraries, "t9" needs to point at the function
+     address.  */
+  regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr);
+
+  /* Set the return address register to point to the entry point of
+     the program, where a breakpoint lies in wait.  */
+  regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr);
+
   /* First ensure that the stack and structure return address (if any)
      are properly aligned.  The stack has to be at least 64-bit
      aligned even on 32-bit machines, because doubles must be 64-bit
@@ -3131,7 +3233,7 @@ mips_o32_push_arguments (int nargs,
 
   if (mips_debug)
     fprintf_unfiltered (gdb_stdlog, 
-                       "mips_o32_push_arguments: sp=0x%s allocated %d\n",
+                       "mips_o32_push_dummy_call: sp=0x%s allocated %d\n",
                        paddr_nz (sp), ROUND_UP (len, 16));
 
   /* Initialize the integer and float register pointers.  */
@@ -3143,7 +3245,7 @@ mips_o32_push_arguments (int nargs,
     {
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog,
-                           "mips_o32_push_arguments: struct_return reg=%d 0x%s\n",
+                           "mips_o32_push_dummy_call: struct_return reg=%d 0x%s\n",
                            argreg, paddr_nz (struct_addr));
       write_register (argreg++, struct_addr);
       stack_offset += MIPS_STACK_ARGSIZE;
@@ -3155,7 +3257,7 @@ mips_o32_push_arguments (int nargs,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       char *val;
-      char *valbuf = alloca (MAX_REGISTER_RAW_SIZE);
+      char valbuf[MAX_REGISTER_SIZE];
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (VALUE_TYPE (arg));
       int len = TYPE_LENGTH (arg_type);
@@ -3163,7 +3265,7 @@ mips_o32_push_arguments (int nargs,
 
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog,
-                           "mips_o32_push_arguments: %d len=%d type=%d",
+                           "mips_o32_push_dummy_call: %d len=%d type=%d",
                            argnum + 1, len, (int) typecode);
 
       val = (char *) VALUE_CONTENTS (arg);
@@ -3394,18 +3496,19 @@ mips_o32_push_arguments (int nargs,
        fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
+  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
+
   /* Return adjusted stack pointer.  */
   return sp;
 }
 
-/* O64 version of push_arguments.  */
+/* O64 version of push_dummy_call.  */
 
 static CORE_ADDR
-mips_o64_push_arguments (int nargs,
-                        struct value **args,
-                        CORE_ADDR sp,
-                        int struct_return,
-                        CORE_ADDR struct_addr)
+mips_o64_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
+                         struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+                         struct value **args, CORE_ADDR sp, int struct_return,
+                         CORE_ADDR struct_addr)
 {
   int argreg;
   int float_argreg;
@@ -3413,6 +3516,14 @@ mips_o64_push_arguments (int nargs,
   int len = 0;
   int stack_offset = 0;
 
+  /* For shared libraries, "t9" needs to point at the function
+     address.  */
+  regcache_cooked_write_signed (regcache, T9_REGNUM, func_addr);
+
+  /* Set the return address register to point to the entry point of
+     the program, where a breakpoint lies in wait.  */
+  regcache_cooked_write_signed (regcache, RA_REGNUM, bp_addr);
+
   /* First ensure that the stack and structure return address (if any)
      are properly aligned.  The stack has to be at least 64-bit
      aligned even on 32-bit machines, because doubles must be 64-bit
@@ -3430,7 +3541,7 @@ mips_o64_push_arguments (int nargs,
 
   if (mips_debug)
     fprintf_unfiltered (gdb_stdlog, 
-                       "mips_o64_push_arguments: sp=0x%s allocated %d\n",
+                       "mips_o64_push_dummy_call: sp=0x%s allocated %d\n",
                        paddr_nz (sp), ROUND_UP (len, 16));
 
   /* Initialize the integer and float register pointers.  */
@@ -3442,7 +3553,7 @@ mips_o64_push_arguments (int nargs,
     {
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog,
-                           "mips_o64_push_arguments: struct_return reg=%d 0x%s\n",
+                           "mips_o64_push_dummy_call: struct_return reg=%d 0x%s\n",
                            argreg, paddr_nz (struct_addr));
       write_register (argreg++, struct_addr);
       stack_offset += MIPS_STACK_ARGSIZE;
@@ -3454,7 +3565,7 @@ mips_o64_push_arguments (int nargs,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       char *val;
-      char *valbuf = alloca (MAX_REGISTER_RAW_SIZE);
+      char valbuf[MAX_REGISTER_SIZE];
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (VALUE_TYPE (arg));
       int len = TYPE_LENGTH (arg_type);
@@ -3462,7 +3573,7 @@ mips_o64_push_arguments (int nargs,
 
       if (mips_debug)
        fprintf_unfiltered (gdb_stdlog,
-                           "mips_o64_push_arguments: %d len=%d type=%d",
+                           "mips_o64_push_dummy_call: %d len=%d type=%d",
                            argnum + 1, len, (int) typecode);
 
       val = (char *) VALUE_CONTENTS (arg);
@@ -3693,131 +3804,19 @@ mips_o64_push_arguments (int nargs,
        fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
-  /* Return adjusted stack pointer.  */
-  return sp;
-}
+  regcache_cooked_write_signed (regcache, SP_REGNUM, sp);
 
-static CORE_ADDR
-mips_push_return_address (CORE_ADDR pc, CORE_ADDR sp)
-{
-  /* Set the return address register to point to the entry
-     point of the program, where a breakpoint lies in wait.  */
-  write_register (RA_REGNUM, CALL_DUMMY_ADDRESS ());
+  /* Return adjusted stack pointer.  */
   return sp;
 }
 
-static void
-mips_push_register (CORE_ADDR * sp, int regno)
-{
-  char *buffer = alloca (MAX_REGISTER_RAW_SIZE);
-  int regsize;
-  int offset;
-  if (MIPS_SAVED_REGSIZE < REGISTER_RAW_SIZE (regno))
-    {
-      regsize = MIPS_SAVED_REGSIZE;
-      offset = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
-               ? REGISTER_RAW_SIZE (regno) - MIPS_SAVED_REGSIZE
-               : 0);
-    }
-  else
-    {
-      regsize = REGISTER_RAW_SIZE (regno);
-      offset = 0;
-    }
-  *sp -= regsize;
-  deprecated_read_register_gen (regno, buffer);
-  write_memory (*sp, buffer + offset, regsize);
-}
-
-/* MASK(i,j) == (1<<i) + (1<<(i+1)) + ... + (1<<j)). Assume i<=j<(MIPS_NUMREGS-1). */
-#define MASK(i,j) (((1 << ((j)+1))-1) ^ ((1 << (i))-1))
-
-static void
-mips_push_dummy_frame (void)
-{
-  int ireg;
-  struct linked_proc_info *link = (struct linked_proc_info *)
-  xmalloc (sizeof (struct linked_proc_info));
-  mips_extra_func_info_t proc_desc = &link->info;
-  CORE_ADDR sp = ADDR_BITS_REMOVE (read_signed_register (SP_REGNUM));
-  CORE_ADDR old_sp = sp;
-  link->next = linked_proc_desc_table;
-  linked_proc_desc_table = link;
-
-/* FIXME!   are these correct ? */
-#define PUSH_FP_REGNUM 16      /* must be a register preserved across calls */
-#define GEN_REG_SAVE_MASK MASK(1,16)|MASK(24,28)|(1<<(MIPS_NUMREGS-1))
-#define FLOAT_REG_SAVE_MASK MASK(0,19)
-#define FLOAT_SINGLE_REG_SAVE_MASK \
-  ((1<<18)|(1<<16)|(1<<14)|(1<<12)|(1<<10)|(1<<8)|(1<<6)|(1<<4)|(1<<2)|(1<<0))
-  /*
-   * The registers we must save are all those not preserved across
-   * procedure calls. Dest_Reg (see tm-mips.h) must also be saved.
-   * In addition, we must save the PC, PUSH_FP_REGNUM, MMLO/-HI
-   * and FP Control/Status registers.
-   *
-   *
-   * Dummy frame layout:
-   *  (high memory)
-   *    Saved PC
-   *    Saved MMHI, MMLO, FPC_CSR
-   *    Saved R31
-   *    Saved R28
-   *    ...
-   *    Saved R1
-   *    Saved D18 (i.e. F19, F18)
-   *    ...
-   *    Saved D0 (i.e. F1, F0)
-   *    Argument build area and stack arguments written via mips_push_arguments
-   *  (low memory)
-   */
-
-  /* Save special registers (PC, MMHI, MMLO, FPC_CSR) */
-  PROC_FRAME_REG (proc_desc) = PUSH_FP_REGNUM;
-  PROC_FRAME_OFFSET (proc_desc) = 0;
-  PROC_FRAME_ADJUST (proc_desc) = 0;
-  mips_push_register (&sp, PC_REGNUM);
-  mips_push_register (&sp, HI_REGNUM);
-  mips_push_register (&sp, LO_REGNUM);
-  mips_push_register (&sp, MIPS_FPU_TYPE == MIPS_FPU_NONE ? 0 : FCRCS_REGNUM);
-
-  /* Save general CPU registers */
-  PROC_REG_MASK (proc_desc) = GEN_REG_SAVE_MASK;
-  /* PROC_REG_OFFSET is the offset of the first saved register from FP.  */
-  PROC_REG_OFFSET (proc_desc) = sp - old_sp - MIPS_SAVED_REGSIZE;
-  for (ireg = 32; --ireg >= 0;)
-    if (PROC_REG_MASK (proc_desc) & (1 << ireg))
-      mips_push_register (&sp, ireg);
-
-  /* Save floating point registers starting with high order word */
-  PROC_FREG_MASK (proc_desc) =
-    MIPS_FPU_TYPE == MIPS_FPU_DOUBLE ? FLOAT_REG_SAVE_MASK
-    : MIPS_FPU_TYPE == MIPS_FPU_SINGLE ? FLOAT_SINGLE_REG_SAVE_MASK : 0;
-  /* PROC_FREG_OFFSET is the offset of the first saved *double* register
-     from FP.  */
-  PROC_FREG_OFFSET (proc_desc) = sp - old_sp - 8;
-  for (ireg = 32; --ireg >= 0;)
-    if (PROC_FREG_MASK (proc_desc) & (1 << ireg))
-      mips_push_register (&sp, ireg + FP0_REGNUM);
-
-  /* Update the frame pointer for the call dummy and the stack pointer.
-     Set the procedure's starting and ending addresses to point to the
-     call dummy address at the entry point.  */
-  write_register (PUSH_FP_REGNUM, old_sp);
-  write_register (SP_REGNUM, sp);
-  PROC_LOW_ADDR (proc_desc) = CALL_DUMMY_ADDRESS ();
-  PROC_HIGH_ADDR (proc_desc) = CALL_DUMMY_ADDRESS () + 4;
-  SET_PROC_DESC_IS_DUMMY (proc_desc);
-  PROC_PC_REG (proc_desc) = RA_REGNUM;
-}
-
 static void
 mips_pop_frame (void)
 {
   register int regnum;
   struct frame_info *frame = get_current_frame ();
   CORE_ADDR new_sp = get_frame_base (frame);
-  mips_extra_func_info_t proc_desc = get_frame_extra_info (frame)->proc_desc;
+  mips_extra_func_info_t proc_desc;
 
   if (DEPRECATED_PC_IN_CALL_DUMMY (get_frame_pc (frame), 0, 0))
     {
@@ -3826,9 +3825,9 @@ mips_pop_frame (void)
       return;
     }
 
-  write_register (PC_REGNUM, FRAME_SAVED_PC (frame));
-  if (get_frame_saved_regs (frame) == NULL)
-    FRAME_INIT_SAVED_REGS (frame);
+  proc_desc = get_frame_extra_info (frame)->proc_desc;
+  write_register (PC_REGNUM, DEPRECATED_FRAME_SAVED_PC (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])
@@ -3884,13 +3883,6 @@ mips_pop_frame (void)
     }
 }
 
-static void
-mips_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun, int nargs, 
-                    struct value **args, struct type *type, int gcc_p)
-{
-  write_register(T9_REGNUM, fun);
-}
-
 /* Floating point register management.
 
    Background: MIPS1 & 2 fp registers are 32 bits wide.  To support
@@ -3943,12 +3935,13 @@ mips_double_register_type (void)
    into rare_buffer.  */
 
 static void
-mips_read_fp_register_single (int regno, char *rare_buffer)
+mips_read_fp_register_single (struct frame_info *frame, int regno,
+                             char *rare_buffer)
 {
   int raw_size = REGISTER_RAW_SIZE (regno);
   char *raw_buffer = alloca (raw_size);
 
-  if (!frame_register_read (deprecated_selected_frame, regno, raw_buffer))
+  if (!frame_register_read (frame, regno, raw_buffer))
     error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
   if (raw_size == 8)
     {
@@ -3974,7 +3967,8 @@ mips_read_fp_register_single (int regno, char *rare_buffer)
    register.  */
 
 static void
-mips_read_fp_register_double (int regno, char *rare_buffer)
+mips_read_fp_register_double (struct frame_info *frame, int regno,
+                             char *rare_buffer)
 {
   int raw_size = REGISTER_RAW_SIZE (regno);
 
@@ -3982,7 +3976,7 @@ mips_read_fp_register_double (int regno, char *rare_buffer)
     {
       /* We have a 64-bit value for this register, and we should use
         all 64 bits.  */
-      if (!frame_register_read (deprecated_selected_frame, regno, rare_buffer))
+      if (!frame_register_read (frame, regno, rare_buffer))
        error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
     }
   else
@@ -3996,173 +3990,148 @@ mips_read_fp_register_double (int regno, char *rare_buffer)
         each register.  */
       if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
        {
-         mips_read_fp_register_single (regno, rare_buffer + 4);
-         mips_read_fp_register_single (regno + 1, rare_buffer);
+         mips_read_fp_register_single (frame, regno, rare_buffer + 4);
+         mips_read_fp_register_single (frame, regno + 1, rare_buffer);
        }
       else
        {
-         mips_read_fp_register_single (regno, rare_buffer);
-         mips_read_fp_register_single (regno + 1, rare_buffer + 4);
+         mips_read_fp_register_single (frame, regno, rare_buffer);
+         mips_read_fp_register_single (frame, regno + 1, rare_buffer + 4);
        }
     }
 }
 
 static void
-mips_print_register (int regnum, int all)
-{
-  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
-
-  /* Get the data in raw format.  */
-  if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
-    {
-      printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum));
-      return;
-    }
-
-  /* If we have a actual 32-bit floating point register (or we are in
-     32-bit compatibility mode), and the register is even-numbered,
-     also print it as a double (spanning two registers).  */
-  if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT
-      && (REGISTER_RAW_SIZE (regnum) == 4
-         || mips2_fp_compat ())
-      && !((regnum - FP0_REGNUM) & 1))
-    {
-      char *dbuffer = alloca (2 * MAX_REGISTER_RAW_SIZE);
-
-      mips_read_fp_register_double (regnum, dbuffer);
-
-      printf_filtered ("(d%d: ", regnum - FP0_REGNUM);
-      val_print (mips_double_register_type (), dbuffer, 0, 0,
-                gdb_stdout, 0, 1, 0, Val_pretty_default);
-      printf_filtered ("); ");
-    }
-  fputs_filtered (REGISTER_NAME (regnum), gdb_stdout);
-
-  /* The problem with printing numeric register names (r26, etc.) is that
-     the user can't use them on input.  Probably the best solution is to
-     fix it so that either the numeric or the funky (a2, etc.) names
-     are accepted on input.  */
-  if (regnum < MIPS_NUMREGS)
-    printf_filtered ("(r%d): ", regnum);
-  else
-    printf_filtered (": ");
-
-  /* If virtual format is floating, print it that way.  */
-  if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
-    if (REGISTER_RAW_SIZE (regnum) == 8 && !mips2_fp_compat ())
-      {
-       /* We have a meaningful 64-bit value in this register.  Show
-          it as a 32-bit float and a 64-bit double.  */
-       int offset = 4 * (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG);
-
-       printf_filtered (" (float) ");
-       val_print (mips_float_register_type (), raw_buffer + offset, 0, 0,
-                  gdb_stdout, 0, 1, 0, Val_pretty_default);
-       printf_filtered (", (double) ");
-       val_print (mips_double_register_type (), raw_buffer, 0, 0,
-                  gdb_stdout, 0, 1, 0, Val_pretty_default);
-      }
-    else
-      val_print (REGISTER_VIRTUAL_TYPE (regnum), raw_buffer, 0, 0,
-                gdb_stdout, 0, 1, 0, Val_pretty_default);
-  /* Else print as integer in hex.  */
-  else
-    {
-      int offset;
-
-      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
-        offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
-      else
-       offset = 0;
-
-      print_scalar_formatted (raw_buffer + offset,
-                             REGISTER_VIRTUAL_TYPE (regnum),
-                             'x', 0, gdb_stdout);
-    }
-}
-
-/* Replacement for generic do_registers_info.
-   Print regs in pretty columns.  */
-
-static int
-do_fp_register_row (int regnum)
+mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
+                       int regnum)
 {                              /* do values for FP (float) regs */
   char *raw_buffer;
   double doub, flt1, flt2;     /* doubles extracted from raw hex data */
-  int inv1, inv2, inv3;
+  int inv1, inv2, namelen;
 
   raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
 
+  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 ())
     {
-      /* 4-byte registers: we can fit two registers per row.  */
-      /* Also print every pair of 4-byte regs as an 8-byte double.  */
-      mips_read_fp_register_single (regnum, raw_buffer);
+      /* 4-byte registers: Print hex and floating.  Also print even
+         numbered registers as doubles.  */
+      mips_read_fp_register_single (frame, regnum, raw_buffer);
       flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
 
-      mips_read_fp_register_single (regnum + 1, raw_buffer);
-      flt2 = unpack_double (mips_float_register_type (), raw_buffer, &inv2);
+      print_scalar_formatted (raw_buffer, builtin_type_uint32, 'x', 'w', file);
 
-      mips_read_fp_register_double (regnum, raw_buffer);
-      doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
-
-      printf_filtered (" %-5s", REGISTER_NAME (regnum));
+      fprintf_filtered (file, " flt: ");
       if (inv1)
-       printf_filtered (": <invalid float>");
-      else
-       printf_filtered ("%-17.9g", flt1);
-
-      printf_filtered (" %-5s", REGISTER_NAME (regnum + 1));
-      if (inv2)
-       printf_filtered (": <invalid float>");
+       fprintf_filtered (file, " <invalid float> ");
       else
-       printf_filtered ("%-17.9g", flt2);
+       fprintf_filtered (file, "%-17.9g", flt1);
 
-      printf_filtered (" dbl: ");
-      if (inv3)
-       printf_filtered ("<invalid double>");
-      else
-       printf_filtered ("%-24.17g", doub);
-      printf_filtered ("\n");
+      if (regnum % 2 == 0)
+       {
+         mips_read_fp_register_double (frame, regnum, raw_buffer);
+         doub = unpack_double (mips_double_register_type (), raw_buffer,
+                               &inv2);
 
-      /* may want to do hex display here (future enhancement) */
-      regnum += 2;
+         fprintf_filtered (file, " dbl: ");
+         if (inv2)
+           fprintf_filtered (file, "<invalid double>");
+         else
+           fprintf_filtered (file, "%-24.17g", doub);
+       }
     }
   else
     {
-      /* Eight byte registers: print each one as float AND as double.  */
-      mips_read_fp_register_single (regnum, raw_buffer);
-      flt1 = unpack_double (mips_double_register_type (), raw_buffer, &inv1);
+      /* Eight byte registers: print each one as hex, float and double.  */
+      mips_read_fp_register_single (frame, regnum, raw_buffer);
+      flt1 = unpack_double (mips_float_register_type (), raw_buffer, &inv1);
 
-      mips_read_fp_register_double (regnum, raw_buffer);
-      doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
+      mips_read_fp_register_double (frame, regnum, raw_buffer);
+      doub = unpack_double (mips_double_register_type (), raw_buffer, &inv2);
 
-      printf_filtered (" %-5s: ", REGISTER_NAME (regnum));
+
+      print_scalar_formatted (raw_buffer, builtin_type_uint64, 'x', 'g', file);
+
+      fprintf_filtered (file, " flt: ");
       if (inv1)
-       printf_filtered ("<invalid float>");
+       fprintf_filtered (file, "<invalid float>");
       else
-       printf_filtered ("flt: %-17.9g", flt1);
+       fprintf_filtered (file, "%-17.9g", flt1);
 
-      printf_filtered (" dbl: ");
-      if (inv3)
-       printf_filtered ("<invalid double>");
+      fprintf_filtered (file, " dbl: ");
+      if (inv2)
+       fprintf_filtered (file, "<invalid double>");
       else
-       printf_filtered ("%-24.17g", doub);
+       fprintf_filtered (file, "%-24.17g", doub);
+    }
+}
+
+static void
+mips_print_register (struct ui_file *file, struct frame_info *frame,
+                    int regnum, int all)
+{
+  char raw_buffer[MAX_REGISTER_SIZE];
+  int offset;
 
-      printf_filtered ("\n");
-      /* may want to do hex display here (future enhancement) */
-      regnum++;
+  if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
+    {
+      mips_print_fp_register (file, frame, regnum);
+      return;
     }
-  return regnum;
+
+  /* Get the data in raw format.  */
+  if (!frame_register_read (frame, regnum, raw_buffer))
+    {
+      fprintf_filtered (file, "%s: [Invalid]", REGISTER_NAME (regnum));
+      return;
+    }
+
+  fputs_filtered (REGISTER_NAME (regnum), file);
+
+  /* The problem with printing numeric register names (r26, etc.) is that
+     the user can't use them on input.  Probably the best solution is to
+     fix it so that either the numeric or the funky (a2, etc.) names
+     are accepted on input.  */
+  if (regnum < MIPS_NUMREGS)
+    fprintf_filtered (file, "(r%d): ", regnum);
+  else
+    fprintf_filtered (file, ": ");
+
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    offset = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
+  else
+    offset = 0;
+
+  print_scalar_formatted (raw_buffer + offset,
+                         REGISTER_VIRTUAL_TYPE (regnum),
+                         'x', 0, file);
+}
+
+/* Replacement for generic do_registers_info.
+   Print regs in pretty columns.  */
+
+static int
+print_fp_register_row (struct ui_file *file, struct frame_info *frame,
+                      int regnum)
+{
+  fprintf_filtered (file, " ");
+  mips_print_fp_register (file, frame, regnum);
+  fprintf_filtered (file, "\n");
+  return regnum + 1;
 }
 
+
 /* Print a row's worth of GP (int) registers, with name labels above */
 
 static int
-do_gp_register_row (int regnum)
+print_gp_register_row (struct ui_file *file, struct frame_info *frame,
+                      int regnum)
 {
   /* do values for GP (int) regs */
-  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+  char raw_buffer[MAX_REGISTER_SIZE];
   int ncols = (MIPS_REGSIZE == 8 ? 4 : 8);     /* display cols per row */
   int col, byte;
   int start_regnum = regnum;
@@ -4170,19 +4139,20 @@ do_gp_register_row (int regnum)
 
 
   /* For GP registers, we print a separate row of names above the vals */
-  printf_filtered ("     ");
+  fprintf_filtered (file, "     ");
   for (col = 0; col < ncols && regnum < numregs; regnum++)
     {
       if (*REGISTER_NAME (regnum) == '\0')
        continue;               /* unused register */
       if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
        break;                  /* end the row: reached FP register */
-      printf_filtered (MIPS_REGSIZE == 8 ? "%17s" : "%9s",
-                      REGISTER_NAME (regnum));
+      fprintf_filtered (file, MIPS_REGSIZE == 8 ? "%17s" : "%9s",
+                       REGISTER_NAME (regnum));
       col++;
     }
-  printf_filtered (start_regnum < MIPS_NUMREGS ? "\n R%-4d" : "\n      ",
-                  start_regnum);       /* 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 */
 
   regnum = start_regnum;       /* go back to start of row */
   /* now print the values in hex, 4 or 8 to the row */
@@ -4193,7 +4163,7 @@ do_gp_register_row (int regnum)
       if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
        break;                  /* end row: reached FP register */
       /* OK: get the data in raw format.  */
-      if (!frame_register_read (deprecated_selected_frame, regnum, raw_buffer))
+      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++)
@@ -4203,17 +4173,17 @@ do_gp_register_row (int regnum)
        for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
             byte < REGISTER_RAW_SIZE (regnum);
             byte++)
-         printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
+         fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
       else
        for (byte = REGISTER_VIRTUAL_SIZE (regnum) - 1;
             byte >= 0;
             byte--)
-         printf_filtered ("%02x", (unsigned char) raw_buffer[byte]);
-      printf_filtered (" ");
+         fprintf_filtered (file, "%02x", (unsigned char) raw_buffer[byte]);
+      fprintf_filtered (file, " ");
       col++;
     }
   if (col > 0)                 /* ie. if we actually printed anything... */
-    printf_filtered ("\n");
+    fprintf_filtered (file, "\n");
 
   return regnum;
 }
@@ -4221,15 +4191,16 @@ do_gp_register_row (int regnum)
 /* MIPS_DO_REGISTERS_INFO(): called by "info register" command */
 
 static void
-mips_do_registers_info (int regnum, int fpregs)
+mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
+                          struct frame_info *frame, int regnum, int all)
 {
   if (regnum != -1)            /* do one specified register */
     {
       if (*(REGISTER_NAME (regnum)) == '\0')
        error ("Not a valid register for the current processor type");
 
-      mips_print_register (regnum, 0);
-      printf_filtered ("\n");
+      mips_print_register (file, frame, regnum, 0);
+      fprintf_filtered (file, "\n");
     }
   else
     /* do all (or most) registers */
@@ -4238,12 +4209,14 @@ mips_do_registers_info (int regnum, int fpregs)
       while (regnum < NUM_REGS)
        {
          if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
-           if (fpregs)         /* true for "INFO ALL-REGISTERS" command */
-             regnum = do_fp_register_row (regnum);     /* FP regs */
-           else
-             regnum += MIPS_NUMREGS;   /* skip floating point regs */
+           {
+             if (all)          /* true for "INFO ALL-REGISTERS" command */
+               regnum = print_fp_register_row (file, frame, regnum);
+             else
+               regnum += MIPS_NUMREGS; /* skip floating point regs */
+           }
          else
-           regnum = do_gp_register_row (regnum);       /* GP (int) regs */
+           regnum = print_gp_register_row (file, frame, regnum);
        }
     }
 }
@@ -4623,7 +4596,7 @@ return_value_location (struct type *valtype,
 
 static void
 mips_eabi_extract_return_value (struct type *valtype,
-                               char regbuf[REGISTER_BYTES],
+                               char regbuf[],
                                char *valbuf)
 {
   struct return_value_word lo;
@@ -4642,7 +4615,7 @@ mips_eabi_extract_return_value (struct type *valtype,
 
 static void
 mips_o64_extract_return_value (struct type *valtype,
-                              char regbuf[REGISTER_BYTES],
+                              char regbuf[],
                               char *valbuf)
 {
   struct return_value_word lo;
@@ -4665,7 +4638,7 @@ mips_o64_extract_return_value (struct type *valtype,
 static void
 mips_eabi_store_return_value (struct type *valtype, char *valbuf)
 {
-  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+  char raw_buffer[MAX_REGISTER_SIZE];
   struct return_value_word lo;
   struct return_value_word hi;
   return_value_location (valtype, &hi, &lo);
@@ -4687,7 +4660,7 @@ mips_eabi_store_return_value (struct type *valtype, char *valbuf)
 static void
 mips_o64_store_return_value (struct type *valtype, char *valbuf)
 {
-  char *raw_buffer = alloca (MAX_REGISTER_RAW_SIZE);
+  char raw_buffer[MAX_REGISTER_SIZE];
   struct return_value_word lo;
   struct return_value_word hi;
   return_value_location (valtype, &hi, &lo);
@@ -4769,7 +4742,7 @@ mips_o32_xfer_return_value (struct type *type,
       /* A struct that contains one or two floats.  Each value is part
          in the least significant part of their floating point
          register..  */
-      bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE);
+      bfd_byte reg[MAX_REGISTER_SIZE];
       int regnum;
       int field;
       for (field = 0, regnum = FP0_REGNUM;
@@ -4881,7 +4854,7 @@ mips_n32n64_xfer_return_value (struct type *type,
       /* A struct that contains one or two floats.  Each value is part
          in the least significant part of their floating point
          register..  */
-      bfd_byte *reg = alloca (MAX_REGISTER_RAW_SIZE);
+      bfd_byte reg[MAX_REGISTER_SIZE];
       int regnum;
       int field;
       for (field = 0, regnum = FP0_REGNUM;
@@ -4955,12 +4928,6 @@ mips_n32n64_store_return_value (struct type *type, char *valbuf)
   mips_n32n64_xfer_return_value (type, current_regcache, NULL, valbuf);
 }
 
-static void
-mips_store_struct_return (CORE_ADDR addr, CORE_ADDR sp)
-{
-  /* Nothing to do -- push_arguments does all the work.  */
-}
-
 static CORE_ADDR
 mips_extract_struct_value_address (struct regcache *regcache)
 {
@@ -5158,7 +5125,7 @@ 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,
@@ -5166,10 +5133,10 @@ gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info)
      guess that if the address passed in is odd, it's 16-bits.  */
   if (proc_desc)
     info->mach = pc_is_mips16 (PROC_LOW_ADDR (proc_desc)) ?
-      bfd_mach_mips16 : TM_PRINT_INSN_MACH;
+      bfd_mach_mips16 : 0;
   else
     info->mach = pc_is_mips16 (memaddr) ?
-      bfd_mach_mips16 : TM_PRINT_INSN_MACH;
+      bfd_mach_mips16 : 0;
 
   /* Round down the instruction address to the appropriate boundary.  */
   memaddr &= (info->mach == bfd_mach_mips16 ? ~1 : ~3);
@@ -5181,19 +5148,6 @@ gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info)
     return print_insn_little_mips (memaddr, info);
 }
 
-/* Old-style breakpoint macros.
-   The IDT board uses an unusual breakpoint value, and sometimes gets
-   confused when it sees the usual MIPS breakpoint instruction.  */
-
-#define BIG_BREAKPOINT {0, 0x5, 0, 0xd}
-#define LITTLE_BREAKPOINT {0xd, 0, 0x5, 0}
-#define PMON_BIG_BREAKPOINT {0, 0, 0, 0xd}
-#define PMON_LITTLE_BREAKPOINT {0xd, 0, 0, 0}
-#define IDT_BIG_BREAKPOINT {0, 0, 0x0a, 0xd}
-#define IDT_LITTLE_BREAKPOINT {0xd, 0x0a, 0, 0}
-#define MIPS16_BIG_BREAKPOINT {0xe8, 0xa5}
-#define MIPS16_LITTLE_BREAKPOINT {0xa5, 0xe8}
-
 /* This function implements the BREAKPOINT_FROM_PC macro.  It uses the program
    counter value to determine whether a 16- or 32-bit breakpoint should be
    used.  It returns a pointer to a string of bytes that encode a breakpoint
@@ -5208,17 +5162,19 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
     {
       if (pc_is_mips16 (*pcptr))
        {
-         static unsigned char mips16_big_breakpoint[] =
-           MIPS16_BIG_BREAKPOINT;
-         *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
+         static unsigned char mips16_big_breakpoint[] = {0xe8, 0xa5};
+         *pcptr = unmake_mips16_addr (*pcptr);
          *lenptr = sizeof (mips16_big_breakpoint);
          return mips16_big_breakpoint;
        }
       else
        {
-         static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
-         static unsigned char pmon_big_breakpoint[] = PMON_BIG_BREAKPOINT;
-         static unsigned char idt_big_breakpoint[] = IDT_BIG_BREAKPOINT;
+         /* The IDT board uses an unusual breakpoint value, and
+            sometimes gets confused when it sees the usual MIPS
+            breakpoint instruction.  */
+         static unsigned char big_breakpoint[] = {0, 0x5, 0, 0xd};
+         static unsigned char pmon_big_breakpoint[] = {0, 0, 0, 0xd};
+         static unsigned char idt_big_breakpoint[] = {0, 0, 0x0a, 0xd};
 
          *lenptr = sizeof (big_breakpoint);
 
@@ -5236,19 +5192,16 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
     {
       if (pc_is_mips16 (*pcptr))
        {
-         static unsigned char mips16_little_breakpoint[] =
-           MIPS16_LITTLE_BREAKPOINT;
-         *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
+         static unsigned char mips16_little_breakpoint[] = {0xa5, 0xe8};
+         *pcptr = unmake_mips16_addr (*pcptr);
          *lenptr = sizeof (mips16_little_breakpoint);
          return mips16_little_breakpoint;
        }
       else
        {
-         static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
-         static unsigned char pmon_little_breakpoint[] =
-           PMON_LITTLE_BREAKPOINT;
-         static unsigned char idt_little_breakpoint[] =
-           IDT_LITTLE_BREAKPOINT;
+         static unsigned char little_breakpoint[] = {0xd, 0, 0x5, 0};
+         static unsigned char pmon_little_breakpoint[] = {0xd, 0, 0, 0};
+         static unsigned char idt_little_breakpoint[] = {0xd, 0x0a, 0, 0};
 
          *lenptr = sizeof (little_breakpoint);
 
@@ -5477,7 +5430,6 @@ mips_get_saved_register (char *raw_buffer,
   CORE_ADDR addrx;
   enum lval_type lvalx;
   int optimizedx;
-  int realnum;
 
   if (!target_has_registers)
     error ("No registers.");
@@ -5489,8 +5441,8 @@ mips_get_saved_register (char *raw_buffer,
     lvalp = &lvalx;
   if (optimizedp == NULL)
     optimizedp = &optimizedx;
-  frame_register_unwind (get_next_frame (frame), regnum, optimizedp, lvalp,
-                        addrp, &realnum, raw_buffer);
+  deprecated_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
@@ -5505,7 +5457,7 @@ mips_get_saved_register (char *raw_buffer,
              /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
                 saved. */
              LONGEST val = read_memory_integer ((*addrp), MIPS_SAVED_REGSIZE);
-             store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
+             store_unsigned_integer (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
            }
        }
     }
@@ -5529,23 +5481,45 @@ mips_saved_pc_after_call (struct frame_info *frame)
 static int
 mips_stab_reg_to_regnum (int num)
 {
-  if (num < 32)
+  if (num >= 0 && num < 32)
     return num;
-  else
+  else if (num >= 38 && num < 70)
     return num + FP0_REGNUM - 38;
+  else if (num == 70)
+    return HI_REGNUM;
+  else if (num == 71)
+    return LO_REGNUM;
+  else
+    {
+      /* This will hopefully (eventually) provoke a warning.  Should
+         we be calling complaint() here?  */
+      return NUM_REGS + NUM_PSEUDO_REGS;
+    }
 }
 
-/* Convert a ecoff register number to a gdb REGNUM */
+
+/* Convert a dwarf, dwarf2, or ecoff register number to a gdb REGNUM */
 
 static int
-mips_ecoff_reg_to_regnum (int num)
+mips_dwarf_dwarf2_ecoff_reg_to_regnum (int num)
 {
-  if (num < 32)
+  if (num >= 0 && num < 32)
     return num;
-  else
+  else if (num >= 32 && num < 64)
     return num + FP0_REGNUM - 32;
+  else if (num == 64)
+    return HI_REGNUM;
+  else if (num == 65)
+    return LO_REGNUM;
+  else
+    {
+      /* This will hopefully (eventually) provoke a warning.  Should
+         we be calling complaint() here?  */
+      return NUM_REGS + NUM_PSEUDO_REGS;
+    }
 }
 
+
 /* Convert an integer into an address.  By first converting the value
    into a pointer and then extracting it signed, the address is
    guarenteed to be correctly sign extended.  */
@@ -5605,8 +5579,6 @@ static struct gdbarch *
 mips_gdbarch_init (struct gdbarch_info info,
                   struct gdbarch_list *arches)
 {
-  static LONGEST mips_call_dummy_words[] =
-  {0};
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
   int elf_flags;
@@ -5614,9 +5586,9 @@ mips_gdbarch_init (struct gdbarch_info info,
 
   /* Reset the disassembly info, in case it was set to something
      non-default.  */
-  tm_print_insn_info.flavour = bfd_target_unknown_flavour;
-  tm_print_insn_info.arch = bfd_arch_unknown;
-  tm_print_insn_info.mach = 0;
+  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;
 
   elf_flags = 0;
 
@@ -5697,6 +5669,34 @@ 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,
@@ -5735,9 +5735,7 @@ 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_max_register_raw_size (gdbarch, 8);
-  set_gdbarch_max_register_virtual_size (gdbarch, 8);
+  set_gdbarch_deprecated_register_raw_size (gdbarch, mips_register_raw_size);
   tdep->found_abi = found_abi;
   tdep->mips_abi = mips_abi;
 
@@ -5752,7 +5750,7 @@ mips_gdbarch_init (struct gdbarch_info info,
   switch (mips_abi)
     {
     case MIPS_ABI_O32:
-      set_gdbarch_push_arguments (gdbarch, mips_o32_push_arguments);
+      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);
       tdep->mips_default_saved_regsize = 4;
@@ -5768,10 +5766,10 @@ mips_gdbarch_init (struct gdbarch_info info,
       set_gdbarch_reg_struct_has_addr (gdbarch, 
                                       mips_o32_reg_struct_has_addr);
       set_gdbarch_use_struct_convention (gdbarch, 
-                                        mips_o32_use_struct_convention);
+                                        always_use_struct_convention);
       break;
     case MIPS_ABI_O64:
-      set_gdbarch_push_arguments (gdbarch, mips_o64_push_arguments);
+      set_gdbarch_push_dummy_call (gdbarch, mips_o64_push_dummy_call);
       set_gdbarch_deprecated_store_return_value (gdbarch, mips_o64_store_return_value);
       set_gdbarch_deprecated_extract_return_value (gdbarch, mips_o64_extract_return_value);
       tdep->mips_default_saved_regsize = 8;
@@ -5786,11 +5784,10 @@ mips_gdbarch_init (struct gdbarch_info info,
       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_use_struct_convention (gdbarch, always_use_struct_convention);
       break;
     case MIPS_ABI_EABI32:
-      set_gdbarch_push_arguments (gdbarch, mips_eabi_push_arguments);
+      set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call);
       set_gdbarch_deprecated_store_return_value (gdbarch, mips_eabi_store_return_value);
       set_gdbarch_deprecated_extract_return_value (gdbarch, mips_eabi_extract_return_value);
       tdep->mips_default_saved_regsize = 4;
@@ -5809,7 +5806,7 @@ mips_gdbarch_init (struct gdbarch_info info,
                                         mips_eabi_use_struct_convention);
       break;
     case MIPS_ABI_EABI64:
-      set_gdbarch_push_arguments (gdbarch, mips_eabi_push_arguments);
+      set_gdbarch_push_dummy_call (gdbarch, mips_eabi_push_dummy_call);
       set_gdbarch_deprecated_store_return_value (gdbarch, mips_eabi_store_return_value);
       set_gdbarch_deprecated_extract_return_value (gdbarch, mips_eabi_extract_return_value);
       tdep->mips_default_saved_regsize = 8;
@@ -5828,7 +5825,7 @@ mips_gdbarch_init (struct gdbarch_info info,
                                         mips_eabi_use_struct_convention);
       break;
     case MIPS_ABI_N32:
-      set_gdbarch_push_arguments (gdbarch, mips_n32n64_push_arguments);
+      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);
       tdep->mips_default_saved_regsize = 8;
@@ -5841,25 +5838,13 @@ mips_gdbarch_init (struct gdbarch_info info,
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
-
-      /* Set up the disassembler info, so that we get the right
-        register names from libopcodes.  */
-      tm_print_insn_info.flavour = bfd_target_elf_flavour;
-      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)
-       tm_print_insn_info.mach = info.bfd_arch_info->mach;
-      else
-       tm_print_insn_info.mach = bfd_mach_mips8000;
-
       set_gdbarch_use_struct_convention (gdbarch, 
                                         mips_n32n64_use_struct_convention);
       set_gdbarch_reg_struct_has_addr (gdbarch, 
                                       mips_n32n64_reg_struct_has_addr);
       break;
     case MIPS_ABI_N64:
-      set_gdbarch_push_arguments (gdbarch, mips_n32n64_push_arguments);
+      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);
       tdep->mips_default_saved_regsize = 8;
@@ -5872,18 +5857,6 @@ mips_gdbarch_init (struct gdbarch_info info,
       set_gdbarch_long_bit (gdbarch, 64);
       set_gdbarch_ptr_bit (gdbarch, 64);
       set_gdbarch_long_long_bit (gdbarch, 64);
-
-      /* Set up the disassembler info, so that we get the right
-        register names from libopcodes.  */
-      tm_print_insn_info.flavour = bfd_target_elf_flavour;
-      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)
-       tm_print_insn_info.mach = info.bfd_arch_info->mach;
-      else
-       tm_print_insn_info.mach = bfd_mach_mips8000;
-
       set_gdbarch_use_struct_convention (gdbarch, 
                                         mips_n32n64_use_struct_convention);
       set_gdbarch_reg_struct_has_addr (gdbarch, 
@@ -5947,9 +5920,8 @@ mips_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_register_name (gdbarch, mips_register_name);
   set_gdbarch_read_pc (gdbarch, mips_read_pc);
   set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
-  set_gdbarch_read_fp (gdbarch, mips_read_sp); /* Draft FRAME base.  */
+  set_gdbarch_deprecated_target_read_fp (gdbarch, mips_read_sp); /* Draft FRAME base.  */
   set_gdbarch_read_sp (gdbarch, mips_read_sp);
-  set_gdbarch_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.  */
@@ -5962,51 +5934,38 @@ mips_gdbarch_init (struct gdbarch_info info,
 
   /* 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_ecoff_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);
 
   /* Initialize a frame */
-  set_gdbarch_init_extra_frame_info (gdbarch, mips_init_extra_frame_info);
-  set_gdbarch_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_p (gdbarch, 1);
-  set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0);
   set_gdbarch_call_dummy_address (gdbarch, mips_call_dummy_address);
-  set_gdbarch_push_return_address (gdbarch, mips_push_return_address);
-  set_gdbarch_push_dummy_frame (gdbarch, generic_push_dummy_frame);
-  set_gdbarch_pop_frame (gdbarch, mips_pop_frame);
-  set_gdbarch_call_dummy_start_offset (gdbarch, 0);
-  set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1);
-  set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0);
-  set_gdbarch_call_dummy_length (gdbarch, 0);
-  set_gdbarch_fix_call_dummy (gdbarch, mips_fix_call_dummy);
-  set_gdbarch_call_dummy_words (gdbarch, mips_call_dummy_words);
-  set_gdbarch_sizeof_call_dummy_words (gdbarch, sizeof (mips_call_dummy_words));
-  set_gdbarch_push_return_address (gdbarch, mips_push_return_address);
+  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_register_convertible (gdbarch, mips_register_convertible);
+  set_gdbarch_deprecated_register_convert_to_virtual (gdbarch, mips_register_convert_to_virtual);
+  set_gdbarch_deprecated_register_convert_to_raw (gdbarch, mips_register_convert_to_raw);
 
-  set_gdbarch_frame_chain (gdbarch, mips_frame_chain);
+  set_gdbarch_deprecated_frame_chain (gdbarch, mips_frame_chain);
   set_gdbarch_frameless_function_invocation (gdbarch, 
                                             generic_frameless_function_invocation_not);
-  set_gdbarch_frame_saved_pc (gdbarch, mips_frame_saved_pc);
-  set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown);
+  set_gdbarch_deprecated_frame_saved_pc (gdbarch, mips_frame_saved_pc);
   set_gdbarch_frame_args_skip (gdbarch, 0);
 
-  set_gdbarch_get_saved_register (gdbarch, mips_get_saved_register);
+  set_gdbarch_deprecated_get_saved_register (gdbarch, mips_get_saved_register);
 
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
   set_gdbarch_breakpoint_from_pc (gdbarch, mips_breakpoint_from_pc);
   set_gdbarch_decr_pc_after_break (gdbarch, 0);
 
   set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
-  set_gdbarch_saved_pc_after_call (gdbarch, mips_saved_pc_after_call);
+  set_gdbarch_deprecated_saved_pc_after_call (gdbarch, mips_saved_pc_after_call);
 
   set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
   set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
@@ -6016,16 +5975,14 @@ mips_gdbarch_init (struct gdbarch_info info,
 
   /* 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_virtual_size (gdbarch, generic_register_size);
+  set_gdbarch_deprecated_register_virtual_type (gdbarch, mips_register_virtual_type);
 
-  set_gdbarch_deprecated_do_registers_info (gdbarch, mips_do_registers_info);
+  set_gdbarch_print_registers_info (gdbarch, mips_print_registers_info);
   set_gdbarch_pc_in_sigtramp (gdbarch, mips_pc_in_sigtramp);
 
   /* Hook in OS ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
-  set_gdbarch_store_struct_return (gdbarch, mips_store_struct_return);
   set_gdbarch_extract_struct_value_address (gdbarch, 
                                            mips_extract_struct_value_address);
   
@@ -6049,6 +6006,38 @@ mips_abi_update (char *ignore_args, int from_tty,
   gdbarch_update_p (info);
 }
 
+/* Print out which MIPS ABI is in use.  */
+
+static void
+show_mips_abi (char *ignore_args, int from_tty)
+{
+  if (gdbarch_bfd_arch_info (current_gdbarch)->arch != bfd_arch_mips)
+    printf_filtered (
+      "The MIPS ABI is unknown because the current architecture is not MIPS.\n");
+  else
+    {
+      enum mips_abi global_abi = global_mips_abi ();
+      enum mips_abi actual_abi = mips_abi (current_gdbarch);
+      const char *actual_abi_str = mips_abi_strings[actual_abi];
+
+      if (global_abi == MIPS_ABI_UNKNOWN)
+       printf_filtered ("The MIPS ABI is set automatically (currently \"%s\").\n",
+                        actual_abi_str);
+      else if (global_abi == actual_abi)
+       printf_filtered (
+         "The MIPS ABI is assumed to be \"%s\" (due to user setting).\n",
+         actual_abi_str);
+      else
+       {
+         /* Probably shouldn't happen...  */
+         printf_filtered (
+           "The (auto detected) MIPS ABI \"%s\" is in use even though the user setting was \"%s\".\n",
+           actual_abi_str,
+           mips_abi_strings[global_abi]);
+       }
+    }
+}
+
 static void
 mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
 {
@@ -6147,8 +6136,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: BADVADDR_REGNUM = %d\n",
                      BADVADDR_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: BIG_BREAKPOINT = delete?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: CAUSE_REGNUM = %d\n",
                      CAUSE_REGNUM);
@@ -6173,19 +6160,12 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: GDB_TARGET_IS_MIPS64 = %d\n",
                      GDB_TARGET_IS_MIPS64);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: GEN_REG_SAVE_MASK = %d\n",
-                     GEN_REG_SAVE_MASK);
   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: IDT_BIG_BREAKPOINT = delete?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: IDT_LITTLE_BREAKPOINT = delete?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: IGNORE_HELPER_CALL # %s\n",
                      XSTRING (IGNORE_HELPER_CALL (PC)));
@@ -6195,13 +6175,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: LITTLE_BREAKPOINT = delete?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: LO_REGNUM = %d\n",
                      LO_REGNUM);
@@ -6220,15 +6196,9 @@ 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_BIG_BREAKPOINT = delete?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS16_INSTLEN = %d\n",
                      MIPS16_INSTLEN);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: MIPS16_LITTLE_BREAKPOINT = delete?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS_DEFAULT_ABI = FIXME!\n");
   fprintf_unfiltered (file,
@@ -6252,10 +6222,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
                      "mips_dump_tdep: OP_LDFPR = used?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: OP_LDGPR = used?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: PMON_BIG_BREAKPOINT = delete?\n");
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: PMON_LITTLE_BREAKPOINT = delete?\n");
   fprintf_unfiltered (file,
                      "mips_dump_tdep: PRID_REGNUM = %d\n",
                      PRID_REGNUM);
@@ -6289,9 +6255,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   fprintf_unfiltered (file,
                      "mips_dump_tdep: PS_REGNUM = %d\n",
                      PS_REGNUM);
-  fprintf_unfiltered (file,
-                     "mips_dump_tdep: PUSH_FP_REGNUM = %d\n",
-                     PUSH_FP_REGNUM);
   fprintf_unfiltered (file,
                      "mips_dump_tdep: RA_REGNUM = %d\n",
                      RA_REGNUM);
@@ -6379,11 +6342,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",
@@ -6404,8 +6362,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",
@@ -6430,6 +6386,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)
 {
@@ -6442,8 +6400,8 @@ _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 (!tm_print_insn)          /* Someone may have already set it */
-    tm_print_insn = gdb_print_insn_mips;
+  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,
@@ -6496,8 +6454,9 @@ This option can be set to one of:\n\
      "  eabi32\n"
      "  eabi64",
      &setmipscmdlist);
-  add_show_from_set (c, &showmipscmdlist);
   set_cmd_sfunc (c, mips_abi_update);
+  add_cmd ("abi", class_obscure, show_mips_abi,
+           "Show ABI in use by MIPS target", &showmipscmdlist);
 
   /* Let the user turn off floating point and set the fence post for
      heuristic_proc_start.  */
This page took 0.084122 seconds and 4 git commands to generate.