* gdbarch.sh (gdbarch_data): Add gdbarch parameter.
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index 3d119c8aacc710dca9adcd3e4f05e16964642fcc..16ebaca7eb762a7ae3e03765033c89c500576b10 100644 (file)
@@ -1,7 +1,7 @@
 /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
 
    Copyright 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, Free Software Foundation, Inc.
+   1997, 1998, 1999, 2000, 2001, 2002 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 "gdbtypes.h"
 #include "target.h"
 #include "arch-utils.h"
+#include "regcache.h"
 
 #include "opcode/mips.h"
 #include "elf/mips.h"
 #include "elf-bfd.h"
 #include "symcat.h"
 
+/* 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)
+
 /* The sizes of floating point registers.  */
 
 enum
@@ -173,6 +178,31 @@ mips_saved_regsize (void)
     return 4;
 }
 
+/* Determine if a MIPS3 or later cpu is operating in MIPS{1,2} FPU
+   compatiblity mode.  A return value of 1 means that we have
+   physical 64-bit registers, but should treat them as 32-bit registers.  */
+
+static int
+mips2_fp_compat (void)
+{
+  /* MIPS1 and MIPS2 have only 32 bit FPRs, and the FR bit is not
+     meaningful.  */
+  if (REGISTER_RAW_SIZE (FP0_REGNUM) == 4)
+    return 0;
+
+#if 0
+  /* FIXME drow 2002-03-10: This is disabled until we can do it consistently,
+     in all the places we deal with FP registers.  PR gdb/413.  */
+  /* Otherwise check the FR bit in the status register - it controls
+     the FP compatiblity mode.  If it is clear we are in compatibility
+     mode.  */
+  if ((read_register (PS_REGNUM) & ST0_FR) == 0)
+    return 1;
+#endif
+
+  return 0;
+}
+
 /* 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
@@ -238,7 +268,7 @@ 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 *);
+heuristic_proc_desc (CORE_ADDR, CORE_ADDR, struct frame_info *, int);
 
 static CORE_ADDR heuristic_proc_start (CORE_ADDR);
 
@@ -251,11 +281,17 @@ static void mips_show_processor_type_command (char *, int);
 static void reinit_frame_cache_sfunc (char *, int, struct cmd_list_element *);
 
 static mips_extra_func_info_t
-find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame);
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame);
 
 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);
+
 /* This value is the model of MIPS in use.  It is derived from the value
    of the PrID register.  */
 
@@ -409,8 +445,9 @@ mips_print_extra_frame_info (struct frame_info *fi)
                     paddr_d (fi->extra_info->proc_desc->pdr.frameoffset));
 }
 
-/* Convert between RAW and VIRTUAL registers.  The RAW register size
-   defines the remote-gdb packet. */
+/* Number of bytes of storage in the actual machine representation for
+   register N.  NOTE: This indirectly defines the register size
+   transfered by the GDB protocol. */
 
 static int mips64_transfers_32bit_regs_p = 0;
 
@@ -419,10 +456,18 @@ mips_register_raw_size (int reg_nr)
 {
   if (mips64_transfers_32bit_regs_p)
     return REGISTER_VIRTUAL_SIZE (reg_nr);
+  else if (reg_nr >= FP0_REGNUM && reg_nr < FP0_REGNUM + 32
+          && FP_REGISTER_DOUBLE)
+    /* For MIPS_ABI_N32 (for example) we need 8 byte floating point
+       registers.  */
+    return 8;
   else
     return MIPS_REGSIZE;
 }
 
+/* Convert between RAW and VIRTUAL registers.  The RAW register size
+   defines the remote-gdb packet. */
+
 int
 mips_register_convertible (int reg_nr)
 {
@@ -436,7 +481,7 @@ void
 mips_register_convert_to_virtual (int n, struct type *virtual_type,
                                  char *raw_buf, char *virt_buf)
 {
-  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
     memcpy (virt_buf,
            raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
            TYPE_LENGTH (virtual_type));
@@ -451,7 +496,7 @@ mips_register_convert_to_raw (struct type *virtual_type, int n,
                              char *virt_buf, char *raw_buf)
 {
   memset (raw_buf, 0, REGISTER_RAW_SIZE (n));
-  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
     memcpy (raw_buf + (REGISTER_RAW_SIZE (n) - TYPE_LENGTH (virtual_type)),
            virt_buf,
            TYPE_LENGTH (virtual_type));
@@ -477,9 +522,10 @@ mips_mask_address_p (void)
     case CMD_AUTO_BOOLEAN_AUTO:
       return MIPS_DEFAULT_MASK_ADDRESS_P;
     default:
-      internal_error ("mips_mask_address_p: bad switch");
+      internal_error (__FILE__, __LINE__,
+                     "mips_mask_address_p: bad switch");
       return -1;
-    }      
+    }
 }
 
 static void
@@ -498,9 +544,10 @@ show_mask_address (char *cmd, int from_tty)
                       mips_mask_address_p () ? "enabled" : "disabled");
       break;
     default:
-      internal_error ("show_mask_address: bad switch");
+      internal_error (__FILE__, __LINE__,
+                     "show_mask_address: bad switch");
       break;
-    }      
+    }
 }
 
 /* Should call_function allocate stack space for a struct return?  */
@@ -538,9 +585,9 @@ pc_is_mips16 (bfd_vma memaddr)
    all registers should be sign extended for simplicity? */
 
 static CORE_ADDR
-mips_read_pc (int pid)
+mips_read_pc (ptid_t ptid)
 {
-  return read_signed_register_pid (PC_REGNUM, pid);
+  return read_signed_register_pid (PC_REGNUM, ptid);
 }
 
 /* This returns the PC of the first inst after the prologue.  If we can't
@@ -553,8 +600,13 @@ after_prologue (CORE_ADDR pc,
   struct symtab_and_line sal;
   CORE_ADDR func_addr, func_end;
 
+  /* Pass cur_frame == 0 to find_proc_desc.  We should not attempt
+     to read the stack pointer from the current machine state, because
+     the current machine state has nothing to do with the information
+     we need from the proc_desc; and the process may or may not exist
+     right now.  */
   if (!proc_desc)
-    proc_desc = find_proc_desc (pc, NULL);
+    proc_desc = find_proc_desc (pc, NULL, 0);
 
   if (proc_desc)
     {
@@ -661,21 +713,21 @@ mips_fetch_instruction (CORE_ADDR addr)
 
 
 /* These the fields of 32 bit mips instructions */
-#define mips32_op(x) (x >> 25)
-#define itype_op(x) (x >> 25)
-#define itype_rs(x) ((x >> 21)& 0x1f)
+#define mips32_op(x) (x >> 26)
+#define itype_op(x) (x >> 26)
+#define itype_rs(x) ((x >> 21) & 0x1f)
 #define itype_rt(x) ((x >> 16) & 0x1f)
-#define itype_immediate(x) ( x & 0xffff)
+#define itype_immediate(x) (x & 0xffff)
 
-#define jtype_op(x) (x >> 25)
-#define jtype_target(x) ( x & 0x03fffff)
+#define jtype_op(x) (x >> 26)
+#define jtype_target(x) (x & 0x03ffffff)
 
-#define rtype_op(x) (x >>25)
-#define rtype_rs(x) ((x>>21) & 0x1f)
-#define rtype_rt(x) ((x>>16)  & 0x1f)
-#define rtype_rd(x) ((x>>11) & 0x1f)
-#define rtype_shamt(x) ((x>>6) & 0x1f)
-#define rtype_funct(x) (x & 0x3f )
+#define rtype_op(x) (x >> 26)
+#define rtype_rs(x) ((x >> 21) & 0x1f)
+#define rtype_rt(x) ((x >> 16) & 0x1f)
+#define rtype_rd(x) ((x >> 11) & 0x1f)
+#define rtype_shamt(x) ((x >> 6) & 0x1f)
+#define rtype_funct(x) (x & 0x3f)
 
 static CORE_ADDR
 mips32_relative_offset (unsigned long inst)
@@ -698,25 +750,39 @@ mips32_next_pc (CORE_ADDR pc)
   unsigned long inst;
   int op;
   inst = mips_fetch_instruction (pc);
-  if ((inst & 0xe0000000) != 0)        /* Not a special, junp or branch instruction */
+  if ((inst & 0xe0000000) != 0)        /* Not a special, jump or branch instruction */
     {
-      if ((inst >> 27) == 5)   /* BEQL BNEZ BLEZL BGTZE , bits 0101xx */
+      if (itype_op (inst) >> 2 == 5)
+                               /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
        {
-         op = ((inst >> 25) & 0x03);
+         op = (itype_op (inst) & 0x03);
          switch (op)
            {
-           case 0:
-             goto equal_branch;        /* BEQL   */
-           case 1:
-             goto neq_branch;  /* BNEZ   */
-           case 2:
-             goto less_branch; /* BLEZ   */
-           case 3:
-             goto greater_branch;      /* BGTZ */
+           case 0:             /* BEQL */
+             goto equal_branch;
+           case 1:             /* BNEL */
+             goto neq_branch;
+           case 2:             /* BLEZL */
+             goto less_branch;
+           case 3:             /* BGTZ */
+             goto greater_branch;
            default:
              pc += 4;
            }
        }
+      else if (itype_op (inst) == 17 && itype_rs (inst) == 8)
+                               /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
+       {
+         int tf = itype_rt (inst) & 0x01;
+         int cnum = itype_rt (inst) >> 2;
+         int fcrcs = read_signed_register (FCRCS_REGNUM);
+         int cond = ((fcrcs >> 24) & 0x0e) | ((fcrcs >> 23) & 0x01);
+
+         if (((cond >> cnum) & 0x01) == tf)
+           pc += mips32_relative_offset (inst) + 4;
+         else
+           pc += 8;
+       }
       else
        pc += 4;                /* Not a branch, next instruction is easy */
     }
@@ -724,7 +790,7 @@ mips32_next_pc (CORE_ADDR pc)
     {                          /* This gets way messy */
 
       /* Further subdivide into SPECIAL, REGIMM and other */
-      switch (op = ((inst >> 26) & 0x07))      /* extract bits 28,27,26 */
+      switch (op = itype_op (inst) & 0x07)     /* extract bits 28,27,26 */
        {
        case 0:         /* SPECIAL */
          op = rtype_funct (inst);
@@ -739,15 +805,15 @@ mips32_next_pc (CORE_ADDR pc)
              pc += 4;
            }
 
-         break;                /* end special */
+         break;        /* end SPECIAL */
        case 1:         /* REGIMM */
          {
-           op = jtype_op (inst);       /* branch condition */
-           switch (jtype_op (inst))
+           op = itype_rt (inst);       /* branch condition */
+           switch (op)
              {
              case 0:           /* BLTZ */
-             case 2:           /* BLTXL */
-             case 16:          /* BLTZALL */
+             case 2:           /* BLTZL */
+             case 16:          /* BLTZAL */
              case 18:          /* BLTZALL */
              less_branch:
                if (read_signed_register (itype_rs (inst)) < 0)
@@ -755,7 +821,7 @@ mips32_next_pc (CORE_ADDR pc)
                else
                  pc += 8;      /* after the delay slot */
                break;
-             case 1:           /* GEZ */
+             case 1:           /* BGEZ */
              case 3:           /* BGEZL */
              case 17:          /* BGEZAL */
              case 19:          /* BGEZALL */
@@ -765,19 +831,19 @@ mips32_next_pc (CORE_ADDR pc)
                else
                  pc += 8;      /* after the delay slot */
                break;
-               /* All of the other intructions in the REGIMM catagory */
+               /* All of the other instructions in the REGIMM category */
              default:
                pc += 4;
              }
          }
-         break;                /* end REGIMM */
+         break;        /* end REGIMM */
        case 2:         /* J */
        case 3:         /* JAL */
          {
            unsigned long reg;
            reg = jtype_target (inst) << 2;
+           /* Upper four bits get never changed... */
            pc = reg + ((pc + 4) & 0xf0000000);
-           /* Whats this mysterious 0xf000000 adjustment ??? */
          }
          break;
          /* FIXME case JALX : */
@@ -788,7 +854,7 @@ mips32_next_pc (CORE_ADDR pc)
            /* Add 1 to indicate 16 bit mode - Invert ISA mode */
          }
          break;                /* The new PC will be alternate mode */
-       case 4:         /* BEQ , BEQL */
+       case 4:         /* BEQ, BEQL */
        equal_branch:
          if (read_signed_register (itype_rs (inst)) ==
              read_signed_register (itype_rt (inst)))
@@ -796,15 +862,15 @@ mips32_next_pc (CORE_ADDR pc)
          else
            pc += 8;
          break;
-       case 5:         /* BNE , BNEL */
+       case 5:         /* BNE, BNEL */
        neq_branch:
          if (read_signed_register (itype_rs (inst)) !=
-             read_signed_register (itype_rs (inst)))
+             read_signed_register (itype_rt (inst)))
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
-       case 6:         /* BLEZ , BLEZL */
+       case 6:         /* BLEZ, BLEZL */
        less_zero_branch:
          if (read_signed_register (itype_rs (inst) <= 0))
            pc += mips32_relative_offset (inst) + 4;
@@ -812,14 +878,13 @@ mips32_next_pc (CORE_ADDR pc)
            pc += 8;
          break;
        case 7:
-       greater_branch: /* BGTZ BGTZL */
+       default:
+       greater_branch: /* BGTZ, BGTZL */
          if (read_signed_register (itype_rs (inst) > 0))
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
-       default:
-         pc += 8;
        }                       /* switch */
     }                          /* else */
   return pc;
@@ -982,7 +1047,8 @@ unpack_mips16 (CORE_ADDR pc,
        break;
       }
     default:
-      internal_error ("%s:%d: bad switch", __FILE__, __LINE__);
+      internal_error (__FILE__, __LINE__,
+                     "bad switch");
     }
   upk->offset = offset;
   upk->regx = regx;
@@ -1331,7 +1397,7 @@ read_next_frame_reg (struct frame_info *fi, int regno)
 
 /* mips_addr_bits_remove - remove useless address bits  */
 
-CORE_ADDR
+static CORE_ADDR
 mips_addr_bits_remove (CORE_ADDR addr)
 {
   if (GDB_TARGET_IS_MIPS64)
@@ -1370,7 +1436,34 @@ mips_addr_bits_remove (CORE_ADDR addr)
   return addr;
 }
 
+/* mips_software_single_step() is called just before we want to resume
+   the inferior, if we want to single-step it but there is no hardware
+   or kernel single-step support (MIPS on GNU/Linux for example).  We find
+   the target of the coming instruction and breakpoint it.
+
+   single_step is also called just after the inferior stops.  If we had
+   set up a simulated single-step, we undo our damage.  */
+
 void
+mips_software_single_step (enum target_signal sig, int insert_breakpoints_p)
+{
+  static CORE_ADDR next_pc;
+  typedef char binsn_quantum[BREAKPOINT_MAX];
+  static binsn_quantum break_mem;
+  CORE_ADDR pc;
+
+  if (insert_breakpoints_p)
+    {
+      pc = read_register (PC_REGNUM);
+      next_pc = mips_next_pc (pc);
+
+      target_insert_breakpoint (next_pc, break_mem);
+    }
+  else
+    target_remove_breakpoint (next_pc, break_mem);
+}
+
+static void
 mips_init_frame_pc_first (int fromleaf, struct frame_info *prev)
 {
   CORE_ADDR pc, tmp;
@@ -1809,9 +1902,14 @@ restart:
 
 static mips_extra_func_info_t
 heuristic_proc_desc (CORE_ADDR start_pc, CORE_ADDR limit_pc,
-                    struct frame_info *next_frame)
+                    struct frame_info *next_frame, int cur_frame)
 {
-  CORE_ADDR sp = read_next_frame_reg (next_frame, SP_REGNUM);
+  CORE_ADDR sp;
+
+  if (cur_frame)
+    sp = read_next_frame_reg (next_frame, SP_REGNUM);
+  else
+    sp = 0;
 
   if (start_pc == 0)
     return NULL;
@@ -1870,7 +1968,7 @@ non_heuristic_proc_desc (CORE_ADDR pc, CORE_ADDR *addrptr)
 
 
 static mips_extra_func_info_t
-find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
+find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame, int cur_frame)
 {
   mips_extra_func_info_t proc_desc;
   CORE_ADDR startaddr;
@@ -1902,7 +2000,7 @@ find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
            {
              mips_extra_func_info_t found_heuristic =
              heuristic_proc_desc (PROC_LOW_ADDR (proc_desc),
-                                  pc, next_frame);
+                                  pc, next_frame, cur_frame);
              if (found_heuristic)
                proc_desc = found_heuristic;
            }
@@ -1926,7 +2024,7 @@ find_proc_desc (CORE_ADDR pc, struct frame_info *next_frame)
        startaddr = heuristic_proc_start (pc);
 
       proc_desc =
-       heuristic_proc_desc (startaddr, pc, next_frame);
+       heuristic_proc_desc (startaddr, pc, next_frame, cur_frame);
     }
   return proc_desc;
 }
@@ -1958,7 +2056,7 @@ mips_frame_chain (struct frame_info *frame)
     saved_pc = tmp;
 
   /* Look up the procedure descriptor for this PC.  */
-  proc_desc = find_proc_desc (saved_pc, frame);
+  proc_desc = find_proc_desc (saved_pc, frame, 1);
   if (!proc_desc)
     return 0;
 
@@ -1984,7 +2082,7 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
 
   /* Use proc_desc calculated in frame_chain */
   mips_extra_func_info_t proc_desc =
-  fci->next ? cached_proc_desc : find_proc_desc (fci->pc, fci->next);
+  fci->next ? cached_proc_desc : find_proc_desc (fci->pc, fci->next, 1);
 
   fci->extra_info = (struct frame_extra_info *)
     frame_obstack_alloc (sizeof (struct frame_extra_info));
@@ -2013,7 +2111,7 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
             We can't use fci->signal_handler_caller, it is not yet set.  */
          find_pc_partial_function (fci->pc, &name,
                                    (CORE_ADDR *) NULL, (CORE_ADDR *) NULL);
-         if (!IN_SIGTRAMP (fci->pc, name))
+         if (!PC_IN_SIGTRAMP (fci->pc, name))
            {
              frame_saved_regs_zalloc (fci);
              memcpy (fci->saved_regs, temp_saved_regs, SIZEOF_FRAME_SAVED_REGS);
@@ -2040,7 +2138,7 @@ mips_init_extra_frame_info (int fromleaf, struct frame_info *fci)
    we basically have to look at symbol information for the function
    that we stopped in, which tells us *which* register (if any) is
    the base of the frame pointer, and what offset from that register
-   the frame itself is at.  
+   the frame itself is at.
 
    This presents a problem when trying to examine a stack in memory
    (that isn't executing at the moment), using the "frame" command.  We
@@ -2077,9 +2175,38 @@ fp_register_arg_p (enum type_code typecode, struct type *arg_type)
           && MIPS_FPU_TYPE != MIPS_FPU_NONE);
 }
 
+/* On o32, argument passing in GPRs depends on the alignment of the type being
+   passed.  Return 1 if this type must be aligned to a doubleword boundary. */
+
+static int
+mips_type_needs_double_align (struct type *type)
+{
+  enum type_code typecode = TYPE_CODE (type);
+
+  if (typecode == TYPE_CODE_FLT && TYPE_LENGTH (type) == 8)
+    return 1;
+  else if (typecode == TYPE_CODE_STRUCT)
+    {
+      if (TYPE_NFIELDS (type) < 1)
+       return 0;
+      return mips_type_needs_double_align (TYPE_FIELD_TYPE (type, 0));
+    }
+  else if (typecode == TYPE_CODE_UNION)
+    {
+      int i, n;
+
+      n = TYPE_NFIELDS (type);
+      for (i = 0; i < n; i++)
+       if (mips_type_needs_double_align (TYPE_FIELD_TYPE (type, i)))
+         return 1;
+      return 0;
+    }
+  return 0;
+}
+
 CORE_ADDR
 mips_push_arguments (int nargs,
-                    value_ptr *args,
+                    struct value **args,
                     CORE_ADDR sp,
                     int struct_return,
                     CORE_ADDR struct_addr)
@@ -2137,7 +2264,7 @@ mips_push_arguments (int nargs,
     {
       char *val;
       char valbuf[MAX_REGISTER_RAW_SIZE];
-      value_ptr arg = args[argnum];
+      struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (VALUE_TYPE (arg));
       int len = TYPE_LENGTH (arg_type);
       enum type_code typecode = TYPE_CODE (arg_type);
@@ -2184,15 +2311,15 @@ mips_push_arguments (int nargs,
          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.  */
-      /* MIPS_EABI squeeses a struct that contains a single floating
-         point value into an FP register instead of pusing it onto the
+      /* MIPS_EABI squeezes a struct that contains a single floating
+         point value into an FP register instead of pushing it onto the
          stack. */
       if (fp_register_arg_p (typecode, arg_type)
          && float_argreg <= MIPS_LAST_FP_ARG_REGNUM)
        {
          if (!FP_REGISTER_DOUBLE && len == 8)
            {
-             int low_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 4 : 0;
+             int low_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
              unsigned long regval;
 
              /* Write the low word of the double to the even register(s).  */
@@ -2263,6 +2390,14 @@ mips_push_arguments (int nargs,
             compatibility, we will put them in both places.  */
          int odd_sized_struct = ((len > MIPS_SAVED_REGSIZE) &&
                                  (len % MIPS_SAVED_REGSIZE != 0));
+         /* Structures should be aligned to eight bytes (even arg registers)
+            on MIPS_ABI_O32 if their first member has double precision. */
+         if (gdbarch_tdep (current_gdbarch)->mips_abi == MIPS_ABI_O32
+             && mips_type_needs_double_align (arg_type))
+           {
+             if ((argreg & 1))
+               argreg++;
+           }
          /* Note: Floating-point values that didn't fit into an FP
              register are only written to memory. */
          while (len > 0)
@@ -2285,7 +2420,7 @@ mips_push_arguments (int nargs,
                  int longword_offset = 0;
                  CORE_ADDR addr;
                  stack_used_p = 1;
-                 if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+                 if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
                    {
                      if (MIPS_STACK_ARGSIZE == 8 &&
                          (typecode == TYPE_CODE_INT ||
@@ -2305,7 +2440,7 @@ mips_push_arguments (int nargs,
                      fprintf_unfiltered (gdb_stdlog, " longword_offset=0x%lx",
                                          (long) longword_offset);
                    }
-                   
+
                  addr = sp + stack_offset + longword_offset;
 
                  if (mips_debug)
@@ -2330,7 +2465,7 @@ mips_push_arguments (int nargs,
                {
                  LONGEST regval = extract_unsigned_integer (val, partial_len);
 
-                 /* A non-floating-point argument being passed in a 
+                 /* A non-floating-point argument being passed in a
                     general register.  If a struct or union, and if
                     the remaining length is smaller than the register
                     size, we have to adjust the register value on
@@ -2340,11 +2475,24 @@ mips_push_arguments (int nargs,
                     same for integral types.
 
                     Also don't do this adjustment on EABI and O64
-                    binaries. */
+                    binaries.
+
+                    cagney/2001-07-23: gdb/179: Also, GCC, when
+                    outputting LE O32 with sizeof (struct) <
+                    MIPS_SAVED_REGSIZE, generates a left shift as
+                    part of storing the argument in a register a
+                    register (the left shift isn't generated when
+                    sizeof (struct) >= MIPS_SAVED_REGSIZE).  Since it
+                    is quite possible that this is GCC contradicting
+                    the LE/O32 ABI, GDB has not been adjusted to
+                    accommodate this.  Either someone needs to
+                    demonstrate that the LE/O32 ABI specifies such a
+                    left shift OR this new ABI gets identified as
+                    such and GDB gets tweaked accordingly.  */
 
                  if (!MIPS_EABI
                      && MIPS_SAVED_REGSIZE < 8
-                     && TARGET_BYTE_ORDER == BIG_ENDIAN
+                     && TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
                      && partial_len < MIPS_SAVED_REGSIZE
                      && (typecode == TYPE_CODE_STRUCT ||
                          typecode == TYPE_CODE_UNION))
@@ -2409,7 +2557,7 @@ mips_push_register (CORE_ADDR * sp, int regno)
   if (MIPS_SAVED_REGSIZE < REGISTER_RAW_SIZE (regno))
     {
       regsize = MIPS_SAVED_REGSIZE;
-      offset = (TARGET_BYTE_ORDER == BIG_ENDIAN
+      offset = (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
                ? REGISTER_RAW_SIZE (regno) - MIPS_SAVED_REGSIZE
                : 0);
     }
@@ -2449,7 +2597,7 @@ mips_push_dummy_frame (void)
    * 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)
@@ -2548,7 +2696,7 @@ mips_pop_frame (void)
       else
        linked_proc_desc_table = pi_ptr->next;
 
-      free (pi_ptr);
+      xfree (pi_ptr);
 
       write_register (HI_REGNUM,
                      read_memory_integer (new_sp - 2 * MIPS_SAVED_REGSIZE,
@@ -2563,34 +2711,151 @@ mips_pop_frame (void)
     }
 }
 
+/* Floating point register management.
+
+   Background: MIPS1 & 2 fp registers are 32 bits wide.  To support
+   64bit operations, these early MIPS cpus treat fp register pairs
+   (f0,f1) as a single register (d0).  Later MIPS cpu's have 64 bit fp
+   registers and offer a compatibility mode that emulates the MIPS2 fp
+   model.  When operating in MIPS2 fp compat mode, later cpu's split
+   double precision floats into two 32-bit chunks and store them in
+   consecutive fp regs.  To display 64-bit floats stored in this
+   fashion, we have to combine 32 bits from f0 and 32 bits from f1.
+   Throw in user-configurable endianness and you have a real mess.
+
+   The way this works is:
+     - If we are in 32-bit mode or on a 32-bit processor, then a 64-bit
+       double-precision value will be split across two logical registers.
+       The lower-numbered logical register will hold the low-order bits,
+       regardless of the processor's endianness.
+     - If we are on a 64-bit processor, and we are looking for a
+       single-precision value, it will be in the low ordered bits
+       of a 64-bit GPR (after mfc1, for example) or a 64-bit register
+       save slot in memory.
+     - If we are in 64-bit mode, everything is straightforward.
+
+   Note that this code only deals with "live" registers at the top of the
+   stack.  We will attempt to deal with saved registers later, when
+   the raw/cooked register interface is in place. (We need a general
+   interface that can deal with dynamic saved register sizes -- fp
+   regs could be 32 bits wide in one frame and 64 on the frame above
+   and below).  */
+
+static struct type *
+mips_float_register_type (void)
+{
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    return builtin_type_ieee_single_big;
+  else
+    return builtin_type_ieee_single_little;
+}
+
+static struct type *
+mips_double_register_type (void)
+{
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+    return builtin_type_ieee_double_big;
+  else
+    return builtin_type_ieee_double_little;
+}
+
+/* Copy a 32-bit single-precision value from the current frame
+   into rare_buffer.  */
+
+static void
+mips_read_fp_register_single (int regno, char *rare_buffer)
+{
+  int raw_size = REGISTER_RAW_SIZE (regno);
+  char *raw_buffer = alloca (raw_size);
+
+  if (!frame_register_read (selected_frame, regno, raw_buffer))
+    error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
+  if (raw_size == 8)
+    {
+      /* We have a 64-bit value for this register.  Find the low-order
+        32 bits.  */
+      int offset;
+
+      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
+       offset = 4;
+      else
+       offset = 0;
+
+      memcpy (rare_buffer, raw_buffer + offset, 4);
+    }
+  else
+    {
+      memcpy (rare_buffer, raw_buffer, 4);
+    }
+}
+
+/* Copy a 64-bit double-precision value from the current frame into
+   rare_buffer.  This may include getting half of it from the next
+   register.  */
+
+static void
+mips_read_fp_register_double (int regno, char *rare_buffer)
+{
+  int raw_size = REGISTER_RAW_SIZE (regno);
+
+  if (raw_size == 8 && !mips2_fp_compat ())
+    {
+      /* We have a 64-bit value for this register, and we should use
+        all 64 bits.  */
+      if (!frame_register_read (selected_frame, regno, rare_buffer))
+       error ("can't read register %d (%s)", regno, REGISTER_NAME (regno));
+    }
+  else
+    {
+      if ((regno - FP0_REGNUM) & 1)
+       internal_error (__FILE__, __LINE__,
+                       "mips_read_fp_register_double: bad access to "
+                       "odd-numbered FP register");
+
+      /* mips_read_fp_register_single will find the correct 32 bits from
+        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);
+       }
+      else
+       {
+         mips_read_fp_register_single (regno, rare_buffer);
+         mips_read_fp_register_single (regno + 1, rare_buffer + 4);
+       }
+    }
+}
+
 static void
 mips_print_register (int regnum, int all)
 {
   char raw_buffer[MAX_REGISTER_RAW_SIZE];
 
   /* Get the data in raw format.  */
-  if (read_relative_register_raw_bytes (regnum, raw_buffer))
+  if (!frame_register_read (selected_frame, regnum, raw_buffer))
     {
       printf_filtered ("%s: [Invalid]", REGISTER_NAME (regnum));
       return;
     }
 
-  /* If an even floating point register, also print as double. */
+  /* 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))
-    if (REGISTER_RAW_SIZE (regnum) == 4)       /* this would be silly on MIPS64 or N32 (Irix 6) */
-      {
-       char dbuffer[2 * MAX_REGISTER_RAW_SIZE];
+    {
+      char dbuffer[2 * MAX_REGISTER_RAW_SIZE];
 
-       read_relative_register_raw_bytes (regnum, dbuffer);
-       read_relative_register_raw_bytes (regnum + 1, dbuffer + MIPS_REGSIZE);
-       REGISTER_CONVERT_TO_TYPE (regnum, builtin_type_double, dbuffer);
+      mips_read_fp_register_double (regnum, dbuffer);
 
-       printf_filtered ("(d%d: ", regnum - FP0_REGNUM);
-       val_print (builtin_type_double, dbuffer, 0, 0,
-                  gdb_stdout, 0, 1, 0, Val_pretty_default);
-       printf_filtered ("); ");
-      }
+      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
@@ -2604,15 +2869,17 @@ mips_print_register (int regnum, int all)
 
   /* If virtual format is floating, print it that way.  */
   if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (regnum)) == TYPE_CODE_FLT)
-    if (FP_REGISTER_DOUBLE)
-      {                                /* show 8-byte floats as float AND double: */
-       int offset = 4 * (TARGET_BYTE_ORDER == BIG_ENDIAN);
+    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 (builtin_type_float, raw_buffer + offset, 0, 0,
+       val_print (mips_float_register_type (), raw_buffer + offset, 0, 0,
                   gdb_stdout, 0, 1, 0, Val_pretty_default);
        printf_filtered (", (double) ");
-       val_print (builtin_type_double, raw_buffer, 0, 0,
+       val_print (mips_double_register_type (), raw_buffer, 0, 0,
                   gdb_stdout, 0, 1, 0, Val_pretty_default);
       }
     else
@@ -2623,74 +2890,86 @@ mips_print_register (int regnum, int all)
     {
       int offset;
 
-      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+      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.  
+/* Replacement for generic do_registers_info.
    Print regs in pretty columns.  */
 
 static int
 do_fp_register_row (int regnum)
 {                              /* do values for FP (float) regs */
-  char *raw_buffer[2];
-  char *dbl_buffer;
-  /* use HI and LO to control the order of combining two flt regs */
-  int HI = (TARGET_BYTE_ORDER == BIG_ENDIAN);
-  int LO = (TARGET_BYTE_ORDER != BIG_ENDIAN);
+  char *raw_buffer;
   double doub, flt1, flt2;     /* doubles extracted from raw hex data */
   int inv1, inv2, inv3;
 
-  raw_buffer[0] = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
-  raw_buffer[1] = (char *) alloca (REGISTER_RAW_SIZE (FP0_REGNUM));
-  dbl_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
+  raw_buffer = (char *) alloca (2 * REGISTER_RAW_SIZE (FP0_REGNUM));
 
-  /* Get the data in raw format.  */
-  if (read_relative_register_raw_bytes (regnum, raw_buffer[HI]))
-    error ("can't read register %d (%s)", regnum, REGISTER_NAME (regnum));
-  if (REGISTER_RAW_SIZE (regnum) == 4)
+  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. */
-      if (read_relative_register_raw_bytes (regnum + 1, raw_buffer[LO]))
-       error ("can't read register %d (%s)",
-              regnum + 1, REGISTER_NAME (regnum + 1));
-
-      /* copy the two floats into one double, and unpack both */
-      memcpy (dbl_buffer, raw_buffer, 2 * REGISTER_RAW_SIZE (FP0_REGNUM));
-      flt1 = unpack_double (builtin_type_float, raw_buffer[HI], &inv1);
-      flt2 = unpack_double (builtin_type_float, raw_buffer[LO], &inv2);
-      doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
-
-      printf_filtered (inv1 ? " %-5s: <invalid float>" :
-                      " %-5s%-17.9g", REGISTER_NAME (regnum), flt1);
-      printf_filtered (inv2 ? " %-5s: <invalid float>" :
-                      " %-5s%-17.9g", REGISTER_NAME (regnum + 1), flt2);
-      printf_filtered (inv3 ? " dbl: <invalid double>\n" :
-                      " dbl: %-24.17g\n", doub);
+      /* 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);
+      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);
+
+      mips_read_fp_register_double (regnum, raw_buffer);
+      doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
+
+      printf_filtered (" %-5s", REGISTER_NAME (regnum));
+      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>");
+      else
+       printf_filtered ("%-17.9g", flt2);
+
+      printf_filtered (" dbl: ");
+      if (inv3)
+       printf_filtered ("<invalid double>");
+      else
+       printf_filtered ("%-24.17g", doub);
+      printf_filtered ("\n");
+
       /* may want to do hex display here (future enhancement) */
       regnum += 2;
     }
   else
-    {                          /* eight byte registers: print each one as float AND as double. */
-      int offset = 4 * (TARGET_BYTE_ORDER == BIG_ENDIAN);
-
-      memcpy (dbl_buffer, raw_buffer[HI], 2 * REGISTER_RAW_SIZE (FP0_REGNUM));
-      flt1 = unpack_double (builtin_type_float,
-                           &raw_buffer[HI][offset], &inv1);
-      doub = unpack_double (builtin_type_double, dbl_buffer, &inv3);
-
-      printf_filtered (inv1 ? " %-5s: <invalid float>" :
-                      " %-5s flt: %-17.9g", REGISTER_NAME (regnum), flt1);
-      printf_filtered (inv3 ? " dbl: <invalid double>\n" :
-                      " dbl: %-24.17g\n", doub);
+    {
+      /* 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);
+
+      mips_read_fp_register_double (regnum, raw_buffer);
+      doub = unpack_double (mips_double_register_type (), raw_buffer, &inv3);
+
+      printf_filtered (" %-5s: ", REGISTER_NAME (regnum));
+      if (inv1)
+       printf_filtered ("<invalid float>");
+      else
+       printf_filtered ("flt: %-17.9g", flt1);
+
+      printf_filtered (" dbl: ");
+      if (inv3)
+       printf_filtered ("<invalid double>");
+      else
+       printf_filtered ("%-24.17g", doub);
+
+      printf_filtered ("\n");
       /* may want to do hex display here (future enhancement) */
       regnum++;
     }
@@ -2734,13 +3013,13 @@ 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 (read_relative_register_raw_bytes (regnum, raw_buffer))
+      if (!frame_register_read (selected_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++)
        printf_filtered ("  ");
       /* Now print the register value in hex, endian order. */
-      if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
        for (byte = REGISTER_RAW_SIZE (regnum) - REGISTER_VIRTUAL_SIZE (regnum);
             byte < REGISTER_RAW_SIZE (regnum);
             byte++)
@@ -3083,9 +3362,9 @@ return_value_location (struct type *valtype,
        {
          /* We need to break a 64bit float in two 32 bit halves and
             spread them across a floating-point register pair. */
-         lo->buf_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 4 : 0;
-         hi->buf_offset = TARGET_BYTE_ORDER == BIG_ENDIAN ? 0 : 4;
-         lo->reg_offset = ((TARGET_BYTE_ORDER == BIG_ENDIAN
+         lo->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 4 : 0;
+         hi->buf_offset = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? 0 : 4;
+         lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
                             && REGISTER_RAW_SIZE (FP0_REGNUM) == 8)
                            ? 4 : 0);
          hi->reg_offset = lo->reg_offset;
@@ -3098,7 +3377,7 @@ return_value_location (struct type *valtype,
        {
          /* The floating point value fits in a single floating-point
             register. */
-         lo->reg_offset = ((TARGET_BYTE_ORDER == BIG_ENDIAN
+         lo->reg_offset = ((TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
                             && REGISTER_RAW_SIZE (FP0_REGNUM) == 8
                             && len == 4)
                            ? 4 : 0);
@@ -3117,7 +3396,7 @@ return_value_location (struct type *valtype,
       int regnum = 2;
       lo->reg = regnum + 0;
       hi->reg = regnum + 1;
-      if (TARGET_BYTE_ORDER == BIG_ENDIAN
+      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
          && len < MIPS_SAVED_REGSIZE)
        {
          /* "un-left-justify" the value in the low register */
@@ -3126,7 +3405,7 @@ return_value_location (struct type *valtype,
          hi->reg_offset = 0;
          hi->len = 0;
        }
-      else if (TARGET_BYTE_ORDER == BIG_ENDIAN
+      else if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
               && len > MIPS_SAVED_REGSIZE      /* odd-size structs */
               && len < MIPS_SAVED_REGSIZE * 2
               && (TYPE_CODE (valtype) == TYPE_CODE_STRUCT ||
@@ -3154,7 +3433,7 @@ return_value_location (struct type *valtype,
              hi->len = 0;
            }
        }
-      if (TARGET_BYTE_ORDER == BIG_ENDIAN
+      if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG
          && REGISTER_RAW_SIZE (regnum) == 8
          && MIPS_SAVED_REGSIZE == 4)
        {
@@ -3178,7 +3457,7 @@ mips_extract_return_value (struct type *valtype,
 {
   struct return_value_word lo;
   struct return_value_word hi;
-  return_value_location (valtype, &lo, &hi);
+  return_value_location (valtype, &hi, &lo);
 
   memcpy (valbuf + lo.buf_offset,
          regbuf + REGISTER_BYTE (lo.reg) + lo.reg_offset,
@@ -3199,7 +3478,7 @@ mips_store_return_value (struct type *valtype, char *valbuf)
   char raw_buffer[MAX_REGISTER_RAW_SIZE];
   struct return_value_word lo;
   struct return_value_word hi;
-  return_value_location (valtype, &lo, &hi);
+  return_value_location (valtype, &hi, &lo);
 
   memset (raw_buffer, 0, sizeof (raw_buffer));
   memcpy (raw_buffer + lo.reg_offset, valbuf + lo.buf_offset, lo.len);
@@ -3248,7 +3527,6 @@ set_mips_command (char *args, int from_tty)
 static void
 show_mipsfpu_command (char *args, int from_tty)
 {
-  char *msg;
   char *fpu;
   switch (MIPS_FPU_TYPE)
     {
@@ -3261,6 +3539,8 @@ show_mipsfpu_command (char *args, int from_tty)
     case MIPS_FPU_NONE:
       fpu = "absent (none)";
       break;
+    default:
+      internal_error (__FILE__, __LINE__, "bad switch");
     }
   if (mips_fpu_type_auto)
     printf_unfiltered ("The MIPS floating-point coprocessor is set automatically (currently %s)\n",
@@ -3331,7 +3611,7 @@ mips_set_processor_type_command (char *args, int from_tty)
        printf_unfiltered ("%s\n", mips_processor_type_table[i].name);
 
       /* Restore the value.  */
-      tmp_mips_processor_type = strsave (mips_processor_type);
+      tmp_mips_processor_type = xstrdup (mips_processor_type);
 
       return;
     }
@@ -3340,7 +3620,7 @@ mips_set_processor_type_command (char *args, int from_tty)
     {
       error ("Unknown processor type `%s'.", tmp_mips_processor_type);
       /* Restore its value.  */
-      tmp_mips_processor_type = strsave (mips_processor_type);
+      tmp_mips_processor_type = xstrdup (mips_processor_type);
     }
 }
 
@@ -3354,7 +3634,7 @@ mips_show_processor_type_command (char *args, int from_tty)
 int
 mips_set_processor_type (char *str)
 {
-  int i, j;
+  int i;
 
   if (str == NULL)
     return 0;
@@ -3417,17 +3697,17 @@ gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info)
      it's definitely a 16-bit function.  Otherwise, we have to just
      guess that if the address passed in is odd, it's 16-bits.  */
   if (proc_desc)
-    info->mach = pc_is_mips16 (PROC_LOW_ADDR (proc_desc)) ? 
+    info->mach = pc_is_mips16 (PROC_LOW_ADDR (proc_desc)) ?
       bfd_mach_mips16 : TM_PRINT_INSN_MACH;
   else
-    info->mach = pc_is_mips16 (memaddr) ? 
+    info->mach = pc_is_mips16 (memaddr) ?
       bfd_mach_mips16 : TM_PRINT_INSN_MACH;
 
   /* Round down the instruction address to the appropriate boundary.  */
   memaddr &= (info->mach == bfd_mach_mips16 ? ~1 : ~3);
 
   /* Call the appropriate disassembler based on the target endian-ness.  */
-  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
     return print_insn_big_mips (memaddr, info);
   else
     return print_insn_little_mips (memaddr, info);
@@ -3453,23 +3733,24 @@ gdb_print_insn_mips (bfd_vma memaddr, disassemble_info *info)
    (if necessary) to point to the actual memory location where the
    breakpoint should be inserted.  */
 
-unsigned char *
+const unsigned char *
 mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
 {
-  if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+  if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG)
     {
       if (pc_is_mips16 (*pcptr))
        {
-         static char mips16_big_breakpoint[] = MIPS16_BIG_BREAKPOINT;
+         static unsigned char mips16_big_breakpoint[] =
+           MIPS16_BIG_BREAKPOINT;
          *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
          *lenptr = sizeof (mips16_big_breakpoint);
          return mips16_big_breakpoint;
        }
       else
        {
-         static char big_breakpoint[] = BIG_BREAKPOINT;
-         static char pmon_big_breakpoint[] = PMON_BIG_BREAKPOINT;
-         static char idt_big_breakpoint[] = IDT_BIG_BREAKPOINT;
+         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;
 
          *lenptr = sizeof (big_breakpoint);
 
@@ -3487,16 +3768,19 @@ mips_breakpoint_from_pc (CORE_ADDR * pcptr, int *lenptr)
     {
       if (pc_is_mips16 (*pcptr))
        {
-         static char mips16_little_breakpoint[] = MIPS16_LITTLE_BREAKPOINT;
+         static unsigned char mips16_little_breakpoint[] =
+           MIPS16_LITTLE_BREAKPOINT;
          *pcptr = UNMAKE_MIPS16_ADDR (*pcptr);
          *lenptr = sizeof (mips16_little_breakpoint);
          return mips16_little_breakpoint;
        }
       else
        {
-         static char little_breakpoint[] = LITTLE_BREAKPOINT;
-         static char pmon_little_breakpoint[] = PMON_LITTLE_BREAKPOINT;
-         static char idt_little_breakpoint[] = IDT_LITTLE_BREAKPOINT;
+         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;
 
          *lenptr = sizeof (little_breakpoint);
 
@@ -3705,7 +3989,7 @@ mips_call_dummy_address (void)
 }
 
 
-/* If the current gcc for for this target does not produce correct debugging
+/* If the current gcc for this target does not produce correct debugging
    information for float parameters, both prototyped and unprototyped, then
    define this macro.  This forces gdb to  always assume that floats are
    passed as doubles and then converted in the callee.
@@ -3801,6 +4085,43 @@ mips_saved_pc_after_call (struct frame_info *frame)
 }
 
 
+/* Convert a dbx stab register number (from `r' declaration) to a gdb
+   REGNUM */
+
+static int
+mips_stab_reg_to_regnum (int num)
+{
+  if (num < 32)
+    return num;
+  else
+    return num + FP0_REGNUM - 38;
+}
+
+/* Convert a ecoff register number to a gdb REGNUM */
+
+static int
+mips_ecoff_reg_to_regnum (int num)
+{
+  if (num < 32)
+    return num;
+  else
+    return num + FP0_REGNUM - 32;
+}
+
+/* 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.  */
+
+static CORE_ADDR
+mips_integer_to_address (struct type *type, void *buf)
+{
+  char *tmp = alloca (TYPE_LENGTH (builtin_type_void_data_ptr));
+  LONGEST val = unpack_long (type, buf);
+  store_signed_integer (tmp, TYPE_LENGTH (builtin_type_void_data_ptr), val);
+  return extract_signed_integer (tmp,
+                                TYPE_LENGTH (builtin_type_void_data_ptr));
+}
+
 static struct gdbarch *
 mips_gdbarch_init (struct gdbarch_info info,
                   struct gdbarch_list *arches)
@@ -3812,6 +4133,12 @@ mips_gdbarch_init (struct gdbarch_info info,
   int elf_flags;
   enum mips_abi mips_abi;
 
+  /* 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;
+
   /* Extract the elf_flags if available */
   if (info.abfd != NULL
       && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
@@ -3856,6 +4183,10 @@ mips_gdbarch_init (struct gdbarch_info info,
        case bfd_mach_mips5000:
          mips_abi = MIPS_ABI_EABI64;
          break;
+       case bfd_mach_mips8000:
+       case bfd_mach_mips10000:
+         mips_abi = MIPS_ABI_N32;
+         break;
        }
     }
 #ifdef MIPS_DEFAULT_ABI
@@ -3892,13 +4223,15 @@ mips_gdbarch_init (struct gdbarch_info info,
   gdbarch = gdbarch_alloc (&info, tdep);
   tdep->elf_flags = elf_flags;
 
-  /* Initially set everything according to the ABI. */
+  /* Initially set everything according to the default ABI/ISA. */
   set_gdbarch_short_bit (gdbarch, 16);
   set_gdbarch_int_bit (gdbarch, 32);
   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);
   tdep->mips_abi = mips_abi;
+
   switch (mips_abi)
     {
     case MIPS_ABI_O32:
@@ -3924,7 +4257,7 @@ mips_gdbarch_init (struct gdbarch_info info,
       tdep->mips_last_fp_arg_regnum = FPA0_REGNUM + 4 - 1;
       tdep->mips_regs_have_home_p = 1;
       tdep->gdb_target_is_mips64 = 1;
-      tdep->default_mask_address_p = 0; 
+      tdep->default_mask_address_p = 0;
       set_gdbarch_long_bit (gdbarch, 32);
       set_gdbarch_ptr_bit (gdbarch, 32);
       set_gdbarch_long_long_bit (gdbarch, 64);
@@ -3944,7 +4277,7 @@ mips_gdbarch_init (struct gdbarch_info info,
       set_gdbarch_long_long_bit (gdbarch, 64);
       break;
     case MIPS_ABI_EABI64:
-       tdep->mips_abi_string = "eabi64";
+      tdep->mips_abi_string = "eabi64";
       tdep->mips_default_saved_regsize = 8;
       tdep->mips_default_stack_argsize = 8;
       tdep->mips_fp_register_double = 1;
@@ -3970,6 +4303,17 @@ 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;
       break;
     default:
       tdep->mips_abi_string = "default";
@@ -3995,7 +4339,7 @@ mips_gdbarch_init (struct gdbarch_info info,
      flag in object files because to do so would make it impossible to
      link with libraries compiled without "-gp32". This is
      unnecessarily restrictive.
+
      We could solve this problem by adding "-gp32" multilibs to gcc,
      but to set this flag before gcc is built with such multilibs will
      break too many systems.''
@@ -4038,10 +4382,22 @@ mips_gdbarch_init (struct gdbarch_info info,
   set_gdbarch_read_pc (gdbarch, mips_read_pc);
   set_gdbarch_write_pc (gdbarch, generic_target_write_pc);
   set_gdbarch_read_fp (gdbarch, generic_target_read_fp);
-  set_gdbarch_write_fp (gdbarch, generic_target_write_fp);
   set_gdbarch_read_sp (gdbarch, generic_target_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. */
+  set_gdbarch_addr_bits_remove (gdbarch, mips_addr_bits_remove);
+
+  /* There's a mess in stack frame creation.  See comments in
+     blockframe.c near reference to INIT_FRAME_PC_FIRST.  */
+  set_gdbarch_init_frame_pc_first (gdbarch, mips_init_frame_pc_first);
+  set_gdbarch_init_frame_pc (gdbarch, init_frame_pc_noop);
+
+  /* Map debug register numbers onto internal register numbers. */
+  set_gdbarch_stab_reg_to_regnum (gdbarch, mips_stab_reg_to_regnum);
+  set_gdbarch_ecoff_reg_to_regnum (gdbarch, mips_ecoff_reg_to_regnum);
+
   /* Initialize a frame */
   set_gdbarch_init_extra_frame_info (gdbarch, mips_init_extra_frame_info);
 
@@ -4070,11 +4426,13 @@ mips_gdbarch_init (struct gdbarch_info info,
   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_ieee_float (gdbarch, 1);
 
   set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
   set_gdbarch_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);
+  set_gdbarch_integer_to_address (gdbarch, mips_integer_to_address);
   return gdbarch;
 }
 
@@ -4099,9 +4457,10 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
          ef_mips_arch = 3;
          break;
        case E_MIPS_ARCH_4:
-         ef_mips_arch = 0;
+         ef_mips_arch = 4;
          break;
        default:
+         ef_mips_arch = 0;
          break;
        }
       /* determine the size of a pointer */
@@ -4238,15 +4597,6 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *file)
   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)));
@@ -4412,11 +4762,8 @@ mips_dump_tdep (struct gdbarch *current_gdbarch, struct ui_file *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);
+                     "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)));
@@ -4579,12 +4926,12 @@ This option can be set to one of:\n\
 Set this to be able to access processor-type-specific registers.\n\
 ",
                   &setlist);
-  c->function.cfunc = mips_set_processor_type_command;
+  set_cmd_cfunc (c, mips_set_processor_type_command);
   c = add_show_from_set (c, &showlist);
-  c->function.cfunc = mips_show_processor_type_command;
+  set_cmd_cfunc (c, mips_show_processor_type_command);
 
-  tmp_mips_processor_type = strsave (DEFAULT_MIPS_TYPE);
-  mips_set_processor_type_command (strsave (DEFAULT_MIPS_TYPE), 0);
+  tmp_mips_processor_type = xstrdup (DEFAULT_MIPS_TYPE);
+  mips_set_processor_type_command (xstrdup (DEFAULT_MIPS_TYPE), 0);
 #endif
 
   /* We really would like to have both "0" and "unlimited" work, but
@@ -4600,7 +4947,7 @@ search.  The only need to set it is when debugging a stripped executable.",
                   &setlist);
   /* We need to throw away the frame cache when we set this, since it
      might change our ability to get backtraces.  */
-  c->function.sfunc = reinit_frame_cache_sfunc;
+  set_cmd_sfunc (c, reinit_frame_cache_sfunc);
   add_show_from_set (c, &showlist);
 
   /* Allow the user to control whether the upper bits of 64-bit
@@ -4632,4 +4979,3 @@ that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
 When non-zero, mips specific debugging is enabled.", &setdebuglist),
                     &showdebuglist);
 }
-
This page took 0.044715 seconds and 4 git commands to generate.