Kazu Hirata's formatting and comment typo fixes.
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index 189dd7b1c93352090d43cedc00f40817f4460b35..0922ceed2cacc2dafa801fd59db4f2e0c2edf12f 100644 (file)
@@ -1,5 +1,8 @@
 /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
-   Copyright 1988-1999, Free Software Foundation, Inc.
+
+   Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
+   1997, 1998, 1999, 2000, Free Software Foundation, Inc.
+
    Contributed by Alessandro Forin(af@cs.cmu.edu) at CMU
    and by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin.
 
 #include "objfiles.h"
 #include "gdbtypes.h"
 #include "target.h"
+#include "arch-utils.h"
 
 #include "opcode/mips.h"
 #include "elf/mips.h"
 #include "elf-bfd.h"
+#include "symcat.h"
 
+/* The sizes of floating point registers.  */
+
+enum
+{
+  MIPS_FPU_SINGLE_REGSIZE = 4,
+  MIPS_FPU_DOUBLE_REGSIZE = 8
+};
+
+/* All the possible MIPS ABIs. */
+
+enum mips_abi
+  {
+    MIPS_ABI_UNKNOWN,
+    MIPS_ABI_N32,
+    MIPS_ABI_O32,
+    MIPS_ABI_O64,
+    MIPS_ABI_EABI32,
+    MIPS_ABI_EABI64
+  };
 
 struct frame_extra_info
   {
@@ -45,22 +69,21 @@ struct frame_extra_info
     int num_args;
   };
 
-/* We allow the user to override MIPS_SAVED_REGSIZE, so define
-   the subcommand enum settings allowed. */
-static char saved_gpreg_size_auto[] = "auto";
-static char saved_gpreg_size_32[] = "32";
-static char saved_gpreg_size_64[] = "64";
+/* Various MIPS ISA options (related to stack analysis) can be
+   overridden dynamically.  Establish an enum/array for managing
+   them. */
+
+static const char size_auto[] = "auto";
+static const char size_32[] = "32";
+static const char size_64[] = "64";
 
-static char *saved_gpreg_size_enums[] = {
-  saved_gpreg_size_auto,
-  saved_gpreg_size_32,
-  saved_gpreg_size_64,
+static const char *size_enums[] = {
+  size_auto,
+  size_32,
+  size_64,
   0
 };
 
-/* The current (string) value of saved_gpreg_size. */
-static char *mips_saved_regsize_string = saved_gpreg_size_auto;
-
 /* Some MIPS boards don't support floating point while others only
    support single-precision floating-point operations.  See also
    FP_REGISTER_DOUBLE. */
@@ -79,17 +102,12 @@ static int mips_fpu_type_auto = 1;
 static enum mips_fpu_type mips_fpu_type = MIPS_DEFAULT_FPU_TYPE;
 #define MIPS_FPU_TYPE mips_fpu_type
 
-#ifndef MIPS_DEFAULT_SAVED_REGSIZE
-#define MIPS_DEFAULT_SAVED_REGSIZE MIPS_REGSIZE
-#endif
-
-#define MIPS_SAVED_REGSIZE (mips_saved_regsize())
-
 /* Do not use "TARGET_IS_MIPS64" to test the size of floating point registers */
 #ifndef FP_REGISTER_DOUBLE
 #define FP_REGISTER_DOUBLE (REGISTER_VIRTUAL_SIZE(FP0_REGNUM) == 8)
 #endif
 
+static int mips_debug = 0;
 
 /* MIPS specific per-architecture information */
 struct gdbarch_tdep
@@ -97,17 +115,21 @@ struct gdbarch_tdep
     /* from the elf header */
     int elf_flags;
     /* mips options */
-    int mips_eabi;
+    enum mips_abi mips_abi;
     enum mips_fpu_type mips_fpu_type;
     int mips_last_arg_regnum;
     int mips_last_fp_arg_regnum;
     int mips_default_saved_regsize;
     int mips_fp_register_double;
+    int mips_regs_have_home_p;
+    int mips_default_stack_argsize;
+    int gdb_target_is_mips64;
   };
 
 #if GDB_MULTI_ARCH
 #undef MIPS_EABI
-#define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_eabi)
+#define MIPS_EABI (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI32 \
+                  || gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_EABI64)
 #endif
 
 #if GDB_MULTI_ARCH
@@ -125,11 +147,30 @@ struct gdbarch_tdep
 #define MIPS_FPU_TYPE (gdbarch_tdep (current_gdbarch)->mips_fpu_type)
 #endif
 
+/* Return the currently configured (or set) saved register size. */
+
 #if GDB_MULTI_ARCH
 #undef MIPS_DEFAULT_SAVED_REGSIZE
 #define MIPS_DEFAULT_SAVED_REGSIZE (gdbarch_tdep (current_gdbarch)->mips_default_saved_regsize)
+#elif !defined (MIPS_DEFAULT_SAVED_REGSIZE)
+#define MIPS_DEFAULT_SAVED_REGSIZE MIPS_REGSIZE
 #endif
 
+static const char *mips_saved_regsize_string = size_auto;
+
+#define MIPS_SAVED_REGSIZE (mips_saved_regsize())
+
+static unsigned int
+mips_saved_regsize ()
+{
+  if (mips_saved_regsize_string == size_auto)
+    return MIPS_DEFAULT_SAVED_REGSIZE;
+  else if (mips_saved_regsize_string == size_64)
+    return 8;
+  else /* if (mips_saved_regsize_string == size_32) */
+    return 4;
+}
+
 /* Indicate that the ABI makes use of double-precision registers
    provided by the FPU (rather than combining pairs of registers to
    form double-precision values).  Do not use "TARGET_IS_MIPS64" to
@@ -140,36 +181,75 @@ struct gdbarch_tdep
 #define FP_REGISTER_DOUBLE (gdbarch_tdep (current_gdbarch)->mips_fp_register_double)
 #endif
 
+/* Does the caller allocate a ``home'' for each register used in the
+   function call?  The N32 ABI and MIPS_EABI do not, the others do. */
+
+#if GDB_MULTI_ARCH
+#undef MIPS_REGS_HAVE_HOME_P
+#define MIPS_REGS_HAVE_HOME_P (gdbarch_tdep (current_gdbarch)->mips_regs_have_home_p)
+#elif !defined (MIPS_REGS_HAVE_HOME_P)
+#define MIPS_REGS_HAVE_HOME_P (!MIPS_EABI)
+#endif
+
+/* The amount of space reserved on the stack for registers. This is
+   different to MIPS_SAVED_REGSIZE as it determines the alignment of
+   data allocated after the registers have run out. */
+
+#if GDB_MULTI_ARCH
+#undef MIPS_DEFAULT_STACK_ARGSIZE
+#define MIPS_DEFAULT_STACK_ARGSIZE (gdbarch_tdep (current_gdbarch)->mips_default_stack_argsize)
+#elif !defined (MIPS_DEFAULT_STACK_ARGSIZE)
+#define MIPS_DEFAULT_STACK_ARGSIZE (MIPS_DEFAULT_SAVED_REGSIZE)
+#endif
+
+#define MIPS_STACK_ARGSIZE (mips_stack_argsize ())
+
+static const char *mips_stack_argsize_string = size_auto;
+
+static unsigned int
+mips_stack_argsize (void)
+{
+  if (mips_stack_argsize_string == size_auto)
+    return MIPS_DEFAULT_STACK_ARGSIZE;
+  else if (mips_stack_argsize_string == size_64)
+    return 8;
+  else /* if (mips_stack_argsize_string == size_32) */
+    return 4;
+}
+
+#if GDB_MULTI_ARCH
+#undef GDB_TARGET_IS_MIPS64
+#define GDB_TARGET_IS_MIPS64 (gdbarch_tdep (current_gdbarch)->gdb_target_is_mips64 + 0)
+#endif
 
 #define VM_MIN_ADDRESS (CORE_ADDR)0x400000
 
 #if 0
-static int mips_in_lenient_prologue PARAMS ((CORE_ADDR, CORE_ADDR));
+static int mips_in_lenient_prologue (CORE_ADDR, CORE_ADDR);
 #endif
 
-int gdb_print_insn_mips PARAMS ((bfd_vma, disassemble_info *));
+int gdb_print_insn_mips (bfd_vma, disassemble_info *);
 
-static void mips_print_register PARAMS ((int, int));
+static void mips_print_register (int, int);
 
 static mips_extra_func_info_t
-  heuristic_proc_desc PARAMS ((CORE_ADDR, CORE_ADDR, struct frame_info *));
+heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *);
 
-static CORE_ADDR heuristic_proc_start PARAMS ((CORE_ADDR));
+static CORE_ADDR heuristic_proc_start (CORE_ADDR);
 
-static CORE_ADDR read_next_frame_reg PARAMS ((struct frame_info *, int));
+static CORE_ADDR read_next_frame_reg (struct frame_info *, int);
 
-int mips_set_processor_type PARAMS ((char *));
+int mips_set_processor_type (char *);
 
-static void mips_show_processor_type_command PARAMS ((char *, int));
+static void mips_show_processor_type_command (char *, int);
 
-static void reinit_frame_cache_sfunc PARAMS ((char *, int,
-                                             struct cmd_list_element *));
+static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
 
 static mips_extra_func_info_t
-  find_proc_desc PARAMS ((CORE_ADDR pc, struct frame_info * next_frame));
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame);
 
-static CORE_ADDR after_prologue PARAMS ((CORE_ADDR pc,
-                                        mips_extra_func_info_t proc_desc));
+static CORE_ADDR after_prologue (CORE_ADDR pc,
+                                mips_extra_func_info_t proc_desc);
 
 /* This value is the model of MIPS in use.  It is derived from the value
    of the PrID register.  */
@@ -325,19 +405,6 @@ mips_print_extra_frame_info (fi)
                     paddr_d (fi->extra_info->proc_desc->pdr.frameoffset));
 }
 
-/* Return the currently configured (or set) saved register size */
-
-static unsigned int
-mips_saved_regsize ()
-{
-  if (mips_saved_regsize_string == saved_gpreg_size_auto)
-    return MIPS_DEFAULT_SAVED_REGSIZE;
-  else if (mips_saved_regsize_string == saved_gpreg_size_64)
-    return 8;
-  else /* if (mips_saved_regsize_string == saved_gpreg_size_32) */
-    return 4;
-}
-
 /* Convert between RAW and VIRTUAL registers.  The RAW register size
    defines the remote-gdb packet. */
 
@@ -1246,31 +1313,34 @@ CORE_ADDR
 mips_addr_bits_remove (addr)
      CORE_ADDR addr;
 {
-#if GDB_TARGET_IS_MIPS64
-  if (mask_address_p && (addr >> 32 == (CORE_ADDR) 0xffffffff))
+  if (GDB_TARGET_IS_MIPS64)
     {
-      /* This hack is a work-around for existing boards using PMON,
-         the simulator, and any other 64-bit targets that doesn't have
-         true 64-bit addressing.  On these targets, the upper 32 bits
-         of addresses are ignored by the hardware.  Thus, the PC or SP
-         are likely to have been sign extended to all 1s by instruction
-         sequences that load 32-bit addresses.  For example, a typical
-         piece of code that loads an address is this:
-         lui $r2, <upper 16 bits>
-         ori $r2, <lower 16 bits>
-         But the lui sign-extends the value such that the upper 32 bits
-         may be all 1s.  The workaround is simply to mask off these bits.
-         In the future, gcc may be changed to support true 64-bit
-         addressing, and this masking will have to be disabled.  */
+      if (mask_address_p && (addr >> 32 == (CORE_ADDR) 0xffffffff))
+       {
+         /* This hack is a work-around for existing boards using
+            PMON, the simulator, and any other 64-bit targets that
+            doesn't have true 64-bit addressing.  On these targets,
+            the upper 32 bits of addresses are ignored by the
+            hardware.  Thus, the PC or SP are likely to have been
+            sign extended to all 1s by instruction sequences that
+            load 32-bit addresses.  For example, a typical piece of
+            code that loads an address is this: lui $r2, <upper 16
+            bits> ori $r2, <lower 16 bits> But the lui sign-extends
+            the value such that the upper 32 bits may be all 1s.  The
+            workaround is simply to mask off these bits.  In the
+            future, gcc may be changed to support true 64-bit
+            addressing, and this masking will have to be disabled.  */
+         addr &= (CORE_ADDR) 0xffffffff;
+       }
+    }
+  else
+    {
+      /* Even when GDB is configured for some 32-bit targets
+        (e.g. mips-elf), BFD is configured to handle 64-bit targets,
+        so CORE_ADDR is 64 bits.  So we still have to mask off
+        useless bits from addresses.  */
       addr &= (CORE_ADDR) 0xffffffff;
     }
-#else
-  /* Even when GDB is configured for some 32-bit targets (e.g. mips-elf),
-     BFD is configured to handle 64-bit targets, so CORE_ADDR is 64 bits.
-     So we still have to mask off useless bits from addresses.  */
-  addr &= (CORE_ADDR) 0xffffffff;
-#endif
-
   return addr;
 }
 
@@ -1992,20 +2062,6 @@ setup_arbitrary_frame (argc, argv)
   return create_new_frame (argv[0], argv[1]);
 }
 
-/*
- * STACK_ARGSIZE -- how many bytes does a pushed function arg take up on the stack?
- *
- * For n32 ABI, eight.
- * For all others, he same as the size of a general register.
- */
-#if defined (_MIPS_SIM_NABI32) && _MIPS_SIM == _MIPS_SIM_NABI32
-#define MIPS_NABI32   1
-#define STACK_ARGSIZE 8
-#else
-#define MIPS_NABI32   0
-#define STACK_ARGSIZE MIPS_SAVED_REGSIZE
-#endif
-
 CORE_ADDR
 mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
      int nargs;
@@ -2040,13 +2096,23 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
     len += ROUND_UP (TYPE_LENGTH (VALUE_TYPE (args[argnum])), MIPS_SAVED_REGSIZE);
   sp -= ROUND_UP (len, 16);
 
+  if (mips_debug)
+    fprintf_unfiltered (gdb_stdlog, "mips_push_arguments: sp=0x%lx allocated %d\n",
+                       (long) sp, ROUND_UP (len, 16));
+
   /* Initialize the integer and float register pointers.  */
   argreg = A0_REGNUM;
   float_argreg = FPA0_REGNUM;
 
   /* the struct_return pointer occupies the first parameter-passing reg */
   if (struct_return)
-    write_register (argreg++, struct_addr);
+    {
+      if (mips_debug)
+       fprintf_unfiltered (gdb_stdlog,
+                           "mips_push_arguments: struct_return at r%d 0x%lx\n",
+                           argreg, (long) struct_addr);
+      write_register (argreg++, struct_addr);
+    }
 
   /* Now load as many as possible of the first arguments into
      registers, and push the rest onto the stack.  Loop thru args
@@ -2060,15 +2126,23 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
       int len = TYPE_LENGTH (arg_type);
       enum type_code typecode = TYPE_CODE (arg_type);
 
+      if (mips_debug)
+       fprintf_unfiltered (gdb_stdlog,
+                           "mips_push_arguments: %d len=%d type=%d",
+                           argnum, len, (int) typecode);
+
       /* The EABI passes structures that do not fit in a register by
          reference. In all other cases, pass the structure by value.  */
-      if (MIPS_EABI && len > MIPS_SAVED_REGSIZE &&
-         (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
+      if (MIPS_EABI
+         && len > MIPS_SAVED_REGSIZE
+         && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
        {
          store_address (valbuf, MIPS_SAVED_REGSIZE, VALUE_ADDRESS (arg));
          typecode = TYPE_CODE_PTR;
          len = MIPS_SAVED_REGSIZE;
          val = valbuf;
+         if (mips_debug)
+           fprintf_unfiltered (gdb_stdlog, " push");
        }
       else
        val = (char *) VALUE_CONTENTS (arg);
@@ -2088,7 +2162,14 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
          don't use float registers for arguments.  This duplication of
          arguments in general registers can't hurt non-MIPS16 functions
          because those registers are normally skipped.  */
-      if (typecode == TYPE_CODE_FLT
+      /* MIPS_EABI squeeses a struct that contains a single floating
+         point value into an FP register instead of pusing it onto the
+         stack. */
+      if ((typecode == TYPE_CODE_FLT
+          || (MIPS_EABI
+              && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION)
+              && TYPE_NFIELDS (arg_type) == 1
+              && TYPE_CODE (TYPE_FIELD_TYPE (arg_type, 0)) == TYPE_CODE_FLT))
          && float_argreg <= MIPS_LAST_FP_ARG_REGNUM
          && MIPS_FPU_TYPE != MIPS_FPU_NONE)
        {
@@ -2099,17 +2180,30 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
 
              /* Write the low word of the double to the even register(s).  */
              regval = extract_unsigned_integer (val + low_offset, 4);
+             if (mips_debug)
+               fprintf_unfiltered (gdb_stdlog, " fpreg=%d val=%s",
+                                   float_argreg, phex (regval, 4));
              write_register (float_argreg++, regval);
              if (!MIPS_EABI)
-               write_register (argreg + 1, regval);
+               {
+                 if (mips_debug)
+                   fprintf_unfiltered (gdb_stdlog, " reg=%d val=%s",
+                                       argreg, phex (regval, 4));
+                 write_register (argreg++, regval);
+               }
 
              /* Write the high word of the double to the odd register(s).  */
              regval = extract_unsigned_integer (val + 4 - low_offset, 4);
+             if (mips_debug)
+               fprintf_unfiltered (gdb_stdlog, " fpreg=%d val=%s",
+                                   float_argreg, phex (regval, 4));
              write_register (float_argreg++, regval);
              if (!MIPS_EABI)
                {
-                 write_register (argreg, regval);
-                 argreg += 2;
+                 if (mips_debug)
+                   fprintf_unfiltered (gdb_stdlog, " reg=%d val=%s",
+                                       argreg, phex (regval, 4));
+                 write_register (argreg++, regval);
                }
 
            }
@@ -2119,7 +2213,10 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
                 in a single register.  */
              /* On 32 bit ABI's the float_argreg is further adjusted
                  above to ensure that it is even register aligned. */
-             CORE_ADDR regval = extract_address (val, len);
+             LONGEST regval = extract_unsigned_integer (val, len);
+             if (mips_debug)
+               fprintf_unfiltered (gdb_stdlog, " fpreg=%d val=%s",
+                                   float_argreg, phex (regval, len));
              write_register (float_argreg++, regval);
              if (!MIPS_EABI)
                {
@@ -2127,6 +2224,9 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
                      registers for each argument.  The below is (my
                      guess) to ensure that the corresponding integer
                      register has reserved the same space. */
+                 if (mips_debug)
+                   fprintf_unfiltered (gdb_stdlog, " reg=%d val=%s",
+                                       argreg, phex (regval, len));
                  write_register (argreg, regval);
                  argreg += FP_REGISTER_DOUBLE ? 1 : 2;
                }
@@ -2155,28 +2255,47 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
                     promoted to int before being stored? */
 
                  int longword_offset = 0;
+                 CORE_ADDR addr;
                  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
                    {
-                     if (STACK_ARGSIZE == 8 &&
+                     if (MIPS_STACK_ARGSIZE == 8 &&
                          (typecode == TYPE_CODE_INT ||
                           typecode == TYPE_CODE_PTR ||
                           typecode == TYPE_CODE_FLT) && len <= 4)
-                       longword_offset = STACK_ARGSIZE - len;
+                       longword_offset = MIPS_STACK_ARGSIZE - len;
                      else if ((typecode == TYPE_CODE_STRUCT ||
                                typecode == TYPE_CODE_UNION) &&
-                              TYPE_LENGTH (arg_type) < STACK_ARGSIZE)
-                       longword_offset = STACK_ARGSIZE - len;
+                              TYPE_LENGTH (arg_type) < MIPS_STACK_ARGSIZE)
+                       longword_offset = MIPS_STACK_ARGSIZE - len;
                    }
 
-                 write_memory (sp + stack_offset + longword_offset,
-                               val, partial_len);
+                 if (mips_debug)
+                   {
+                     fprintf_unfiltered (gdb_stdlog, " stack_offset=0x%lx",
+                                         (long) stack_offset);
+                     fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%lx",
+                                         (long) longword_offset);
+                   }
+                   
+                 addr = sp + stack_offset + longword_offset;
+
+                 if (mips_debug)
+                   {
+                     int i;
+                     fprintf_unfiltered (gdb_stdlog, " @0x%lx ", (long) addr);
+                     for (i = 0; i < partial_len; i++)
+                       {
+                         fprintf_unfiltered (gdb_stdlog, "%02x", val[i] & 0xff);
+                       }
+                   }
+                 write_memory (addr, val, partial_len);
                }
 
              /* Note!!! This is NOT an else clause.
                 Odd sized structs may go thru BOTH paths.  */
              if (argreg <= MIPS_LAST_ARG_REGNUM)
                {
-                 CORE_ADDR regval = extract_address (val, partial_len);
+                 LONGEST regval = extract_unsigned_integer (val, partial_len);
 
                  /* A non-floating-point argument being passed in a 
                     general register.  If a struct or union, and if
@@ -2199,6 +2318,10 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
                    regval <<= ((MIPS_SAVED_REGSIZE - partial_len) *
                                TARGET_CHAR_BIT);
 
+                 if (mips_debug)
+                   fprintf_filtered (gdb_stdlog, " reg=%d val=%s",
+                                     argreg,
+                                     phex (regval, MIPS_SAVED_REGSIZE));
                  write_register (argreg, regval);
                  argreg++;
 
@@ -2222,11 +2345,12 @@ mips_push_arguments (nargs, args, sp, struct_return, struct_addr)
                 stack offset does not get incremented until after
                 we have used up the 8 parameter registers.  */
 
-             if (!(MIPS_EABI || MIPS_NABI32) ||
-                 argnum >= 8)
-               stack_offset += ROUND_UP (partial_len, STACK_ARGSIZE);
+             if (MIPS_REGS_HAVE_HOME_P || argnum >= 8)
+               stack_offset += ROUND_UP (partial_len, MIPS_STACK_ARGSIZE);
            }
        }
+      if (mips_debug)
+       fprintf_unfiltered (gdb_stdlog, "\n");
     }
 
   /* Return adjusted stack pointer.  */
@@ -2657,7 +2781,7 @@ mips_frame_num_args (frame)
 
 /* Is this a branch with a delay slot?  */
 
-static int is_delayed PARAMS ((unsigned long));
+static int is_delayed (unsigned long);
 
 static int
 is_delayed (insn)
@@ -2956,7 +3080,8 @@ struct return_value_word
   int buf_offset;
 };
 
-static void return_value_location PARAMS ((struct type *, struct return_value_word *, struct return_value_word *));
+static void return_value_location (struct type *, struct return_value_word *,
+                                  struct return_value_word *);
 
 static void
 return_value_location (valtype, hi, lo)
@@ -3182,7 +3307,7 @@ in_sigtramp (pc, ignore)
 /* Root of all "set mips "/"show mips " commands. This will eventually be
    used for all MIPS-specific commands.  */
 
-static void show_mips_command PARAMS ((char *, int));
+static void show_mips_command (char *, int);
 static void
 show_mips_command (args, from_tty)
      char *args;
@@ -3191,7 +3316,7 @@ show_mips_command (args, from_tty)
   help_list (showmipscmdlist, "show mips ", all_commands, gdb_stdout);
 }
 
-static void set_mips_command PARAMS ((char *, int));
+static void set_mips_command (char *, int);
 static void
 set_mips_command (args, from_tty)
      char *args;
@@ -3203,7 +3328,7 @@ set_mips_command (args, from_tty)
 
 /* Commands to show/set the MIPS FPU type.  */
 
-static void show_mipsfpu_command PARAMS ((char *, int));
+static void show_mipsfpu_command (char *, int);
 static void
 show_mipsfpu_command (args, from_tty)
      char *args;
@@ -3232,7 +3357,7 @@ show_mipsfpu_command (args, from_tty)
 }
 
 
-static void set_mipsfpu_command PARAMS ((char *, int));
+static void set_mipsfpu_command (char *, int);
 static void
 set_mipsfpu_command (args, from_tty)
      char *args;
@@ -3242,7 +3367,7 @@ set_mipsfpu_command (args, from_tty)
   show_mipsfpu_command (args, from_tty);
 }
 
-static void set_mipsfpu_single_command PARAMS ((char *, int));
+static void set_mipsfpu_single_command (char *, int);
 static void
 set_mipsfpu_single_command (args, from_tty)
      char *args;
@@ -3256,7 +3381,7 @@ set_mipsfpu_single_command (args, from_tty)
     }
 }
 
-static void set_mipsfpu_double_command PARAMS ((char *, int));
+static void set_mipsfpu_double_command (char *, int);
 static void
 set_mipsfpu_double_command (args, from_tty)
      char *args;
@@ -3270,7 +3395,7 @@ set_mipsfpu_double_command (args, from_tty)
     }
 }
 
-static void set_mipsfpu_none_command PARAMS ((char *, int));
+static void set_mipsfpu_none_command (char *, int);
 static void
 set_mipsfpu_none_command (args, from_tty)
      char *args;
@@ -3284,7 +3409,7 @@ set_mipsfpu_none_command (args, from_tty)
     }
 }
 
-static void set_mipsfpu_auto_command PARAMS ((char *, int));
+static void set_mipsfpu_auto_command (char *, int);
 static void
 set_mipsfpu_auto_command (args, from_tty)
      char *args;
@@ -3714,6 +3839,72 @@ mips_coerce_float_to_double (struct type *formal, struct type *actual)
   return current_language->la_language == language_c;
 }
 
+/* When debugging a 64 MIPS target running a 32 bit ABI, the size of
+   the register stored on the stack (32) is different to its real raw
+   size (64).  The below ensures that registers are fetched from the
+   stack using their ABI size and then stored into the RAW_BUFFER
+   using their raw size.
+
+   The alternative to adding this function would be to add an ABI
+   macro - REGISTER_STACK_SIZE(). */
+
+static void
+mips_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+     char *raw_buffer;
+     int *optimized;
+     CORE_ADDR *addrp;
+     struct frame_info *frame;
+     int regnum;
+     enum lval_type *lval;
+{
+  CORE_ADDR addr;
+
+  if (!target_has_registers)
+    error ("No registers.");
+
+  /* Normal systems don't optimize out things with register numbers.  */
+  if (optimized != NULL)
+    *optimized = 0;
+  addr = find_saved_register (frame, regnum);
+  if (addr != 0)
+    {
+      if (lval != NULL)
+       *lval = lval_memory;
+      if (regnum == SP_REGNUM)
+       {
+         if (raw_buffer != NULL)
+           {
+             /* Put it back in target format.  */
+             store_address (raw_buffer, REGISTER_RAW_SIZE (regnum),
+                            (LONGEST) addr);
+           }
+         if (addrp != NULL)
+           *addrp = 0;
+         return;
+       }
+      if (raw_buffer != NULL)
+       {
+         LONGEST val;
+         if (regnum < 32)
+           /* Only MIPS_SAVED_REGSIZE bytes of GP registers are
+               saved. */
+           val = read_memory_integer (addr, MIPS_SAVED_REGSIZE);
+         else
+           val = read_memory_integer (addr, REGISTER_RAW_SIZE (regnum));
+         store_address (raw_buffer, REGISTER_RAW_SIZE (regnum), val);
+       }
+    }
+  else
+    {
+      if (lval != NULL)
+       *lval = lval_register;
+      addr = REGISTER_BYTE (regnum);
+      if (raw_buffer != NULL)
+       read_register_gen (regnum, raw_buffer);
+    }
+  if (addrp != NULL)
+    *addrp = addr;
+}
 
 static gdbarch_init_ftype mips_gdbarch_init;
 static struct gdbarch *
@@ -3726,9 +3917,13 @@ mips_gdbarch_init (info, arches)
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
   int elf_flags;
-  char *ef_mips_abi;
+#if 0
   int ef_mips_bitptrs;
+#endif
+#if 0
   int ef_mips_arch;
+#endif
+  enum mips_abi mips_abi;
 
   /* Extract the elf_flags if available */
   if (info.abfd != NULL
@@ -3737,6 +3932,66 @@ mips_gdbarch_init (info, arches)
   else
     elf_flags = 0;
 
+  /* Check ELF_FLAGS to see if it specifies the ABI being used. */
+  switch ((elf_flags & EF_MIPS_ABI))
+    {
+    case E_MIPS_ABI_O32:
+      mips_abi = MIPS_ABI_O32;
+      break;
+    case E_MIPS_ABI_O64:
+      mips_abi = MIPS_ABI_O64;
+      break;
+    case E_MIPS_ABI_EABI32:
+      mips_abi = MIPS_ABI_EABI32;
+      break;
+    case E_MIPS_ABI_EABI64:
+      mips_abi = MIPS_ABI_EABI64;
+      break;
+    default:
+      mips_abi = MIPS_ABI_UNKNOWN;
+      break;
+    }
+  /* Try the architecture for any hint of the corect ABI */
+  if (mips_abi == MIPS_ABI_UNKNOWN
+      && info.bfd_arch_info != NULL
+      && info.bfd_arch_info->arch == bfd_arch_mips)
+    {
+      switch (info.bfd_arch_info->mach)
+       {
+       case bfd_mach_mips3900:
+         mips_abi = MIPS_ABI_EABI32;
+         break;
+       case bfd_mach_mips4100:
+       case bfd_mach_mips5000:
+         mips_abi = MIPS_ABI_EABI64;
+         break;
+       }
+    }
+#ifdef MIPS_DEFAULT_ABI
+  if (mips_abi == MIPS_ABI_UNKNOWN)
+    mips_abi = MIPS_DEFAULT_ABI;
+#endif
+
+  if (gdbarch_debug)
+    {
+      fprintf_unfiltered (gdb_stdlog,
+                         "mips_gdbarch_init: elf_flags = 0x%08x\n",
+                         elf_flags);
+#if 0
+      fprintf_unfiltered (gdb_stdlog,
+                         "mips_gdbarch_init: ef_mips_arch = %d\n",
+                         ef_mips_arch);
+#endif
+#if 0
+      fprintf_unfiltered (gdb_stdlog,
+                         "mips_gdbarch_init: ef_mips_bitptrs = %d\n",
+                         ef_mips_bitptrs);
+#endif
+      fprintf_unfiltered (gdb_stdlog,
+                         "mips_gdbarch_init: mips_abi = %d\n",
+                         mips_abi);
+    }
+
   /* try to find a pre-existing architecture */
   for (arches = gdbarch_list_lookup_by_info (arches, &info);
        arches != NULL;
@@ -3746,6 +4001,8 @@ mips_gdbarch_init (info, arches)
          using. */
       if (gdbarch_tdep (current_gdbarch)->elf_flags != elf_flags)
        continue;
+      if (gdbarch_tdep (current_gdbarch)->mips_abi != mips_abi)
+       continue;
       return arches->gdbarch;
     }
 
@@ -3760,49 +4017,77 @@ mips_gdbarch_init (info, arches)
   set_gdbarch_float_bit (gdbarch, 32);
   set_gdbarch_double_bit (gdbarch, 64);
   set_gdbarch_long_double_bit (gdbarch, 64);
-  switch ((elf_flags & EF_MIPS_ABI))
+  tdep->mips_abi = mips_abi;
+  switch (mips_abi)
     {
-    case E_MIPS_ABI_O32:
-      ef_mips_abi = "o32";
-      tdep->mips_eabi = 0;
+    case MIPS_ABI_O32:
       tdep->mips_default_saved_regsize = 4;
+      tdep->mips_default_stack_argsize = 4;
       tdep->mips_fp_register_double = 0;
+      tdep->mips_last_arg_regnum = ZERO_REGNUM + 7;
+      tdep->mips_last_fp_arg_regnum = FP0_REGNUM + 15;
+      tdep->mips_regs_have_home_p = 1;
+      tdep->gdb_target_is_mips64 = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
-    case E_MIPS_ABI_O64:
-      ef_mips_abi = "o64";
-      tdep->mips_eabi = 0;
+    case MIPS_ABI_O64:
       tdep->mips_default_saved_regsize = 8;
+      tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
+      tdep->mips_last_arg_regnum = ZERO_REGNUM + 7;
+      tdep->mips_last_fp_arg_regnum = FP0_REGNUM + 15;
+      tdep->mips_regs_have_home_p = 1;
+      tdep->gdb_target_is_mips64 = 1;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
-    case E_MIPS_ABI_EABI32:
-      ef_mips_abi = "eabi32";
-      tdep->mips_eabi = 1;
+    case MIPS_ABI_EABI32:
       tdep->mips_default_saved_regsize = 4;
+      tdep->mips_default_stack_argsize = 4;
       tdep->mips_fp_register_double = 0;
+      tdep->mips_last_arg_regnum = ZERO_REGNUM + 11;
+      tdep->mips_last_fp_arg_regnum = FP0_REGNUM + 19;
+      tdep->mips_regs_have_home_p = 0;
+      tdep->gdb_target_is_mips64 = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
-    case E_MIPS_ABI_EABI64:
-      ef_mips_abi = "eabi64";
-      tdep->mips_eabi = 1;
+    case MIPS_ABI_EABI64:
       tdep->mips_default_saved_regsize = 8;
+      tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
+      tdep->mips_last_arg_regnum = ZERO_REGNUM + 11;
+      tdep->mips_last_fp_arg_regnum = FP0_REGNUM + 19;
+      tdep->mips_regs_have_home_p = 0;
+      tdep->gdb_target_is_mips64 = 1;
       set_gdbarch_long_bit (gdbarch, 64);
       set_gdbarch_ptr_bit (gdbarch, 64);
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
+    case MIPS_ABI_N32:
+      tdep->mips_default_saved_regsize = 4;
+      tdep->mips_default_stack_argsize = 8;
+      tdep->mips_fp_register_double = 1;
+      tdep->mips_last_arg_regnum = ZERO_REGNUM + 11;
+      tdep->mips_last_fp_arg_regnum = FP0_REGNUM + 19;
+      tdep->mips_regs_have_home_p = 0;
+      tdep->gdb_target_is_mips64 = 0;
+      set_gdbarch_long_bit (gdbarch, 32);
+      set_gdbarch_ptr_bit (gdbarch, 32);
+      set_gdbarch_long_long_bit (gdbarch, 64);
+      break;
     default:
-      ef_mips_abi = "default";
-      tdep->mips_eabi = 0;
       tdep->mips_default_saved_regsize = MIPS_REGSIZE;
+      tdep->mips_default_stack_argsize = MIPS_REGSIZE;
       tdep->mips_fp_register_double = (REGISTER_VIRTUAL_SIZE (FP0_REGNUM) == 8);
+      tdep->mips_last_arg_regnum = ZERO_REGNUM + 11;
+      tdep->mips_last_fp_arg_regnum = FP0_REGNUM + 19;
+      tdep->mips_regs_have_home_p = 1;
+      tdep->gdb_target_is_mips64 = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
@@ -3830,6 +4115,7 @@ mips_gdbarch_init (info, arches)
      the current gcc - it would make GDB treat these 64-bit programs
      as 32-bit programs by default. */
 
+#if 0
   /* determine the ISA */
   switch (elf_flags & EF_MIPS_ARCH)
     {
@@ -3848,6 +4134,7 @@ mips_gdbarch_init (info, arches)
     default:
       break;
     }
+#endif
 
 #if 0
   /* determine the size of a pointer */
@@ -3865,22 +4152,6 @@ mips_gdbarch_init (info, arches)
     }
 #endif
 
-  /* Select either of the two alternative ABI's */
-  if (tdep->mips_eabi)
-    {
-      /* EABI uses R4 through R11 for args */
-      tdep->mips_last_arg_regnum = 11;
-      /* EABI uses F12 through F19 for args */
-      tdep->mips_last_fp_arg_regnum = FP0_REGNUM + 19;
-    }
-  else
-    {
-      /* old ABI uses R4 through R7 for args */
-      tdep->mips_last_arg_regnum = 7;
-      /* old ABI uses F12 through F15 for args */
-      tdep->mips_last_fp_arg_regnum = FP0_REGNUM + 15;
-    }
-
   /* enable/disable the MIPS FPU */
   if (!mips_fpu_type_auto)
     tdep->mips_fpu_type = mips_fpu_type;
@@ -3888,10 +4159,14 @@ mips_gdbarch_init (info, arches)
           && info.bfd_arch_info->arch == bfd_arch_mips)
     switch (info.bfd_arch_info->mach)
       {
+      case bfd_mach_mips3900:
       case bfd_mach_mips4100:
       case bfd_mach_mips4111:
        tdep->mips_fpu_type = MIPS_FPU_NONE;
        break;
+      case bfd_mach_mips4650:
+       tdep->mips_fpu_type = MIPS_FPU_SINGLE;
+       break;
       default:
        tdep->mips_fpu_type = MIPS_FPU_DOUBLE;
        break;
@@ -3934,51 +4209,393 @@ mips_gdbarch_init (info, arches)
   set_gdbarch_coerce_float_to_double (gdbarch, mips_coerce_float_to_double);
 
   set_gdbarch_frame_chain_valid (gdbarch, func_frame_chain_valid);
-  set_gdbarch_get_saved_register (gdbarch, default_get_saved_register);
-
-  if (gdbarch_debug)
-    {
-      fprintf_unfiltered (gdb_stderr,
-                         "mips_gdbarch_init: (info)elf_flags = 0x%x\n",
-                         elf_flags);
-      fprintf_unfiltered (gdb_stderr,
-                         "mips_gdbarch_init: (info)ef_mips_abi = %s\n",
-                         ef_mips_abi);
-      fprintf_unfiltered (gdb_stderr,
-                         "mips_gdbarch_init: (info)ef_mips_arch = %d\n",
-                         ef_mips_arch);
-      fprintf_unfiltered (gdb_stderr,
-                         "mips_gdbarch_init: (info)ef_mips_bitptrs = %d\n",
-                         ef_mips_bitptrs);
-      fprintf_unfiltered (gdb_stderr,
-                         "mips_gdbarch_init: MIPS_EABI = %d\n",
-                         tdep->mips_eabi);
-      fprintf_unfiltered (gdb_stderr,
-                         "mips_gdbarch_init: MIPS_LAST_ARG_REGNUM = %d\n",
-                         tdep->mips_last_arg_regnum);
-      fprintf_unfiltered (gdb_stderr,
-                  "mips_gdbarch_init: MIPS_LAST_FP_ARG_REGNUM = %d (%d)\n",
-                         tdep->mips_last_fp_arg_regnum,
-                         tdep->mips_last_fp_arg_regnum - FP0_REGNUM);
-      fprintf_unfiltered (gdb_stderr,
-                      "mips_gdbarch_init: tdep->mips_fpu_type = %d (%s)\n",
-                         tdep->mips_fpu_type,
-                         (tdep->mips_fpu_type == MIPS_FPU_NONE ? "none"
-                        : tdep->mips_fpu_type == MIPS_FPU_SINGLE ? "single"
-                        : tdep->mips_fpu_type == MIPS_FPU_DOUBLE ? "double"
-                          : "???"));
-      fprintf_unfiltered (gdb_stderr,
-                      "mips_gdbarch_init: tdep->mips_default_saved_regsize = %d\n",
-                         tdep->mips_default_saved_regsize);
-      fprintf_unfiltered (gdb_stderr,
-            "mips_gdbarch_init: tdep->mips_fp_register_double = %d (%s)\n",
-                         tdep->mips_fp_register_double,
-                       (tdep->mips_fp_register_double ? "true" : "false"));
-    }
+  set_gdbarch_get_saved_register (gdbarch, mips_get_saved_register);
 
   return gdbarch;
 }
 
+static void
+mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
+  if (tdep != NULL)
+    {
+      fprintf_unfiltered (file,
+                         "mips_dump_tdep: tdep->elf_flags = 0x%x\n",
+                         tdep->elf_flags);
+      fprintf_unfiltered (file,
+                         "mips_dump_tdep: tdep->mips_abi = %d\n",
+                         tdep->mips_abi);
+    }
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: FP_REGISTER_DOUBLE = %d\n",
+                     FP_REGISTER_DOUBLE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_DEFAULT_FPU_TYPE = %d (%s)\n",
+                     MIPS_DEFAULT_FPU_TYPE,
+                     (MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_NONE ? "none"
+                      : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
+                      : MIPS_DEFAULT_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
+                      : "???"));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_EABI = %d\n",
+                     MIPS_EABI);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_LAST_FP_ARG_REGNUM = %d\n",
+                     MIPS_LAST_FP_ARG_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
+                     MIPS_FPU_TYPE,
+                     (MIPS_FPU_TYPE == MIPS_FPU_NONE ? "none"
+                      : MIPS_FPU_TYPE == MIPS_FPU_SINGLE ? "single"
+                      : MIPS_FPU_TYPE == MIPS_FPU_DOUBLE ? "double"
+                      : "???"));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_DEFAULT_SAVED_REGSIZE = %d\n",
+                     MIPS_DEFAULT_SAVED_REGSIZE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: FP_REGISTER_DOUBLE = %d\n",
+                     FP_REGISTER_DOUBLE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_REGS_HAVE_HOME_P = %d\n",
+                     MIPS_REGS_HAVE_HOME_P);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_DEFAULT_STACK_ARGSIZE = %d\n",
+                     MIPS_DEFAULT_STACK_ARGSIZE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_STACK_ARGSIZE = %d\n",
+                     MIPS_STACK_ARGSIZE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_REGSIZE = %d\n",
+                     MIPS_REGSIZE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: A0_REGNUM = %d\n",
+                     A0_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: ADDR_BITS_REMOVE # %s\n",
+                     XSTRING (ADDR_BITS_REMOVE(ADDR)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: ATTACH_DETACH # %s\n",
+                     XSTRING (ATTACH_DETACH));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: 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);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: CPLUS_MARKER = %c\n",
+                     CPLUS_MARKER);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: DEFAULT_MIPS_TYPE = %s\n",
+                     DEFAULT_MIPS_TYPE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: DO_REGISTERS_INFO # %s\n",
+                     XSTRING (DO_REGISTERS_INFO));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: DWARF_REG_TO_REGNUM # %s\n",
+                     XSTRING (DWARF_REG_TO_REGNUM (REGNUM)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: ECOFF_REG_TO_REGNUM # %s\n",
+                     XSTRING (ECOFF_REG_TO_REGNUM (REGNUM)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: ELF_MAKE_MSYMBOL_SPECIAL # %s\n",
+                     XSTRING (ELF_MAKE_MSYMBOL_SPECIAL (SYM, MSYM)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: FCRCS_REGNUM = %d\n",
+                     FCRCS_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: FCRIR_REGNUM = %d\n",
+                     FCRIR_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: FIRST_EMBED_REGNUM = %d\n",
+                     FIRST_EMBED_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: FPA0_REGNUM = %d\n",
+                     FPA0_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: GDB_TARGET_IS_MIPS64 = %d\n",
+                     GDB_TARGET_IS_MIPS64);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: GDB_TARGET_MASK_DISAS_PC # %s\n",
+                     XSTRING (GDB_TARGET_MASK_DISAS_PC (PC)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: GDB_TARGET_UNMASK_DISAS_PC # %s\n",
+                     XSTRING (GDB_TARGET_UNMASK_DISAS_PC (PC)));
+  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)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: INIT_FRAME_PC # %s\n",
+                     XSTRING (INIT_FRAME_PC (FROMLEAF, PREV)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: INIT_FRAME_PC_FIRST # %s\n",
+                     XSTRING (INIT_FRAME_PC_FIRST (FROMLEAF, PREV)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: IN_SIGTRAMP # %s\n",
+                     XSTRING (IN_SIGTRAMP (PC, NAME)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: IN_SOLIB_CALL_TRAMPOLINE # %s\n",
+                     XSTRING (IN_SOLIB_CALL_TRAMPOLINE (PC, NAME)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: 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);
+#ifdef MACHINE_CPROC_FP_OFFSET
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MACHINE_CPROC_FP_OFFSET = %d\n",
+                     MACHINE_CPROC_FP_OFFSET);
+#endif
+#ifdef MACHINE_CPROC_PC_OFFSET
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MACHINE_CPROC_PC_OFFSET = %d\n",
+                     MACHINE_CPROC_PC_OFFSET);
+#endif
+#ifdef MACHINE_CPROC_SP_OFFSET
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MACHINE_CPROC_SP_OFFSET = %d\n",
+                     MACHINE_CPROC_SP_OFFSET);
+#endif
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: 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,
+                     "mips_dump_tdep: MIPS_EFI_SYMBOL_NAME = multi-arch!!\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_INSTLEN = %d\n",
+                     MIPS_INSTLEN);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_LAST_ARG_REGNUM = %d\n",
+                     MIPS_LAST_ARG_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_NUMREGS = %d\n",
+                     MIPS_NUMREGS);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_REGISTER_NAMES = delete?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MIPS_SAVED_REGSIZE = %d\n",
+                     MIPS_SAVED_REGSIZE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MSYMBOL_IS_SPECIAL = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: MSYMBOL_SIZE # %s\n",
+                     XSTRING (MSYMBOL_SIZE (MSYM)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: OP_LDFPR = used?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: OP_LDGPR = used?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: 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);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PRINT_EXTRA_FRAME_INFO # %s\n",
+                     XSTRING (PRINT_EXTRA_FRAME_INFO (FRAME)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_DESC_IS_DUMMY = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_FRAME_ADJUST = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_FRAME_OFFSET = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_FRAME_REG = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_FREG_MASK = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_FREG_OFFSET = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_HIGH_ADDR = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_LOW_ADDR = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_PC_REG = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_REG_MASK = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_REG_OFFSET = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PROC_SYMBOL = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: PS_REGNUM = %d\n",
+                     PS_REGNUM);
+  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);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: REGISTER_CONVERT_FROM_TYPE # %s\n",
+                     XSTRING (REGISTER_CONVERT_FROM_TYPE (REGNUM, VALTYPE, RAW_BUFFER)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: REGISTER_CONVERT_TO_TYPE # %s\n",
+                     XSTRING (REGISTER_CONVERT_TO_TYPE (REGNUM, VALTYPE, RAW_BUFFER)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: REGISTER_NAMES = delete?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: ROUND_DOWN = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: ROUND_UP = function?\n");
+#ifdef SAVED_BYTES
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SAVED_BYTES = %d\n",
+                     SAVED_BYTES);
+#endif
+#ifdef SAVED_FP
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SAVED_FP = %d\n",
+                     SAVED_FP);
+#endif
+#ifdef SAVED_PC
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SAVED_PC = %d\n",
+                     SAVED_PC);
+#endif
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SETUP_ARBITRARY_FRAME # %s\n",
+                     XSTRING (SETUP_ARBITRARY_FRAME (NUMARGS, ARGS)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SET_PROC_DESC_IS_DUMMY = function?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SIGFRAME_BASE = %d\n",
+                     SIGFRAME_BASE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SIGFRAME_FPREGSAVE_OFF = %d\n",
+                     SIGFRAME_FPREGSAVE_OFF);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SIGFRAME_PC_OFF = %d\n",
+                     SIGFRAME_PC_OFF);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SIGFRAME_REGSAVE_OFF = %d\n",
+                     SIGFRAME_REGSAVE_OFF);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SIGFRAME_REG_SIZE = %d\n",
+                     SIGFRAME_REG_SIZE);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SKIP_TRAMPOLINE_CODE # %s\n",
+                     XSTRING (SKIP_TRAMPOLINE_CODE (PC)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SOFTWARE_SINGLE_STEP # %s\n",
+                     XSTRING (SOFTWARE_SINGLE_STEP (SIG, BP_P)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P = %d\n",
+                     SOFTWARE_SINGLE_STEP_P);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: SOFTWARE_SINGLE_STEP_P = %d\n",
+                     SOFTWARE_SINGLE_STEP_P);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: STAB_REG_TO_REGNUM # %s\n",
+                     XSTRING (STAB_REG_TO_REGNUM (REGNUM)));
+#ifdef STACK_END_ADDR
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: STACK_END_ADDR = %d\n",
+                     STACK_END_ADDR);
+#endif
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: STEP_SKIPS_DELAY # %s\n",
+                     XSTRING (STEP_SKIPS_DELAY (PC)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: STEP_SKIPS_DELAY_P = %d\n",
+                     STEP_SKIPS_DELAY_P);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: STOPPED_BY_WATCHPOINT # %s\n",
+                     XSTRING (STOPPED_BY_WATCHPOINT (WS)));
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: T9_REGNUM = %d\n",
+                     T9_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: TABULAR_REGISTER_OUTPUT = used?\n");
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: TARGET_CAN_USE_HARDWARE_WATCHPOINT # %s\n",
+                     XSTRING (TARGET_CAN_USE_HARDWARE_WATCHPOINT (TYPE,CNT,OTHERTYPE)));
+  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",
+                     XSTRING (TRACE_CLEAR (THREAD, STATE)));
+#endif
+#ifdef TRACE_FLAVOR
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: TRACE_FLAVOR = %d\n",
+                     TRACE_FLAVOR);
+#endif
+#ifdef TRACE_FLAVOR_SIZE
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: TRACE_FLAVOR_SIZE = %d\n",
+                     TRACE_FLAVOR_SIZE);
+#endif
+#ifdef TRACE_SET
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: TRACE_SET # %s\n",
+                     XSTRING (TRACE_SET (X,STATE)));
+#endif
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: UNMAKE_MIPS16_ADDR = function?\n");
+#ifdef UNUSED_REGNUM
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: UNUSED_REGNUM = %d\n",
+                     UNUSED_REGNUM);
+#endif
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: V0_REGNUM = %d\n",
+                     V0_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: VM_MIN_ADDRESS = %ld\n",
+                     (long) VM_MIN_ADDRESS);
+#ifdef VX_NUM_REGS
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: VX_NUM_REGS = %d (used?)\n",
+                     VX_NUM_REGS);
+#endif
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: ZERO_REGNUM = %d\n",
+                     ZERO_REGNUM);
+  fprintf_unfiltered (file,
+                     "mips_dump_tdep: _PROC_MAGIC_ = %d\n",
+                     _PROC_MAGIC_);
+}
 
 void
 _initialize_mips_tdep ()
@@ -3986,8 +4603,7 @@ _initialize_mips_tdep ()
   static struct cmd_list_element *mipsfpulist = NULL;
   struct cmd_list_element *c;
 
-  if (GDB_MULTI_ARCH)
-    register_gdbarch_init (bfd_arch_mips, mips_gdbarch_init);
+  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;
 
@@ -4002,9 +4618,9 @@ _initialize_mips_tdep ()
 
   /* Allow the user to override the saved register size. */
   add_show_from_set (add_set_enum_cmd ("saved-gpreg-size",
-                                 class_obscure,
-                                 saved_gpreg_size_enums,
-                                 (char *) &mips_saved_regsize_string, "\
+                                      class_obscure,
+                                      size_enums,
+                                      &mips_saved_regsize_string, "\
 Set size of general purpose registers saved on the stack.\n\
 This option can be set to one of:\n\
   32    - Force GDB to treat saved GP registers as 32-bit\n\
@@ -4012,7 +4628,21 @@ This option can be set to one of:\n\
   auto  - Allow GDB to use the target's default setting or autodetect the\n\
           saved GP register size from information contained in the executable.\n\
           (default: auto)",
-                                 &setmipscmdlist),
+                                      &setmipscmdlist),
+                    &showmipscmdlist);
+
+  /* Allow the user to override the argument stack size. */
+  add_show_from_set (add_set_enum_cmd ("stack-arg-size",
+                                      class_obscure,
+                                      size_enums,
+                                      &mips_stack_argsize_string, "\
+Set the amount of stack space reserved for each argument.\n\
+This option can be set to one of:\n\
+  32    - Force GDB to allocate 32-bit chunks per argument\n\
+  64    - Force GDB to allocate 64-bit chunks per argument\n\
+  auto  - Allow GDB to determine the correct setting from the current\n\
+          target and executable (default)",
+                                      &setmipscmdlist),
                     &showmipscmdlist);
 
   /* Let the user turn off floating point and set the fence post for
@@ -4095,4 +4725,11 @@ that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
 64 bits for others.  Use \"off\" to disable compatibility mode",
                                  &setlist),
                     &showlist);
+
+  /* Debug this files internals. */
+  add_show_from_set (add_set_cmd ("mips", class_maintenance, var_zinteger,
+                                 &mips_debug, "Set mips debugging.\n\
+When non-zero, mips specific debugging is enabled.", &setdebuglist),
+                    &showdebuglist);
 }
+
This page took 0.040076 seconds and 4 git commands to generate.