bfd_set_input_error
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index 8165f94b4ddcfdad6dc4a273594a0550eef32cf8..5fc061878734c4e89178cab37a94940701548879 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
 
-   Copyright (C) 1988-2014 Free Software Foundation, Inc.
+   Copyright (C) 1988-2017 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.
@@ -44,6 +44,7 @@
 #include "symcat.h"
 #include "sim-regno.h"
 #include "dis-asm.h"
+#include "disasm.h"
 #include "frame-unwind.h"
 #include "frame-base.h"
 #include "trad-frame.h"
 #include "user-regs.h"
 #include "valprint.h"
 #include "ax.h"
+#include <algorithm>
 
 static const struct objfile_data *mips_pdr_data;
 
 static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum);
 
-static int mips32_instruction_has_delay_slot (struct gdbarch *, CORE_ADDR);
-static int micromips_instruction_has_delay_slot (struct gdbarch *, CORE_ADDR,
-                                                int);
-static int mips16_instruction_has_delay_slot (struct gdbarch *, CORE_ADDR,
-                                             int);
+static int mips32_instruction_has_delay_slot (struct gdbarch *gdbarch,
+                                             ULONGEST inst);
+static int micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32);
+static int mips16_instruction_has_delay_slot (unsigned short inst,
+                                             int mustbe32);
+
+static int mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                            CORE_ADDR addr);
+static int micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                               CORE_ADDR addr, int mustbe32);
+static int mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                            CORE_ADDR addr, int mustbe32);
+
+static void mips_print_float_info (struct gdbarch *, struct ui_file *,
+                                  struct frame_info *, const char *);
 
 /* A useful bit in the CP0 status register (MIPS_PS_REGNUM).  */
 /* This bit is set if we are emulating 32-bit FPRs on a 64-bit chip.  */
@@ -97,6 +109,23 @@ static const char *const mips_abi_strings[] = {
   NULL
 };
 
+/* Enum describing the different kinds of breakpoints.  */
+
+enum mips_breakpoint_kind
+{
+  /* 16-bit MIPS16 mode breakpoint.  */
+  MIPS_BP_KIND_MIPS16 = 2,
+
+  /* 16-bit microMIPS mode breakpoint.  */
+  MIPS_BP_KIND_MICROMIPS16 = 3,
+
+  /* 32-bit standard MIPS mode breakpoint.  */
+  MIPS_BP_KIND_MIPS32 = 4,
+
+  /* 32-bit microMIPS mode breakpoint.  */
+  MIPS_BP_KIND_MICROMIPS32 = 5,
+};
+
 /* For backwards compatibility we default to MIPS16.  This flag is
    overridden as soon as unambiguous ELF file flags tell us the
    compressed ISA encoding used.  */
@@ -242,6 +271,9 @@ mips_isa_regsize (struct gdbarch *gdbarch)
          / gdbarch_bfd_arch_info (gdbarch)->bits_per_byte);
 }
 
+/* Max saved register size.  */
+#define MAX_MIPS_ABI_REGSIZE 8
+
 /* Return the currently configured (or set) saved register size.  */
 
 unsigned int
@@ -333,6 +365,15 @@ make_compact_addr (CORE_ADDR addr)
   return ((addr) | (CORE_ADDR) 1);
 }
 
+/* Extern version of unmake_compact_addr; we use a separate function
+   so that unmake_compact_addr can be inlined throughout this file.  */
+
+CORE_ADDR
+mips_unmake_compact_addr (CORE_ADDR addr)
+{
+  return unmake_compact_addr (addr);
+}
+
 /* Functions for setting and testing a bit in a minimal symbol that
    marks it as MIPS16 or microMIPS function.  The MSB of the minimal
    symbol's "info" field is used for this purpose.
@@ -362,9 +403,15 @@ mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym)
     return;
 
   if (ELF_ST_IS_MICROMIPS (st_other))
-    MSYMBOL_TARGET_FLAG_2 (msym) = 1;
+    {
+      MSYMBOL_TARGET_FLAG_MICROMIPS (msym) = 1;
+      SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1);
+    }
   else if (ELF_ST_IS_MIPS16 (st_other))
-    MSYMBOL_TARGET_FLAG_1 (msym) = 1;
+    {
+      MSYMBOL_TARGET_FLAG_MIPS16 (msym) = 1;
+      SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1);
+    }
 }
 
 /* Return one iff MSYM refers to standard ISA code.  */
@@ -372,7 +419,8 @@ mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym)
 static int
 msymbol_is_mips (struct minimal_symbol *msym)
 {
-  return !(MSYMBOL_TARGET_FLAG_1 (msym) | MSYMBOL_TARGET_FLAG_2 (msym));
+  return !(MSYMBOL_TARGET_FLAG_MIPS16 (msym)
+          | MSYMBOL_TARGET_FLAG_MICROMIPS (msym));
 }
 
 /* Return one iff MSYM refers to MIPS16 code.  */
@@ -380,7 +428,7 @@ msymbol_is_mips (struct minimal_symbol *msym)
 static int
 msymbol_is_mips16 (struct minimal_symbol *msym)
 {
-  return MSYMBOL_TARGET_FLAG_1 (msym);
+  return MSYMBOL_TARGET_FLAG_MIPS16 (msym);
 }
 
 /* Return one iff MSYM refers to microMIPS code.  */
@@ -388,7 +436,36 @@ msymbol_is_mips16 (struct minimal_symbol *msym)
 static int
 msymbol_is_micromips (struct minimal_symbol *msym)
 {
-  return MSYMBOL_TARGET_FLAG_2 (msym);
+  return MSYMBOL_TARGET_FLAG_MICROMIPS (msym);
+}
+
+/* Set the ISA bit in the main symbol too, complementing the corresponding
+   minimal symbol setting and reflecting the run-time value of the symbol.
+   The need for comes from the ISA bit having been cleared as code in
+   `_bfd_mips_elf_symbol_processing' separated it into the ELF symbol's
+   `st_other' STO_MIPS16 or STO_MICROMIPS annotation, making the values
+   of symbols referring to compressed code different in GDB to the values
+   used by actual code.  That in turn makes them evaluate incorrectly in
+   expressions, producing results different to what the same expressions
+   yield when compiled into the program being debugged.  */
+
+static void
+mips_make_symbol_special (struct symbol *sym, struct objfile *objfile)
+{
+  if (SYMBOL_CLASS (sym) == LOC_BLOCK)
+    {
+      /* We are in symbol reading so it is OK to cast away constness.  */
+      struct block *block = (struct block *) SYMBOL_BLOCK_VALUE (sym);
+      CORE_ADDR compact_block_start;
+      struct bound_minimal_symbol msym;
+
+      compact_block_start = BLOCK_START (block) | 1;
+      msym = lookup_minimal_symbol_by_pc (compact_block_start);
+      if (msym.minsym && !msymbol_is_mips (msym.minsym))
+       {
+         BLOCK_START (block) = compact_block_start;
+       }
+    }
 }
 
 /* XFER a value from the big/little/left end of the register.
@@ -504,19 +581,6 @@ static const char *mips_generic_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
   "fsr", "fir",
 };
 
-/* Names of IDT R3041 registers.  */
-
-static const char *mips_r3041_reg_names[] = {
-  "sr", "lo", "hi", "bad", "cause", "pc",
-  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
-  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
-  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
-  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
-  "fsr", "fir", "", /*"fp" */ "",
-  "", "", "bus", "ccfg", "", "", "", "",
-  "", "", "port", "cmp", "", "", "epc", "prid",
-};
-
 /* Names of tx39 registers.  */
 
 static const char *mips_tx39_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
@@ -530,15 +594,6 @@ static const char *mips_tx39_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
   "", "", "config", "cache", "debug", "depc", "epc",
 };
 
-/* Names of IRIX registers.  */
-static const char *mips_irix_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
-  "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
-  "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
-  "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
-  "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
-  "pc", "cause", "bad", "hi", "lo", "fsr", "fir"
-};
-
 /* Names of registers with Linux kernels.  */
 static const char *mips_linux_reg_names[NUM_MIPS_PROCESSOR_REGS] = {
   "sr", "lo", "hi", "bad", "cause", "pc",
@@ -556,7 +611,7 @@ mips_register_name (struct gdbarch *gdbarch, int regno)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   /* GPR names for all ABIs other than n32/n64.  */
-  static char *mips_gpr_names[] = {
+  static const char *mips_gpr_names[] = {
     "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
@@ -564,7 +619,7 @@ mips_register_name (struct gdbarch *gdbarch, int regno)
   };
 
   /* GPR names for n32 and n64 ABIs.  */
-  static char *mips_n32_n64_gpr_names[] = {
+  static const char *mips_n32_n64_gpr_names[] = {
     "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
     "a4", "a5", "a6", "a7", "t0", "t1", "t2", "t3",
     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
@@ -977,8 +1032,7 @@ mips_register_type (struct gdbarch *gdbarch, int regnum)
       if (rawnum == mips_regnum (gdbarch)->fp_control_status
          || rawnum == mips_regnum (gdbarch)->fp_implementation_revision)
        return builtin_type (gdbarch)->builtin_int32;
-      else if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX
-              && gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
+      else if (gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
               && rawnum >= MIPS_FIRST_EMBED_REGNUM
               && rawnum <= MIPS_LAST_EMBED_REGNUM)
        /* The pseudo/cooked view of the embedded registers is always
@@ -1018,11 +1072,18 @@ mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   if (TYPE_LENGTH (rawtype) == 0)
     return rawtype;
 
+  /* Present the floating point registers however the hardware did;
+     do not try to convert between FPU layouts.  */
   if (mips_float_register_p (gdbarch, rawnum))
-    /* Present the floating point registers however the hardware did;
-       do not try to convert between FPU layouts.  */
     return rawtype;
 
+  /* Floating-point control registers are always 32-bit even though for
+     backwards compatibility reasons 64-bit targets will transfer them
+     as 64-bit quantities even if using XML descriptions.  */
+  if (rawnum == mips_regnum (gdbarch)->fp_control_status
+      || rawnum == mips_regnum (gdbarch)->fp_implementation_revision)
+    return builtin_type (gdbarch)->builtin_int32;
+
   /* Use pointer types for registers if we can.  For n32 we can not,
      since we do not have a 64-bit pointer type.  */
   if (mips_abi_regsize (gdbarch)
@@ -1047,19 +1108,16 @@ mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
              && rawnum < mips_regnum (gdbarch)->dspacc + 6)))
     return builtin_type (gdbarch)->builtin_int32;
 
-  if (gdbarch_osabi (gdbarch) != GDB_OSABI_IRIX
-      && gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
-      && rawnum >= MIPS_EMBED_FP0_REGNUM + 32
+  /* The pseudo/cooked view of embedded registers is always
+     32-bit, even if the target transfers 64-bit values for them.
+     New targets relying on XML descriptions should only transfer
+     the necessary 32 bits, but older versions of GDB expected 64,
+     so allow the target to provide 64 bits without interfering
+     with the displayed type.  */
+  if (gdbarch_osabi (gdbarch) != GDB_OSABI_LINUX
+      && rawnum >= MIPS_FIRST_EMBED_REGNUM
       && rawnum <= MIPS_LAST_EMBED_REGNUM)
-    {
-      /* The pseudo/cooked view of embedded registers is always
-        32-bit, even if the target transfers 64-bit values for them.
-        New targets relying on XML descriptions should only transfer
-        the necessary 32 bits, but older versions of GDB expected 64,
-        so allow the target to provide 64 bits without interfering
-        with the displayed type.  */
-      return builtin_type (gdbarch)->builtin_int32;
-    }
+    return builtin_type (gdbarch)->builtin_int32;
 
   /* For all other registers, pass through the hardware type.  */
   return rawtype;
@@ -1125,7 +1183,7 @@ mips_pc_is_mips (CORE_ADDR memaddr)
      stored by elfread.c in the high bit of the info field.  Use this
      to decide if the function is standard MIPS.  Otherwise if bit 0
      of the address is clear, then this is a standard MIPS function.  */
-  sym = lookup_minimal_symbol_by_pc (memaddr);
+  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
   if (sym.minsym)
     return msymbol_is_mips (sym.minsym);
   else
@@ -1143,7 +1201,7 @@ mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr)
      elfread.c in the high bit of the info field.  Use this to decide
      if the function is MIPS16.  Otherwise if bit 0 of the address is
      set, then ELF file flags will tell if this is a MIPS16 function.  */
-  sym = lookup_minimal_symbol_by_pc (memaddr);
+  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
   if (sym.minsym)
     return msymbol_is_mips16 (sym.minsym);
   else
@@ -1162,7 +1220,7 @@ mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr)
      if the function is microMIPS.  Otherwise if bit 0 of the address
      is set, then ELF file flags will tell if this is a microMIPS
      function.  */
-  sym = lookup_minimal_symbol_by_pc (memaddr);
+  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
   if (sym.minsym)
     return msymbol_is_micromips (sym.minsym);
   else
@@ -1182,7 +1240,7 @@ mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr)
      this to decide if the function is MIPS16 or microMIPS or normal
      MIPS.  Otherwise if bit 0 of the address is set, then ELF file
      flags will tell if this is a MIPS16 or a microMIPS function.  */
-  sym = lookup_minimal_symbol_by_pc (memaddr);
+  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
   if (sym.minsym)
     {
       if (msymbol_is_micromips (sym.minsym))
@@ -1203,6 +1261,67 @@ mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr)
     }
 }
 
+/* Set the ISA bit correctly in the PC, used by DWARF-2 machinery.
+   The need for comes from the ISA bit having been cleared, making
+   addresses in FDE, range records, etc. referring to compressed code
+   different to those in line information, the symbol table and finally
+   the PC register.  That in turn confuses many operations.  */
+
+static CORE_ADDR
+mips_adjust_dwarf2_addr (CORE_ADDR pc)
+{
+  pc = unmake_compact_addr (pc);
+  return mips_pc_is_mips (pc) ? pc : make_compact_addr (pc);
+}
+
+/* Recalculate the line record requested so that the resulting PC has
+   the ISA bit set correctly, used by DWARF-2 machinery.  The need for
+   this adjustment comes from some records associated with compressed
+   code having the ISA bit cleared, most notably at function prologue
+   ends.  The ISA bit is in this context retrieved from the minimal
+   symbol covering the address requested, which in turn has been
+   constructed from the binary's symbol table rather than DWARF-2
+   information.  The correct setting of the ISA bit is required for
+   breakpoint addresses to correctly match against the stop PC.
+
+   As line entries can specify relative address adjustments we need to
+   keep track of the absolute value of the last line address recorded
+   in line information, so that we can calculate the actual address to
+   apply the ISA bit adjustment to.  We use PC for this tracking and
+   keep the original address there.
+
+   As such relative address adjustments can be odd within compressed
+   code we need to keep track of the last line address with the ISA
+   bit adjustment applied too, as the original address may or may not
+   have had the ISA bit set.  We use ADJ_PC for this tracking and keep
+   the adjusted address there.
+
+   For relative address adjustments we then use these variables to
+   calculate the address intended by line information, which will be
+   PC-relative, and return an updated adjustment carrying ISA bit
+   information, which will be ADJ_PC-relative.  For absolute address
+   adjustments we just return the same address that we store in ADJ_PC
+   too.
+
+   As the first line entry can be relative to an implied address value
+   of 0 we need to have the initial address set up that we store in PC
+   and ADJ_PC.  This is arranged with a call from `dwarf_decode_lines_1'
+   that sets PC to 0 and ADJ_PC accordingly, usually 0 as well.  */
+
+static CORE_ADDR
+mips_adjust_dwarf2_line (CORE_ADDR addr, int rel)
+{
+  static CORE_ADDR adj_pc;
+  static CORE_ADDR pc;
+  CORE_ADDR isa_pc;
+
+  pc = rel ? pc + addr : addr;
+  isa_pc = mips_adjust_dwarf2_addr (pc);
+  addr = rel ? isa_pc - adj_pc : isa_pc;
+  adj_pc = isa_pc;
+  return addr;
+}
+
 /* Various MIPS16 thunk (aka stub or trampoline) names.  */
 
 static const char mips_str_mips16_call_stub[] = "__mips16_call_stub_";
@@ -1229,14 +1348,13 @@ mips_in_frame_stub (CORE_ADDR pc)
     return 0;
 
   /* If the PC is in __mips16_call_stub_*, this is a call/return stub.  */
-  if (strncmp (name, mips_str_mips16_call_stub,
-              strlen (mips_str_mips16_call_stub)) == 0)
+  if (startswith (name, mips_str_mips16_call_stub))
     return 1;
   /* If the PC is in __call_stub_*, this is a call/return or a call stub.  */
-  if (strncmp (name, mips_str_call_stub, strlen (mips_str_call_stub)) == 0)
+  if (startswith (name, mips_str_call_stub))
     return 1;
   /* If the PC is in __fn_stub_*, this is a call stub.  */
-  if (strncmp (name, mips_str_fn_stub, strlen (mips_str_fn_stub)) == 0)
+  if (startswith (name, mips_str_fn_stub))
     return 1;
 
   return 0;                    /* Not a stub.  */
@@ -1252,8 +1370,6 @@ mips_read_pc (struct regcache *regcache)
   LONGEST pc;
 
   regcache_cooked_read_signed (regcache, regnum, &pc);
-  if (is_compact_addr (pc))
-    pc = unmake_compact_addr (pc);
   return pc;
 }
 
@@ -1263,8 +1379,6 @@ mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
   CORE_ADDR pc;
 
   pc = frame_unwind_register_signed (next_frame, gdbarch_pc_regnum (gdbarch));
-  if (is_compact_addr (pc))
-    pc = unmake_compact_addr (pc);
   /* macro/2012-04-20: This hack skips over MIPS16 call thunks as
      intermediate frames.  In this case we can get the caller's address
      from $ra, or if $ra contains an address within a thunk as well, then
@@ -1274,15 +1388,9 @@ mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
     {
       pc = frame_unwind_register_signed
             (next_frame, gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM);
-      if (is_compact_addr (pc))
-       pc = unmake_compact_addr (pc);
       if (mips_in_frame_stub (pc))
-       {
-         pc = frame_unwind_register_signed
-                (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
-         if (is_compact_addr (pc))
-           pc = unmake_compact_addr (pc);
-       }
+       pc = frame_unwind_register_signed
+              (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
     }
   return pc;
 }
@@ -1316,10 +1424,7 @@ mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
   int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
 
-  if (mips_pc_is_mips (pc))
-    regcache_cooked_write_unsigned (regcache, regnum, pc);
-  else
-    regcache_cooked_write_unsigned (regcache, regnum, make_compact_addr (pc));
+  regcache_cooked_write_unsigned (regcache, regnum, pc);
 }
 
 /* Fetch and return instruction from the specified location.  Handle
@@ -1327,12 +1432,12 @@ mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
 
 static ULONGEST
 mips_fetch_instruction (struct gdbarch *gdbarch,
-                       enum mips_isa isa, CORE_ADDR addr, int *statusp)
+                       enum mips_isa isa, CORE_ADDR addr, int *errp)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[MIPS_INSN32_SIZE];
   int instlen;
-  int status;
+  int err;
 
   switch (isa)
     {
@@ -1348,13 +1453,13 @@ mips_fetch_instruction (struct gdbarch *gdbarch,
       internal_error (__FILE__, __LINE__, _("invalid ISA"));
       break;
     }
-  status = target_read_memory (addr, buf, instlen);
-  if (statusp != NULL)
-    *statusp = status;
-  if (status)
+  err = target_read_memory (addr, buf, instlen);
+  if (errp != NULL)
+    *errp = err;
+  if (err != 0)
     {
-      if (statusp == NULL)
-       memory_error (status, addr);
+      if (errp == NULL)
+       memory_error (TARGET_XFER_E_IO, addr);
       return 0;
     }
   return extract_unsigned_integer (buf, instlen, byte_order);
@@ -1416,10 +1521,8 @@ mips_insn_size (enum mips_isa isa, ULONGEST insn)
   switch (isa)
     {
     case ISA_MICROMIPS:
-      if (micromips_op (insn) == 0x1f)
-        return 3 * MIPS_INSN16_SIZE;
-      else if (((micromips_op (insn) & 0x4) == 0x4)
-              || ((micromips_op (insn) & 0x7) == 0x0))
+      if ((micromips_op (insn) & 0x4) == 0x4
+         || (micromips_op (insn) & 0x7) == 0x0)
         return 2 * MIPS_INSN16_SIZE;
       else
         return MIPS_INSN16_SIZE;
@@ -1445,7 +1548,7 @@ mips32_relative_offset (ULONGEST inst)
    number of the floating condition bits tested by the branch.  */
 
 static CORE_ADDR
-mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
+mips32_bc1_pc (struct gdbarch *gdbarch, struct regcache *regcache,
               ULONGEST inst, CORE_ADDR pc, int count)
 {
   int fcsr = mips_regnum (gdbarch)->fp_control_status;
@@ -1459,7 +1562,7 @@ mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
     /* No way to handle; it'll most likely trap anyway.  */
     return pc;
 
-  fcs = get_frame_register_unsigned (frame, fcsr);
+  fcs = regcache_raw_get_unsigned (regcache, fcsr);
   cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
 
   if (((cond >> cnum) & mask) != mask * !tf)
@@ -1503,9 +1606,9 @@ is_octeon_bbit_op (int op, struct gdbarch *gdbarch)
    branch prediction.  */
 
 static CORE_ADDR
-mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
+mips32_next_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   unsigned long inst;
   int op;
   inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
@@ -1532,15 +1635,15 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
        }
       else if (op == 17 && itype_rs (inst) == 8)
        /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
-       pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 1);
+       pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 1);
       else if (op == 17 && itype_rs (inst) == 9
               && (itype_rt (inst) & 2) == 0)
        /* BC1ANY2F, BC1ANY2T: 010001 01001 xxx0x */
-       pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 2);
+       pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 2);
       else if (op == 17 && itype_rs (inst) == 10
               && (itype_rt (inst) & 2) == 0)
        /* BC1ANY4F, BC1ANY4T: 010001 01010 xxx0x */
-       pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 4);
+       pc = mips32_bc1_pc (gdbarch, regcache, inst, pc + 4, 4);
       else if (op == 29)
        /* JALX: 011101 */
        /* The new PC will be alternate mode.  */
@@ -1562,8 +1665,8 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
          if (op == 54 || op == 62)
            bit += 32;
 
-         if (((get_frame_register_signed (frame,
-                                          itype_rs (inst)) >> bit) & 1)
+         if (((regcache_raw_get_signed (regcache,
+                                        itype_rs (inst)) >> bit) & 1)
               == branch_if)
            pc += mips32_relative_offset (inst) + 4;
           else
@@ -1586,15 +1689,15 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
            case 8:             /* JR */
            case 9:             /* JALR */
              /* Set PC to that address.  */
-             pc = get_frame_register_signed (frame, rtype_rs (inst));
+             pc = regcache_raw_get_signed (regcache, rtype_rs (inst));
              break;
            case 12:            /* SYSCALL */
              {
                struct gdbarch_tdep *tdep;
 
-               tdep = gdbarch_tdep (get_frame_arch (frame));
+               tdep = gdbarch_tdep (gdbarch);
                if (tdep->syscall_next_pc != NULL)
-                 pc = tdep->syscall_next_pc (frame);
+                 pc = tdep->syscall_next_pc (get_current_frame ());
                else
                  pc += 4;
              }
@@ -1614,7 +1717,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
              case 16:          /* BLTZAL */
              case 18:          /* BLTZALL */
              less_branch:
-               if (get_frame_register_signed (frame, itype_rs (inst)) < 0)
+               if (regcache_raw_get_signed (regcache, itype_rs (inst)) < 0)
                  pc += mips32_relative_offset (inst) + 4;
                else
                  pc += 8;      /* after the delay slot */
@@ -1623,7 +1726,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
              case 3:           /* BGEZL */
              case 17:          /* BGEZAL */
              case 19:          /* BGEZALL */
-               if (get_frame_register_signed (frame, itype_rs (inst)) >= 0)
+               if (regcache_raw_get_signed (regcache, itype_rs (inst)) >= 0)
                  pc += mips32_relative_offset (inst) + 4;
                else
                  pc += 8;      /* after the delay slot */
@@ -1640,8 +1743,8 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
                      /* No way to handle; it'll most likely trap anyway.  */
                      break;
 
-                   if ((get_frame_register_unsigned (frame,
-                                                     dspctl) & 0x7f) >= pos)
+                   if ((regcache_raw_get_unsigned (regcache,
+                                                   dspctl) & 0x7f) >= pos)
                      pc += mips32_relative_offset (inst);
                    else
                      pc += 4;
@@ -1664,22 +1767,22 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
          break;
        case 4:         /* BEQ, BEQL */
        equal_branch:
-         if (get_frame_register_signed (frame, itype_rs (inst)) ==
-             get_frame_register_signed (frame, itype_rt (inst)))
+         if (regcache_raw_get_signed (regcache, itype_rs (inst)) ==
+             regcache_raw_get_signed (regcache, itype_rt (inst)))
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
        case 5:         /* BNE, BNEL */
        neq_branch:
-         if (get_frame_register_signed (frame, itype_rs (inst)) !=
-             get_frame_register_signed (frame, itype_rt (inst)))
+         if (regcache_raw_get_signed (regcache, itype_rs (inst)) !=
+             regcache_raw_get_signed (regcache, itype_rt (inst)))
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
          break;
        case 6:         /* BLEZ, BLEZL */
-         if (get_frame_register_signed (frame, itype_rs (inst)) <= 0)
+         if (regcache_raw_get_signed (regcache, itype_rs (inst)) <= 0)
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
@@ -1687,7 +1790,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
        case 7:
        default:
        greater_branch: /* BGTZ, BGTZL */
-         if (get_frame_register_signed (frame, itype_rs (inst)) > 0)
+         if (regcache_raw_get_signed (regcache, itype_rs (inst)) > 0)
            pc += mips32_relative_offset (inst) + 4;
          else
            pc += 8;
@@ -1741,7 +1844,7 @@ micromips_pc_insn_size (struct gdbarch *gdbarch, CORE_ADDR pc)
    examined by the branch.  */
 
 static CORE_ADDR
-micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
+micromips_bc1_pc (struct gdbarch *gdbarch, struct regcache *regcache,
                  ULONGEST insn, CORE_ADDR pc, int count)
 {
   int fcsr = mips_regnum (gdbarch)->fp_control_status;
@@ -1755,7 +1858,7 @@ micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
     /* No way to handle; it'll most likely trap anyway.  */
     return pc;
 
-  fcs = get_frame_register_unsigned (frame, fcsr);
+  fcs = regcache_raw_get_unsigned (regcache, fcsr);
   cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
 
   if (((cond >> cnum) & mask) != mask * !tf)
@@ -1770,21 +1873,15 @@ micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
    after the instruction at the address PC.  */
 
 static CORE_ADDR
-micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
+micromips_next_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   ULONGEST insn;
 
   insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
   pc += MIPS_INSN16_SIZE;
   switch (mips_insn_size (ISA_MICROMIPS, insn))
     {
-    /* 48-bit instructions.  */
-    case 3 * MIPS_INSN16_SIZE: /* POOL48A: bits 011111 */
-      /* No branch or jump instructions in this category.  */
-      pc += 2 * MIPS_INSN16_SIZE;
-      break;
-
     /* 32-bit instructions.  */
     case 2 * MIPS_INSN16_SIZE:
       insn <<= 16;
@@ -1798,7 +1895,7 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
              && (b6s10_ext (insn) & 0x2bf) == 0x3c)
                                /* JALR, JALR.HB: 000000 000x111100 111100 */
                                /* JALRS, JALRS.HB: 000000 010x111100 111100 */
-           pc = get_frame_register_signed (frame, b0s5_reg (insn >> 16));
+           pc = regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16));
          break;
 
        case 0x10: /* POOL32I: bits 010000 */
@@ -1807,8 +1904,8 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
            case 0x00: /* BLTZ: bits 010000 00000 */
            case 0x01: /* BLTZAL: bits 010000 00001 */
            case 0x11: /* BLTZALS: bits 010000 10001 */
-             if (get_frame_register_signed (frame,
-                                            b0s5_reg (insn >> 16)) < 0)
+             if (regcache_raw_get_signed (regcache,
+                                          b0s5_reg (insn >> 16)) < 0)
                pc += micromips_relative_offset16 (insn);
              else
                pc += micromips_pc_insn_size (gdbarch, pc);
@@ -1817,38 +1914,38 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
            case 0x02: /* BGEZ: bits 010000 00010 */
            case 0x03: /* BGEZAL: bits 010000 00011 */
            case 0x13: /* BGEZALS: bits 010000 10011 */
-             if (get_frame_register_signed (frame,
-                                            b0s5_reg (insn >> 16)) >= 0)
+             if (regcache_raw_get_signed (regcache,
+                                          b0s5_reg (insn >> 16)) >= 0)
                pc += micromips_relative_offset16 (insn);
              else
                pc += micromips_pc_insn_size (gdbarch, pc);
              break;
 
            case 0x04: /* BLEZ: bits 010000 00100 */
-             if (get_frame_register_signed (frame,
-                                            b0s5_reg (insn >> 16)) <= 0)
+             if (regcache_raw_get_signed (regcache,
+                                          b0s5_reg (insn >> 16)) <= 0)
                pc += micromips_relative_offset16 (insn);
              else
                pc += micromips_pc_insn_size (gdbarch, pc);
              break;
 
            case 0x05: /* BNEZC: bits 010000 00101 */
-             if (get_frame_register_signed (frame,
-                                            b0s5_reg (insn >> 16)) != 0)
+             if (regcache_raw_get_signed (regcache,
+                                          b0s5_reg (insn >> 16)) != 0)
                pc += micromips_relative_offset16 (insn);
              break;
 
            case 0x06: /* BGTZ: bits 010000 00110 */
-             if (get_frame_register_signed (frame,
-                                            b0s5_reg (insn >> 16)) > 0)
+             if (regcache_raw_get_signed (regcache,
+                                          b0s5_reg (insn >> 16)) > 0)
                pc += micromips_relative_offset16 (insn);
              else
                pc += micromips_pc_insn_size (gdbarch, pc);
              break;
 
            case 0x07: /* BEQZC: bits 010000 00111 */
-             if (get_frame_register_signed (frame,
-                                            b0s5_reg (insn >> 16)) == 0)
+             if (regcache_raw_get_signed (regcache,
+                                          b0s5_reg (insn >> 16)) == 0)
                pc += micromips_relative_offset16 (insn);
              break;
 
@@ -1869,8 +1966,8 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
                  /* No way to handle; it'll most likely trap anyway.  */
                  break;
 
-               if ((get_frame_register_unsigned (frame,
-                                                 dspctl) & 0x7f) >= pos)
+               if ((regcache_raw_get_unsigned (regcache,
+                                               dspctl) & 0x7f) >= pos)
                  pc += micromips_relative_offset16 (insn);
                else
                  pc += micromips_pc_insn_size (gdbarch, pc);
@@ -1882,14 +1979,14 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
            case 0x1d: /* BC1T: bits 010000 11101 xxx00 */
                       /* BC1ANY2T: bits 010000 11101 xxx01 */
              if (((insn >> 16) & 0x2) == 0x0)
-               pc = micromips_bc1_pc (gdbarch, frame, insn, pc,
+               pc = micromips_bc1_pc (gdbarch, regcache, insn, pc,
                                       ((insn >> 16) & 0x1) + 1);
              break;
 
            case 0x1e: /* BC1ANY4F: bits 010000 11110 xxx01 */
            case 0x1f: /* BC1ANY4T: bits 010000 11111 xxx01 */
              if (((insn >> 16) & 0x3) == 0x1)
-               pc = micromips_bc1_pc (gdbarch, frame, insn, pc, 4);
+               pc = micromips_bc1_pc (gdbarch, regcache, insn, pc, 4);
              break;
            }
          break;
@@ -1901,16 +1998,16 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
          break;
 
        case 0x25: /* BEQ: bits 100101 */
-           if (get_frame_register_signed (frame, b0s5_reg (insn >> 16))
-               == get_frame_register_signed (frame, b5s5_reg (insn >> 16)))
+           if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
+               == regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16)))
              pc += micromips_relative_offset16 (insn);
            else
              pc += micromips_pc_insn_size (gdbarch, pc);
          break;
 
        case 0x2d: /* BNE: bits 101101 */
-           if (get_frame_register_signed (frame, b0s5_reg (insn >> 16))
-               != get_frame_register_signed (frame, b5s5_reg (insn >> 16)))
+         if (regcache_raw_get_signed (regcache, b0s5_reg (insn >> 16))
+               != regcache_raw_get_signed (regcache, b5s5_reg (insn >> 16)))
              pc += micromips_relative_offset16 (insn);
            else
              pc += micromips_pc_insn_size (gdbarch, pc);
@@ -1929,17 +2026,17 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
        case 0x11: /* POOL16C: bits 010001 */
          if ((b5s5_op (insn) & 0x1c) == 0xc)
            /* JR16, JRC, JALR16, JALRS16: 010001 011xx */
-           pc = get_frame_register_signed (frame, b0s5_reg (insn));
+           pc = regcache_raw_get_signed (regcache, b0s5_reg (insn));
          else if (b5s5_op (insn) == 0x18)
            /* JRADDIUSP: bits 010001 11000 */
-           pc = get_frame_register_signed (frame, MIPS_RA_REGNUM);
+           pc = regcache_raw_get_signed (regcache, MIPS_RA_REGNUM);
          break;
 
        case 0x23: /* BEQZ16: bits 100011 */
          {
            int rs = mips_reg3_to_reg[b7s3_reg (insn)];
 
-           if (get_frame_register_signed (frame, rs) == 0)
+           if (regcache_raw_get_signed (regcache, rs) == 0)
              pc += micromips_relative_offset7 (insn);
            else
              pc += micromips_pc_insn_size (gdbarch, pc);
@@ -1950,7 +2047,7 @@ micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
          {
            int rs = mips_reg3_to_reg[b7s3_reg (insn)];
 
-           if (get_frame_register_signed (frame, rs) != 0)
+           if (regcache_raw_get_signed (regcache, rs) != 0)
              pc += micromips_relative_offset7 (insn);
            else
              pc += micromips_pc_insn_size (gdbarch, pc);
@@ -2119,17 +2216,20 @@ unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
 }
 
 
+/* Calculate the destination of a branch whose 16-bit opcode word is at PC,
+   and having a signed 16-bit OFFSET.  */
+
 static CORE_ADDR
 add_offset_16 (CORE_ADDR pc, int offset)
 {
-  return ((offset << 2) | ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)));
+  return pc + (offset << 1) + 2;
 }
 
 static CORE_ADDR
-extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
+extended_mips16_next_pc (regcache *regcache, CORE_ADDR pc,
                         unsigned int extension, unsigned int insn)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   int op = (insn >> 11);
   switch (op)
     {
@@ -2137,7 +2237,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
       {
        struct upk_mips16 upk;
        unpack_mips16 (gdbarch, pc, extension, insn, itype, &upk);
-       pc += (upk.offset << 1) + 2;
+       pc = add_offset_16 (pc, upk.offset);
        break;
       }
     case 3:                    /* JAL , JALX - Watch out, these are 32 bit
@@ -2145,7 +2245,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
       {
        struct upk_mips16 upk;
        unpack_mips16 (gdbarch, pc, extension, insn, jalxtype, &upk);
-       pc = add_offset_16 (pc, upk.offset);
+       pc = ((pc + 2) & (~(CORE_ADDR) 0x0fffffff)) | (upk.offset << 2);
        if ((insn >> 10) & 0x01)        /* Exchange mode */
          pc = pc & ~0x01;      /* Clear low bit, indicate 32 bit mode.  */
        else
@@ -2157,9 +2257,9 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        struct upk_mips16 upk;
        int reg;
        unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
-       reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]);
+       reg = regcache_raw_get_signed (regcache, mips_reg3_to_reg[upk.regx]);
        if (reg == 0)
-         pc += (upk.offset << 1) + 2;
+         pc = add_offset_16 (pc, upk.offset);
        else
          pc += 2;
        break;
@@ -2169,9 +2269,9 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        struct upk_mips16 upk;
        int reg;
        unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
-       reg = get_frame_register_signed (frame, mips_reg3_to_reg[upk.regx]);
+       reg = regcache_raw_get_signed (regcache, mips_reg3_to_reg[upk.regx]);
        if (reg != 0)
-         pc += (upk.offset << 1) + 2;
+         pc = add_offset_16 (pc, upk.offset);
        else
          pc += 2;
        break;
@@ -2182,11 +2282,11 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        int reg;
        unpack_mips16 (gdbarch, pc, extension, insn, i8type, &upk);
        /* upk.regx contains the opcode */
-       reg = get_frame_register_signed (frame, 24);  /* Test register is 24 */
+       /* Test register is 24 */
+       reg = regcache_raw_get_signed (regcache, 24);
        if (((upk.regx == 0) && (reg == 0))     /* BTEZ */
            || ((upk.regx == 1) && (reg != 0))) /* BTNEZ */
-         /* pc = add_offset_16(pc,upk.offset) ; */
-         pc += (upk.offset << 1) + 2;
+         pc = add_offset_16 (pc, upk.offset);
        else
          pc += 2;
        break;
@@ -2205,7 +2305,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
              reg = mips_reg3_to_reg[upk.regx];
            else
              reg = 31;         /* Function return instruction.  */
-           pc = get_frame_register_signed (frame, reg);
+           pc = regcache_raw_get_signed (regcache, reg);
          }
        else
          pc += 2;
@@ -2217,7 +2317,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
          that.  */
       {
        pc += 2;
-       pc = extended_mips16_next_pc (frame, pc, insn,
+       pc = extended_mips16_next_pc (regcache, pc, insn,
                                      fetch_mips_16 (gdbarch, pc));
        break;
       }
@@ -2231,11 +2331,11 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
 }
 
 static CORE_ADDR
-mips16_next_pc (struct frame_info *frame, CORE_ADDR pc)
+mips16_next_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   unsigned int insn = fetch_mips_16 (gdbarch, pc);
-  return extended_mips16_next_pc (frame, pc, 0, insn);
+  return extended_mips16_next_pc (regcache, pc, 0, insn);
 }
 
 /* The mips_next_pc function supports single_step when the remote
@@ -2244,16 +2344,58 @@ mips16_next_pc (struct frame_info *frame, CORE_ADDR pc)
    branch will go.  This isn't hard because all the data is available.
    The MIPS32, MIPS16 and microMIPS variants are quite different.  */
 static CORE_ADDR
-mips_next_pc (struct frame_info *frame, CORE_ADDR pc)
+mips_next_pc (struct regcache *regcache, CORE_ADDR pc)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
 
   if (mips_pc_is_mips16 (gdbarch, pc))
-    return mips16_next_pc (frame, pc);
+    return mips16_next_pc (regcache, pc);
   else if (mips_pc_is_micromips (gdbarch, pc))
-    return micromips_next_pc (frame, pc);
+    return micromips_next_pc (regcache, pc);
   else
-    return mips32_next_pc (frame, pc);
+    return mips32_next_pc (regcache, pc);
+}
+
+/* Return non-zero if the MIPS16 instruction INSN is a compact branch
+   or jump.  */
+
+static int
+mips16_instruction_is_compact_branch (unsigned short insn)
+{
+  switch (insn & 0xf800)
+    {
+    case 0xe800:
+      return (insn & 0x009f) == 0x80;  /* JALRC/JRC */
+    case 0x6000:
+      return (insn & 0x0600) == 0;     /* BTNEZ/BTEQZ */
+    case 0x2800:                       /* BNEZ */
+    case 0x2000:                       /* BEQZ */
+    case 0x1000:                       /* B */
+      return 1;
+    default:
+      return 0;
+    }
+}
+
+/* Return non-zero if the microMIPS instruction INSN is a compact branch
+   or jump.  */
+
+static int
+micromips_instruction_is_compact_branch (unsigned short insn)
+{
+  switch (micromips_op (insn))
+    {
+    case 0x11:                 /* POOL16C: bits 010001 */
+      return (b5s5_op (insn) == 0x18
+                               /* JRADDIUSP: bits 010001 11000 */
+             || b5s5_op (insn) == 0xd);
+                               /* JRC: bits 010011 01101 */
+    case 0x10:                 /* POOL32I: bits 010000 */
+      return (b5s5_op (insn) & 0x1d) == 0x5;
+                               /* BEQZC/BNEZC: bits 010000 001x1 */
+    default:
+      return 0;
+    }
 }
 
 struct mips_frame_cache
@@ -2333,6 +2475,10 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
                       struct frame_info *this_frame,
                       struct mips_frame_cache *this_cache)
 {
+  int prev_non_prologue_insn = 0;
+  int this_non_prologue_insn;
+  int non_prologue_insns = 0;
+  CORE_ADDR prev_pc;
   CORE_ADDR cur_pc;
   CORE_ADDR frame_addr = 0;    /* Value of $r17, used as frame pointer.  */
   CORE_ADDR sp;
@@ -2343,11 +2489,13 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
   unsigned inst = 0;           /* current instruction */
   unsigned entry_inst = 0;     /* the entry instruction */
   unsigned save_inst = 0;      /* the save instruction */
+  int prev_delay_slot = 0;
+  int in_delay_slot;
   int reg, offset;
 
   int extend_bytes = 0;
-  int prev_extend_bytes;
-  CORE_ADDR end_prologue_addr = 0;
+  int prev_extend_bytes = 0;
+  CORE_ADDR end_prologue_addr;
 
   /* Can be called when there's no process, and hence when there's no
      THIS_FRAME.  */
@@ -2360,9 +2508,16 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
 
   if (limit_pc > start_pc + 200)
     limit_pc = start_pc + 200;
+  prev_pc = start_pc;
 
+  /* Permit at most one non-prologue non-control-transfer instruction
+     in the middle which may have been reordered by the compiler for
+     optimisation.  */
   for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN16_SIZE)
     {
+      this_non_prologue_insn = 0;
+      in_delay_slot = 0;
+
       /* Save the previous instruction.  If it's an EXTEND, we'll extract
          the immediate offset extension from it in mips16_get_imm.  */
       prev_inst = inst;
@@ -2452,21 +2607,40 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
          if (prev_extend_bytes)                /* extend */
            save_inst |= prev_inst << 16;
        }
-      else if ((inst & 0xf800) == 0x1800)      /* jal(x) */
-       cur_pc += MIPS_INSN16_SIZE;     /* 32-bit instruction */
       else if ((inst & 0xff1c) == 0x6704)      /* move reg,$a0-$a3 */
         {
           /* This instruction is part of the prologue, but we don't
              need to do anything special to handle it.  */
         }
+      else if (mips16_instruction_has_delay_slot (inst, 0))
+                                               /* JAL/JALR/JALX/JR */
+       {
+         /* The instruction in the delay slot can be a part
+            of the prologue, so move forward once more.  */
+         in_delay_slot = 1;
+         if (mips16_instruction_has_delay_slot (inst, 1))
+                                               /* JAL/JALX */
+           {
+             prev_extend_bytes = MIPS_INSN16_SIZE;
+             cur_pc += MIPS_INSN16_SIZE;       /* 32-bit instruction */
+           }
+       }
       else
         {
-          /* This instruction is not an instruction typically found
-             in a prologue, so we must have reached the end of the
-             prologue.  */
-          if (end_prologue_addr == 0)
-            end_prologue_addr = cur_pc - prev_extend_bytes;
+         this_non_prologue_insn = 1;
         }
+
+      non_prologue_insns += this_non_prologue_insn;
+
+      /* A jump or branch, or enough non-prologue insns seen?  If so,
+         then we must have reached the end of the prologue by now.  */
+      if (prev_delay_slot || non_prologue_insns > 1
+         || mips16_instruction_is_compact_branch (inst))
+       break;
+
+      prev_non_prologue_insn = this_non_prologue_insn;
+      prev_delay_slot = in_delay_slot;
+      prev_pc = cur_pc - prev_extend_bytes;
     }
 
   /* The entry instruction is typically the first instruction in a function,
@@ -2619,11 +2793,12 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
         = this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM];
     }
 
-  /* If we didn't reach the end of the prologue when scanning the function
-     instructions, then set end_prologue_addr to the address of the
-     instruction immediately after the last one we scanned.  */
-  if (end_prologue_addr == 0)
-    end_prologue_addr = cur_pc;
+  /* Set end_prologue_addr to the address of the instruction immediately
+     after the last one we scanned.  Unless the last one looked like a
+     non-prologue instruction (and we looked ahead), in which case use
+     its address instead.  */
+  end_prologue_addr = (prev_non_prologue_insn || prev_delay_slot
+                      ? prev_pc : cur_pc - prev_extend_bytes);
 
   return end_prologue_addr;
 }
@@ -2639,7 +2814,7 @@ mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache)
   struct mips_frame_cache *cache;
 
   if ((*this_cache) != NULL)
-    return (*this_cache);
+    return (struct mips_frame_cache *) (*this_cache);
   cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
   (*this_cache) = cache;
   cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
@@ -2657,7 +2832,8 @@ mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache)
     if (start_addr == 0)
       return cache;
 
-    mips16_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache);
+    mips16_scan_prologue (gdbarch, start_addr, pc, this_frame,
+                         (struct mips_frame_cache *) *this_cache);
   }
   
   /* gdbarch_sp_regnum contains the value and not the address.  */
@@ -2665,7 +2841,7 @@ mips_insn16_frame_cache (struct frame_info *this_frame, void **this_cache)
                        gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM,
                        cache->base);
 
-  return (*this_cache);
+  return (struct mips_frame_cache *) (*this_cache);
 }
 
 static void
@@ -2760,14 +2936,15 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
                         struct frame_info *this_frame,
                         struct mips_frame_cache *this_cache)
 {
-  CORE_ADDR end_prologue_addr = 0;
+  CORE_ADDR end_prologue_addr;
   int prev_non_prologue_insn = 0;
   int frame_reg = MIPS_SP_REGNUM;
   int this_non_prologue_insn;
   int non_prologue_insns = 0;
   long frame_offset = 0;       /* Size of stack frame.  */
   long frame_adjust = 0;       /* Offset of FP from SP.  */
-  CORE_ADDR frame_addr = 0;    /* Value of $30, used as frame pointer.  */
+  int prev_delay_slot = 0;
+  int in_delay_slot;
   CORE_ADDR prev_pc;
   CORE_ADDR cur_pc;
   ULONGEST insn;               /* current instruction */
@@ -2804,19 +2981,13 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
   for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += loc)
     {
       this_non_prologue_insn = 0;
+      in_delay_slot = 0;
       sp_adj = 0;
       loc = 0;
       insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, cur_pc, NULL);
       loc += MIPS_INSN16_SIZE;
       switch (mips_insn_size (ISA_MICROMIPS, insn))
        {
-       /* 48-bit instructions.  */
-       case 3 * MIPS_INSN16_SIZE:
-         /* No prologue instructions in this category.  */
-         this_non_prologue_insn = 1;
-         loc += 2 * MIPS_INSN16_SIZE;
-         break;
-
        /* 32-bit instructions.  */
        case 2 * MIPS_INSN16_SIZE:
          insn <<= 16;
@@ -2872,7 +3043,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
                       && ((reglist >= 1 && reglist <= 9)
                           || (reglist >= 16 && reglist <= 25)))
                {
-                 int sreglist = min(reglist & 0xf, 8);
+                 int sreglist = std::min(reglist & 0xf, 8);
 
                  s = 4 << ((b12s4_op (insn) & 0x2) == 0x2);
                  for (i = 0; i < sreglist; i++)
@@ -2900,7 +3071,6 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
              else if (sreg == MIPS_SP_REGNUM && dreg == 30)
                                /* (D)ADDIU $fp, $sp, imm */
                {
-                 frame_addr = sp + offset;
                  frame_adjust = offset;
                  frame_reg = 30;
                }
@@ -2956,9 +3126,15 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
              break;
 
            default:
-             this_non_prologue_insn = 1;
+             /* The instruction in the delay slot can be a part
+                of the prologue, so move forward once more.  */
+             if (micromips_instruction_has_delay_slot (insn, 0))
+               in_delay_slot = 1;
+             else
+               this_non_prologue_insn = 1;
              break;
            }
+         insn >>= 16;
          break;
 
        /* 16-bit instructions.  */
@@ -2970,10 +3146,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
              dreg = b5s5_reg (insn);
              if (sreg == MIPS_SP_REGNUM && dreg == 30)
                                /* MOVE  $fp, $sp */
-               {
-                 frame_addr = sp;
-                 frame_reg = 30;
-               }
+               frame_reg = 30;
              else if ((sreg & 0x1c) != 0x4)
                                /* MOVE  reg, $a0-$a3 */
                this_non_prologue_insn = 1;
@@ -3013,7 +3186,12 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
              break;
 
            default:
-             this_non_prologue_insn = 1;
+             /* The instruction in the delay slot can be a part
+                of the prologue, so move forward once more.  */
+             if (micromips_instruction_has_delay_slot (insn << 16, 0))
+               in_delay_slot = 1;
+             else
+               this_non_prologue_insn = 1;
              break;
            }
          break;
@@ -3022,13 +3200,16 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
        frame_offset -= sp_adj;
 
       non_prologue_insns += this_non_prologue_insn;
-      /* Enough non-prologue insns seen or positive stack adjustment? */
-      if (end_prologue_addr == 0 && (non_prologue_insns > 1 || sp_adj > 0))
-       {
-         end_prologue_addr = prev_non_prologue_insn ? prev_pc : cur_pc;
-         break;
-       }
+
+      /* A jump or branch, enough non-prologue insns seen or positive
+         stack adjustment?  If so, then we must have reached the end
+         of the prologue by now.  */
+      if (prev_delay_slot || non_prologue_insns > 1 || sp_adj > 0
+         || micromips_instruction_is_compact_branch (insn))
+       break;
+
       prev_non_prologue_insn = this_non_prologue_insn;
+      prev_delay_slot = in_delay_slot;
       prev_pc = cur_pc;
     }
 
@@ -3046,13 +3227,12 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
        = this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM];
     }
 
-  /* If we didn't reach the end of the prologue when scanning the function
-     instructions, then set end_prologue_addr to the address of the
-     instruction immediately after the last one we scanned.  Unless the
-     last one looked like a non-prologue instruction (and we looked ahead),
-     in which case use its address instead.  */
-  if (end_prologue_addr == 0)
-    end_prologue_addr = prev_non_prologue_insn ? prev_pc : cur_pc;
+  /* Set end_prologue_addr to the address of the instruction immediately
+     after the last one we scanned.  Unless the last one looked like a
+     non-prologue instruction (and we looked ahead), in which case use
+     its address instead.  */
+  end_prologue_addr
+    = prev_non_prologue_insn || prev_delay_slot ? prev_pc : cur_pc;
 
   return end_prologue_addr;
 }
@@ -3068,7 +3248,7 @@ mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache)
   struct mips_frame_cache *cache;
 
   if ((*this_cache) != NULL)
-    return (*this_cache);
+    return (struct mips_frame_cache *) (*this_cache);
 
   cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
   (*this_cache) = cache;
@@ -3087,7 +3267,8 @@ mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache)
     if (start_addr == 0)
       return cache;
 
-    micromips_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache);
+    micromips_scan_prologue (gdbarch, start_addr, pc, this_frame,
+                            (struct mips_frame_cache *) *this_cache);
   }
 
   /* gdbarch_sp_regnum contains the value and not the address.  */
@@ -3095,7 +3276,7 @@ mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache)
                        gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM,
                        cache->base);
 
-  return (*this_cache);
+  return (struct mips_frame_cache *) (*this_cache);
 }
 
 static void
@@ -3200,17 +3381,22 @@ mips32_scan_prologue (struct gdbarch *gdbarch,
                       struct frame_info *this_frame,
                       struct mips_frame_cache *this_cache)
 {
-  CORE_ADDR cur_pc;
+  int prev_non_prologue_insn;
+  int this_non_prologue_insn;
+  int non_prologue_insns;
   CORE_ADDR frame_addr = 0; /* Value of $r30. Used by gcc for
                               frame-pointer.  */
+  int prev_delay_slot;
+  CORE_ADDR prev_pc;
+  CORE_ADDR cur_pc;
   CORE_ADDR sp;
   long frame_offset;
   int  frame_reg = MIPS_SP_REGNUM;
 
-  CORE_ADDR end_prologue_addr = 0;
+  CORE_ADDR end_prologue_addr;
   int seen_sp_adjust = 0;
   int load_immediate_bytes = 0;
-  int in_delay_slot = 0;
+  int in_delay_slot;
   int regsize_is_64_bits = (mips_abi_regsize (gdbarch) == 8);
 
   /* Can be called when there's no process, and hence when there's no
@@ -3226,28 +3412,39 @@ mips32_scan_prologue (struct gdbarch *gdbarch,
     limit_pc = start_pc + 200;
 
 restart:
+  prev_non_prologue_insn = 0;
+  non_prologue_insns = 0;
+  prev_delay_slot = 0;
+  prev_pc = start_pc;
 
+  /* Permit at most one non-prologue non-control-transfer instruction
+     in the middle which may have been reordered by the compiler for
+     optimisation.  */
   frame_offset = 0;
   for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN32_SIZE)
     {
-      unsigned long inst, high_word, low_word;
+      unsigned long inst, high_word;
+      long offset;
       int reg;
 
+      this_non_prologue_insn = 0;
+      in_delay_slot = 0;
+
       /* Fetch the instruction.  */
       inst = (unsigned long) mips_fetch_instruction (gdbarch, ISA_MIPS,
                                                     cur_pc, NULL);
 
       /* Save some code by pre-extracting some useful fields.  */
       high_word = (inst >> 16) & 0xffff;
-      low_word = inst & 0xffff;
+      offset = ((inst & 0xffff) ^ 0x8000) - 0x8000;
       reg = high_word & 0x1f;
 
       if (high_word == 0x27bd          /* addiu $sp,$sp,-i */
          || high_word == 0x23bd        /* addi $sp,$sp,-i */
          || high_word == 0x67bd)       /* daddiu $sp,$sp,-i */
        {
-         if (low_word & 0x8000)        /* Negative stack adjustment?  */
-            frame_offset += 0x10000 - low_word;
+         if (offset < 0)               /* Negative stack adjustment?  */
+            frame_offset -= offset;
          else
            /* Exit loop if a positive stack adjustment is found, which
               usually means that the stack cleanup code in the function
@@ -3258,19 +3455,19 @@ restart:
       else if (((high_word & 0xFFE0) == 0xafa0) /* sw reg,offset($sp) */
                && !regsize_is_64_bits)
        {
-         set_reg_offset (gdbarch, this_cache, reg, sp + low_word);
+         set_reg_offset (gdbarch, this_cache, reg, sp + offset);
        }
       else if (((high_word & 0xFFE0) == 0xffa0)        /* sd reg,offset($sp) */
                && regsize_is_64_bits)
        {
          /* Irix 6.2 N32 ABI uses sd instructions for saving $gp and $ra.  */
-         set_reg_offset (gdbarch, this_cache, reg, sp + low_word);
+         set_reg_offset (gdbarch, this_cache, reg, sp + offset);
        }
       else if (high_word == 0x27be)    /* addiu $30,$sp,size */
        {
          /* Old gcc frame, r30 is virtual frame pointer.  */
-         if ((long) low_word != frame_offset)
-           frame_addr = sp + low_word;
+         if (offset != frame_offset)
+           frame_addr = sp + offset;
          else if (this_frame && frame_reg == MIPS_SP_REGNUM)
            {
              unsigned alloca_adjust;
@@ -3280,7 +3477,7 @@ restart:
                (this_frame, gdbarch_num_regs (gdbarch) + 30);
              frame_offset = 0;
 
-             alloca_adjust = (unsigned) (frame_addr - (sp + low_word));
+             alloca_adjust = (unsigned) (frame_addr - (sp + offset));
              if (alloca_adjust > 0)
                {
                   /* FP > SP + frame_size.  This may be because of
@@ -3329,7 +3526,7 @@ restart:
       else if ((high_word & 0xFFE0) == 0xafc0  /* sw reg,offset($30) */
                && !regsize_is_64_bits)
        {
-         set_reg_offset (gdbarch, this_cache, reg, frame_addr + low_word);
+         set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset);
        }
       else if ((high_word & 0xFFE0) == 0xE7A0 /* swc1 freg,n($sp) */
                || (high_word & 0xF3E0) == 0xA3C0 /* sx reg,n($s8) */
@@ -3349,6 +3546,7 @@ restart:
          initialize a local variable, so we accept them only before
          a stack adjustment instruction was seen.  */
       else if (!seen_sp_adjust
+              && !prev_delay_slot
               && (high_word == 0x3c01 /* lui $at,n */
                   || high_word == 0x3c08 /* lui $t0,n */
                   || high_word == 0x3421 /* ori $at,$at,n */
@@ -3357,31 +3555,32 @@ restart:
                   || high_word == 0x3408 /* ori $t0,$zero,n */
                  ))
        {
-         if (end_prologue_addr == 0)
-           load_immediate_bytes += MIPS_INSN32_SIZE;           /* FIXME!  */
+         load_immediate_bytes += MIPS_INSN32_SIZE;             /* FIXME!  */
+       }
+      /* Check for branches and jumps.  The instruction in the delay
+         slot can be a part of the prologue, so move forward once more.  */
+      else if (mips32_instruction_has_delay_slot (gdbarch, inst))
+       {
+         in_delay_slot = 1;
        }
+      /* This instruction is not an instruction typically found
+         in a prologue, so we must have reached the end of the
+         prologue.  */
       else
        {
-         /* This instruction is not an instruction typically found
-            in a prologue, so we must have reached the end of the
-            prologue.  */
-         /* FIXME: brobecker/2004-10-10: Can't we just break out of this
-            loop now?  Why would we need to continue scanning the function
-            instructions?  */
-         if (end_prologue_addr == 0)
-           end_prologue_addr = cur_pc;
-
-         /* Check for branches and jumps.  For now, only jump to
-            register are caught (i.e. returns).  */
-         if ((itype_op (inst) & 0x07) == 0 && rtype_funct (inst) == 8)
-           in_delay_slot = 1;
+         this_non_prologue_insn = 1;
        }
 
-      /* If the previous instruction was a jump, we must have reached
-        the end of the prologue by now.  Stop scanning so that we do
-        not go past the function return.  */
-      if (in_delay_slot)
+      non_prologue_insns += this_non_prologue_insn;
+
+      /* A jump or branch, or enough non-prologue insns seen?  If so,
+         then we must have reached the end of the prologue by now.  */
+      if (prev_delay_slot || non_prologue_insns > 1)
        break;
+
+      prev_non_prologue_insn = this_non_prologue_insn;
+      prev_delay_slot = in_delay_slot;
+      prev_pc = cur_pc;
     }
 
   if (this_cache != NULL)
@@ -3399,14 +3598,12 @@ restart:
                                 + MIPS_RA_REGNUM];
     }
 
-  /* If we didn't reach the end of the prologue when scanning the function
-     instructions, then set end_prologue_addr to the address of the
-     instruction immediately after the last one we scanned.  */
-  /* brobecker/2004-10-10: I don't think this would ever happen, but
-     we may as well be careful and do our best if we have a null
-     end_prologue_addr.  */
-  if (end_prologue_addr == 0)
-    end_prologue_addr = cur_pc;
+  /* Set end_prologue_addr to the address of the instruction immediately
+     after the last one we scanned.  Unless the last one looked like a
+     non-prologue instruction (and we looked ahead), in which case use
+     its address instead.  */
+  end_prologue_addr
+    = prev_non_prologue_insn || prev_delay_slot ? prev_pc : cur_pc;
      
   /* In a frameless function, we might have incorrectly
      skipped some load immediate instructions.  Undo the skipping
@@ -3429,7 +3626,7 @@ mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache)
   struct mips_frame_cache *cache;
 
   if ((*this_cache) != NULL)
-    return (*this_cache);
+    return (struct mips_frame_cache *) (*this_cache);
 
   cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
   (*this_cache) = cache;
@@ -3448,7 +3645,8 @@ mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache)
     if (start_addr == 0)
       return cache;
 
-    mips32_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache);
+    mips32_scan_prologue (gdbarch, start_addr, pc, this_frame,
+                         (struct mips_frame_cache *) *this_cache);
   }
   
   /* gdbarch_sp_regnum contains the value and not the address.  */
@@ -3456,7 +3654,7 @@ mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache)
                        gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM,
                        cache->base);
 
-  return (*this_cache);
+  return (struct mips_frame_cache *) (*this_cache);
 }
 
 static void
@@ -3538,7 +3736,7 @@ mips_stub_frame_cache (struct frame_info *this_frame, void **this_cache)
   int num_regs = gdbarch_num_regs (gdbarch);
 
   if ((*this_cache) != NULL)
-    return (*this_cache);
+    return (struct trad_frame_cache *) (*this_cache);
   this_trad_cache = trad_frame_cache_zalloc (this_frame);
   (*this_cache) = this_trad_cache;
 
@@ -3601,7 +3799,7 @@ mips_stub_frame_sniffer (const struct frame_unwind *self,
   msym = lookup_minimal_symbol_by_pc (pc);
   if (msym.minsym != NULL
       && MSYMBOL_LINKAGE_NAME (msym.minsym) != NULL
-      && strncmp (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) == 0)
+      && startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic."))
     return 1;
 
   return 0;
@@ -3650,9 +3848,6 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  if (is_compact_addr (addr))
-    addr = unmake_compact_addr (addr);
-
   if (mips_mask_address_p (tdep) && (((ULONGEST) addr) >> 32 == 0xffffffffUL))
     /* This hack is a work-around for existing boards using PMON, the
        simulator, and any other 64-bit targets that doesn't have true
@@ -3687,9 +3882,8 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
 #define SC_OPCODE 0x38
 #define SCD_OPCODE 0x3c
 
-static int
-mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
-                               struct address_space *aspace, CORE_ADDR pc)
+static std::vector<CORE_ADDR>
+mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   CORE_ADDR breaks[2] = {-1, -1};
   CORE_ADDR loc = pc;
@@ -3703,7 +3897,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
   insn = mips_fetch_instruction (gdbarch, ISA_MIPS, loc, NULL);
   /* Assume all atomic sequences start with a ll/lld instruction.  */
   if (itype_op (insn) != LL_OPCODE && itype_op (insn) != LLD_OPCODE)
-    return 0;
+    return {};
 
   /* Assume that no atomic sequence is longer than "atomic_sequence_length" 
      instructions.  */
@@ -3720,7 +3914,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
        {
        case 0: /* SPECIAL */
          if (rtype_funct (insn) >> 1 == 4) /* JR, JALR */
-           return 0; /* fallback to the standard single-step code.  */
+           return {}; /* fallback to the standard single-step code.  */
          break;
        case 1: /* REGIMM */
          is_branch = ((itype_rt (insn) & 0xc) == 0 /* B{LT,GE}Z* */
@@ -3729,7 +3923,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
          break;
        case 2: /* J */
        case 3: /* JAL */
-         return 0; /* fallback to the standard single-step code.  */
+         return {}; /* fallback to the standard single-step code.  */
        case 4: /* BEQ */
        case 5: /* BNE */
        case 6: /* BLEZ */
@@ -3755,8 +3949,8 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
        {
          branch_bp = loc + mips32_relative_offset (insn) + 4;
          if (last_breakpoint >= 1)
-           return 0; /* More than one branch found, fallback to the
-                        standard single-step code.  */
+           return {}; /* More than one branch found, fallback to the
+                         standard single-step code.  */
          breaks[1] = branch_bp;
          last_breakpoint++;
        }
@@ -3767,7 +3961,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
 
   /* Assume that the atomic sequence ends with a sc/scd instruction.  */
   if (itype_op (insn) != SC_OPCODE && itype_op (insn) != SCD_OPCODE)
-    return 0;
+    return {};
 
   loc += MIPS_INSN32_SIZE;
 
@@ -3779,16 +3973,17 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
   if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
     last_breakpoint = 0;
 
+  std::vector<CORE_ADDR> next_pcs;
+
   /* Effectively inserts the breakpoints.  */
   for (index = 0; index <= last_breakpoint; index++)
-    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+    next_pcs.push_back (breaks[index]);
 
-  return 1;
+  return next_pcs;
 }
 
-static int
+static std::vector<CORE_ADDR>
 micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
-                                    struct address_space *aspace,
                                     CORE_ADDR pc)
 {
   const int atomic_sequence_length = 16; /* Instruction sequence length.  */
@@ -3805,12 +4000,12 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
   /* Assume all atomic sequences start with a ll/lld instruction.  */
   insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
   if (micromips_op (insn) != 0x18)     /* POOL32C: bits 011000 */
-    return 0;
+    return {};
   loc += MIPS_INSN16_SIZE;
   insn <<= 16;
   insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
   if ((b12s4_op (insn) & 0xb) != 0x3)  /* LL, LLD: bits 011000 0x11 */
-    return 0;
+    return {};
   loc += MIPS_INSN16_SIZE;
 
   /* Assume all atomic sequences end with an sc/scd instruction.  Assume
@@ -3830,11 +4025,6 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
          its destination address.  */
       switch (mips_insn_size (ISA_MICROMIPS, insn))
        {
-       /* 48-bit instructions.  */
-       case 3 * MIPS_INSN16_SIZE: /* POOL48A: bits 011111 */
-         loc += 2 * MIPS_INSN16_SIZE;
-         break;
-
        /* 32-bit instructions.  */
        case 2 * MIPS_INSN16_SIZE:
          switch (micromips_op (insn))
@@ -3885,7 +4075,7 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
            case 0x35: /* J: bits 110101 */
            case 0x3d: /* JAL: bits 111101 */
            case 0x3c: /* JALX: bits 111100 */
-             return 0; /* Fall back to the standard single-step code. */
+             return {}; /* Fall back to the standard single-step code. */
 
            case 0x18: /* POOL32C: bits 011000 */
              if ((b12s4_op (insn) & 0xb) == 0xb)
@@ -3912,24 +4102,24 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
                  && b5s5_op (insn) != 0x18)
                                /* JRADDIUSP: bits 010001 11000 */
                break;
-             return 0; /* Fall back to the standard single-step code. */
+             return {}; /* Fall back to the standard single-step code. */
 
            case 0x33: /* B16: bits 110011 */
-             return 0; /* Fall back to the standard single-step code. */
+             return {}; /* Fall back to the standard single-step code. */
            }
          break;
        }
       if (is_branch)
        {
          if (last_breakpoint >= 1)
-           return 0; /* More than one branch found, fallback to the
-                        standard single-step code.  */
+           return {}; /* More than one branch found, fallback to the
+                         standard single-step code.  */
          breaks[1] = branch_bp;
          last_breakpoint++;
        }
     }
   if (!sc_found)
-    return 0;
+    return {};
 
   /* Insert a breakpoint right after the end of the atomic sequence.  */
   breaks[0] = loc;
@@ -3939,23 +4129,24 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
   if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
     last_breakpoint = 0;
 
+  std::vector<CORE_ADDR> next_pcs;
+
   /* Effectively inserts the breakpoints.  */
   for (index = 0; index <= last_breakpoint; index++)
-    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+    next_pcs.push_back (breaks[index]);
 
-  return 1;
+  return next_pcs;
 }
 
-static int
-deal_with_atomic_sequence (struct gdbarch *gdbarch,
-                          struct address_space *aspace, CORE_ADDR pc)
+static std::vector<CORE_ADDR>
+deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   if (mips_pc_is_mips (pc))
-    return mips_deal_with_atomic_sequence (gdbarch, aspace, pc);
+    return mips_deal_with_atomic_sequence (gdbarch, pc);
   else if (mips_pc_is_micromips (gdbarch, pc))
-    return micromips_deal_with_atomic_sequence (gdbarch, aspace, pc);
+    return micromips_deal_with_atomic_sequence (gdbarch, pc);
   else
-    return 0;
+    return {};
 }
 
 /* mips_software_single_step() is called just before we want to resume
@@ -3963,21 +4154,21 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch,
    or kernel single-step support (MIPS on GNU/Linux for example).  We find
    the target of the coming instruction and breakpoint it.  */
 
-int
-mips_software_single_step (struct frame_info *frame)
+std::vector<CORE_ADDR>
+mips_software_single_step (struct regcache *regcache)
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
-  struct address_space *aspace = get_frame_address_space (frame);
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   CORE_ADDR pc, next_pc;
 
-  pc = get_frame_pc (frame);
-  if (deal_with_atomic_sequence (gdbarch, aspace, pc))
-    return 1;
+  pc = regcache_read_pc (regcache);
+  std::vector<CORE_ADDR> next_pcs = deal_with_atomic_sequence (gdbarch, pc);
 
-  next_pc = mips_next_pc (frame, pc);
+  if (!next_pcs.empty ())
+    return next_pcs;
 
-  insert_single_step_breakpoint (gdbarch, aspace, next_pc);
-  return 1;
+  next_pc = mips_next_pc (regcache, pc);
+
+  return {next_pc};
 }
 
 /* Test whether the PC points to the return instruction at the
@@ -4288,7 +4479,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int stack_offset = 0;
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR func_addr = find_function_addr (function, NULL);
-  int regsize = mips_abi_regsize (gdbarch);
+  int abi_regsize = mips_abi_regsize (gdbarch);
 
   /* For shared libraries, "t9" needs to point at the function
      address.  */
@@ -4311,7 +4502,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
      than necessary for EABI, because the first few arguments are
      passed in registers, but that's OK.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += align_up (TYPE_LENGTH (value_type (args[argnum])), regsize);
+    len += align_up (TYPE_LENGTH (value_type (args[argnum])), abi_regsize);
   sp -= align_up (len, 16);
 
   if (mips_debug)
@@ -4340,7 +4531,9 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       const gdb_byte *val;
-      gdb_byte valbuf[MAX_REGISTER_SIZE];
+      /* This holds the address of structures that are passed by
+        reference.  */
+      gdb_byte ref_valbuf[MAX_MIPS_ABI_REGSIZE];
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
@@ -4351,32 +4544,17 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                            "mips_eabi_push_dummy_call: %d len=%d type=%d",
                            argnum + 1, len, (int) typecode);
 
-      /* Function pointer arguments to mips16 code need to be made into
-         mips16 pointers.  */
-      if (typecode == TYPE_CODE_PTR
-          && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
-       {
-         CORE_ADDR addr = extract_signed_integer (value_contents (arg),
-                                                  len, byte_order);
-         if (mips_pc_is_mips (addr))
-           val = value_contents (arg);
-         else
-           {
-             store_signed_integer (valbuf, len, byte_order, 
-                                   make_compact_addr (addr));
-             val = valbuf;
-           }
-       }
       /* The EABI passes structures that do not fit in a register by
          reference.  */
-      else if (len > regsize
+      if (len > abi_regsize
          && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
        {
-         store_unsigned_integer (valbuf, regsize, byte_order,
+         gdb_assert (abi_regsize <= ARRAY_SIZE (ref_valbuf));
+         store_unsigned_integer (ref_valbuf, abi_regsize, byte_order,
                                  value_address (arg));
          typecode = TYPE_CODE_PTR;
-         len = regsize;
-         val = valbuf;
+         len = abi_regsize;
+         val = ref_valbuf;
          if (mips_debug)
            fprintf_unfiltered (gdb_stdlog, " push");
        }
@@ -4388,7 +4566,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          up before the check to see if there are any FP registers
          left.  Non MIPS_EABI targets also pass the FP in the integer
          registers so also round up normal registers.  */
-      if (regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type))
+      if (abi_regsize < 8 && fp_register_arg_p (gdbarch, typecode, arg_type))
        {
          if ((float_argreg & 1))
            float_argreg++;
@@ -4454,12 +4632,12 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
          /* Copy the argument to general registers or the stack in
             register-sized pieces.  Large arguments are split between
             registers and stack.  */
-         /* Note: structs whose size is not a multiple of regsize
+         /* Note: structs whose size is not a multiple of abi_regsize
             are treated specially: Irix cc passes
             them in registers where gcc sometimes puts them on the
             stack.  For maximum compatibility, we will put them in
             both places.  */
-         int odd_sized_struct = (len > regsize && len % regsize != 0);
+         int odd_sized_struct = (len > abi_regsize && len % abi_regsize != 0);
 
          /* Note: Floating-point values that didn't fit into an FP
             register are only written to memory.  */
@@ -4467,7 +4645,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
            {
              /* Remember if the argument was written to the stack.  */
              int stack_used_p = 0;
-             int partial_len = (len < regsize ? len : regsize);
+             int partial_len = (len < abi_regsize ? len : abi_regsize);
 
              if (mips_debug)
                fprintf_unfiltered (gdb_stdlog, " -- partial=%d",
@@ -4485,15 +4663,15 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                  stack_used_p = 1;
                  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
                    {
-                     if (regsize == 8
+                     if (abi_regsize == 8
                          && (typecode == TYPE_CODE_INT
                              || typecode == TYPE_CODE_PTR
                              || typecode == TYPE_CODE_FLT) && len <= 4)
-                       longword_offset = regsize - len;
+                       longword_offset = abi_regsize - len;
                      else if ((typecode == TYPE_CODE_STRUCT
                                || typecode == TYPE_CODE_UNION)
-                              && TYPE_LENGTH (arg_type) < regsize)
-                       longword_offset = regsize - len;
+                              && TYPE_LENGTH (arg_type) < abi_regsize)
+                       longword_offset = abi_regsize - len;
                    }
 
                  if (mips_debug)
@@ -4534,7 +4712,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                  if (mips_debug)
                    fprintf_filtered (gdb_stdlog, " - reg=%d val=%s",
                                      argreg,
-                                     phex (regval, regsize));
+                                     phex (regval, abi_regsize));
                  regcache_cooked_write_signed (regcache, argreg, regval);
                  argreg++;
                }
@@ -4549,7 +4727,7 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                 only needs to be adjusted when it has been used.  */
 
              if (stack_used_p)
-               stack_offset += align_up (partial_len, regsize);
+               stack_offset += align_up (partial_len, abi_regsize);
            }
        }
       if (mips_debug)
@@ -5327,8 +5505,6 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
            }
          while (len > 0)
            {
-             /* Remember if the argument was written to the stack.  */
-             int stack_used_p = 0;
              int partial_len = (len < MIPS32_REGSIZE ? len : MIPS32_REGSIZE);
 
              if (mips_debug)
@@ -5343,7 +5519,6 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                     promoted to int before being stored?  */
                  int longword_offset = 0;
                  CORE_ADDR addr;
-                 stack_used_p = 1;
 
                  if (mips_debug)
                    {
@@ -5590,7 +5765,6 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct value *function,
       /* A struct that contains one or two floats.  Each value is part
          in the least significant part of their floating point
          register..  */
-      gdb_byte reg[MAX_REGISTER_SIZE];
       int regnum;
       int field;
       for (field = 0, regnum = mips_regnum (gdbarch)->fp0;
@@ -5734,7 +5908,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       const gdb_byte *val;
-      gdb_byte valbuf[MAX_REGISTER_SIZE];
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
@@ -5747,21 +5920,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
       val = value_contents (arg);
 
-      /* Function pointer arguments to mips16 code need to be made into
-         mips16 pointers.  */
-      if (typecode == TYPE_CODE_PTR
-          && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
-       {
-         CORE_ADDR addr = extract_signed_integer (value_contents (arg),
-                                                  len, byte_order);
-         if (!mips_pc_is_mips (addr))
-           {
-             store_signed_integer (valbuf, len, byte_order, 
-                                   make_compact_addr (addr));
-             val = valbuf;
-           }
-       }
-
       /* Floating point arguments passed in registers have to be
          treated specially.  On 32-bit architectures, doubles are
          passed in register pairs; the even FP register gets the
@@ -5801,8 +5959,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                                  && len % MIPS64_REGSIZE != 0);
          while (len > 0)
            {
-             /* Remember if the argument was written to the stack.  */
-             int stack_used_p = 0;
              int partial_len = (len < MIPS64_REGSIZE ? len : MIPS64_REGSIZE);
 
              if (mips_debug)
@@ -5817,7 +5973,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                     promoted to int before being stored?  */
                  int longword_offset = 0;
                  CORE_ADDR addr;
-                 stack_used_p = 1;
                  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
                    {
                      if ((typecode == TYPE_CODE_INT
@@ -6029,7 +6184,7 @@ mips_read_fp_register_single (struct frame_info *frame, int regno,
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   int raw_size = register_size (gdbarch, regno);
-  gdb_byte *raw_buffer = alloca (raw_size);
+  gdb_byte *raw_buffer = (gdb_byte *) alloca (raw_size);
 
   if (!deprecated_frame_register_read (frame, regno, raw_buffer))
     error (_("can't read register %d (%s)"),
@@ -6105,8 +6260,9 @@ mips_print_fp_register (struct ui_file *file, struct frame_info *frame,
   double doub, flt1;   /* Doubles extracted from raw hex data.  */
   int inv1, inv2;
 
-  raw_buffer = alloca (2 * register_size (gdbarch,
-                                         mips_regnum (gdbarch)->fp0));
+  raw_buffer
+    = ((gdb_byte *)
+       alloca (2 * register_size (gdbarch, mips_regnum (gdbarch)->fp0)));
 
   fprintf_filtered (file, "%s:", gdbarch_register_name (gdbarch, regnum));
   fprintf_filtered (file, "%*s",
@@ -6194,12 +6350,6 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
     }
 
   val = get_frame_register_value (frame, regnum);
-  if (value_optimized_out (val))
-    {
-      fprintf_filtered (file, "%s: [Invalid]",
-                       gdbarch_register_name (gdbarch, regnum));
-      return;
-    }
 
   fputs_filtered (gdbarch_register_name (gdbarch, regnum), file);
 
@@ -6214,12 +6364,99 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
 
   get_formatted_print_options (&opts, 'x');
   val_print_scalar_formatted (value_type (val),
-                             value_contents_for_printing (val),
                              value_embedded_offset (val),
                              val,
                              &opts, 0, file);
 }
 
+/* Print IEEE exception condition bits in FLAGS.  */
+
+static void
+print_fpu_flags (struct ui_file *file, int flags)
+{
+  if (flags & (1 << 0))
+    fputs_filtered (" inexact", file);
+  if (flags & (1 << 1))
+    fputs_filtered (" uflow", file);
+  if (flags & (1 << 2))
+    fputs_filtered (" oflow", file);
+  if (flags & (1 << 3))
+    fputs_filtered (" div0", file);
+  if (flags & (1 << 4))
+    fputs_filtered (" inval", file);
+  if (flags & (1 << 5))
+    fputs_filtered (" unimp", file);
+  fputc_filtered ('\n', file);
+}
+
+/* Print interesting information about the floating point processor
+   (if present) or emulator.  */
+
+static void
+mips_print_float_info (struct gdbarch *gdbarch, struct ui_file *file,
+                     struct frame_info *frame, const char *args)
+{
+  int fcsr = mips_regnum (gdbarch)->fp_control_status;
+  enum mips_fpu_type type = MIPS_FPU_TYPE (gdbarch);
+  ULONGEST fcs = 0;
+  int i;
+
+  if (fcsr == -1 || !read_frame_register_unsigned (frame, fcsr, &fcs))
+    type = MIPS_FPU_NONE;
+
+  fprintf_filtered (file, "fpu type: %s\n",
+                   type == MIPS_FPU_DOUBLE ? "double-precision"
+                   : type == MIPS_FPU_SINGLE ? "single-precision"
+                   : "none / unused");
+
+  if (type == MIPS_FPU_NONE)
+    return;
+
+  fprintf_filtered (file, "reg size: %d bits\n",
+                   register_size (gdbarch, mips_regnum (gdbarch)->fp0) * 8);
+
+  fputs_filtered ("cond    :", file);
+  if (fcs & (1 << 23))
+    fputs_filtered (" 0", file);
+  for (i = 1; i <= 7; i++)
+    if (fcs & (1 << (24 + i)))
+      fprintf_filtered (file, " %d", i);
+  fputc_filtered ('\n', file);
+
+  fputs_filtered ("cause   :", file);
+  print_fpu_flags (file, (fcs >> 12) & 0x3f);
+  fputs ("mask    :", stdout);
+  print_fpu_flags (file, (fcs >> 7) & 0x1f);
+  fputs ("flags   :", stdout);
+  print_fpu_flags (file, (fcs >> 2) & 0x1f);
+
+  fputs_filtered ("rounding: ", file);
+  switch (fcs & 3)
+    {
+    case 0: fputs_filtered ("nearest\n", file); break;
+    case 1: fputs_filtered ("zero\n", file); break;
+    case 2: fputs_filtered ("+inf\n", file); break;
+    case 3: fputs_filtered ("-inf\n", file); break;
+    }
+
+  fputs_filtered ("flush   :", file);
+  if (fcs & (1 << 21))
+    fputs_filtered (" nearest", file);
+  if (fcs & (1 << 22))
+    fputs_filtered (" override", file);
+  if (fcs & (1 << 24))
+    fputs_filtered (" zero", file);
+  if ((fcs & (0xb << 21)) == 0)
+    fputs_filtered (" no", file);
+  fputc_filtered ('\n', file);
+
+  fprintf_filtered (file, "nan2008 : %s\n", fcs & (1 << 18) ? "yes" : "no");
+  fprintf_filtered (file, "abs2008 : %s\n", fcs & (1 << 19) ? "yes" : "no");
+  fputc_filtered ('\n', file);
+
+  default_print_float_info (gdbarch, file, frame, args);
+}
+
 /* Replacement for generic do_registers_info.
    Print regs in pretty columns.  */
 
@@ -6242,7 +6479,8 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   /* Do values for GP (int) regs.  */
-  gdb_byte raw_buffer[MAX_REGISTER_SIZE];
+  const gdb_byte *raw_buffer;
+  struct value *value;
   int ncols = (mips_abi_regsize (gdbarch) == 8 ? 4 : 8);    /* display cols
                                                               per row.  */
   int col, byte;
@@ -6301,14 +6539,23 @@ print_gp_register_row (struct ui_file *file, struct frame_info *frame,
        break;                  /* End row: large register.  */
 
       /* OK: get the data in raw format.  */
-      if (!deprecated_frame_register_read (frame, regnum, raw_buffer))
-       error (_("can't read register %d (%s)"),
-              regnum, gdbarch_register_name (gdbarch, regnum));
+      value = get_frame_register_value (frame, regnum);
+      if (value_optimized_out (value)
+       || !value_entirely_available (value))
+       {
+         fprintf_filtered (file, "%*s ",
+                           (int) mips_abi_regsize (gdbarch) * 2,
+                           (mips_abi_regsize (gdbarch) == 4 ? "<unavl>"
+                            : "<unavailable>"));
+         col++;
+         continue;
+       }
+      raw_buffer = value_contents_all (value);
       /* pad small registers */
       for (byte = 0;
           byte < (mips_abi_regsize (gdbarch)
                   - register_size (gdbarch, regnum)); byte++)
-       printf_filtered ("  ");
+       fprintf_filtered (file, "  ");
       /* Now print the register value in hex, endian order.  */
       if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
        for (byte =
@@ -6376,11 +6623,11 @@ mips_single_step_through_delay (struct gdbarch *gdbarch,
   int size;
 
   if ((mips_pc_is_mips (pc)
-       && !mips32_instruction_has_delay_slot (gdbarch, pc))
+       && !mips32_insn_at_pc_has_delay_slot (gdbarch, pc))
       || (mips_pc_is_micromips (gdbarch, pc)
-         && !micromips_instruction_has_delay_slot (gdbarch, pc, 0))
+         && !micromips_insn_at_pc_has_delay_slot (gdbarch, pc, 0))
       || (mips_pc_is_mips16 (gdbarch, pc)
-         && !mips16_instruction_has_delay_slot (gdbarch, pc, 0)))
+         && !mips16_insn_at_pc_has_delay_slot (gdbarch, pc, 0)))
     return 0;
 
   isa = mips_pc_isa (gdbarch, pc);
@@ -6414,7 +6661,7 @@ mips_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
       CORE_ADDR post_prologue_pc
        = skip_prologue_using_sal (gdbarch, func_addr);
       if (post_prologue_pc != 0)
-       return max (pc, post_prologue_pc);
+       return std::max (pc, post_prologue_pc);
     }
 
   /* Can't determine prologue from the symbol table, need to examine
@@ -6435,10 +6682,11 @@ mips_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
     return mips32_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
 }
 
-/* Check whether the PC is in a function epilogue (32-bit version).
-   This is a helper function for mips_in_function_epilogue_p.  */
+/* Implement the stack_frame_destroyed_p gdbarch method (32-bit version).
+   This is a helper function for mips_stack_frame_destroyed_p.  */
+
 static int
-mips32_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+mips32_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   CORE_ADDR func_addr = 0, func_end = 0;
 
@@ -6473,11 +6721,11 @@ mips32_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   return 0;
 }
 
-/* Check whether the PC is in a function epilogue (microMIPS version).
-   This is a helper function for mips_in_function_epilogue_p.  */
+/* Implement the stack_frame_destroyed_p gdbarch method (microMIPS version).
+   This is a helper function for mips_stack_frame_destroyed_p.  */
 
 static int
-micromips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+micromips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   CORE_ADDR func_addr = 0;
   CORE_ADDR func_end = 0;
@@ -6506,11 +6754,6 @@ micromips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
       loc += MIPS_INSN16_SIZE;
       switch (mips_insn_size (ISA_MICROMIPS, insn))
        {
-       /* 48-bit instructions.  */
-       case 3 * MIPS_INSN16_SIZE:
-         /* No epilogue instructions in this category.  */
-         return 0;
-
        /* 32-bit instructions.  */
        case 2 * MIPS_INSN16_SIZE:
          insn <<= 16;
@@ -6574,10 +6817,11 @@ micromips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   return 1;
 }
 
-/* Check whether the PC is in a function epilogue (16-bit version).
-   This is a helper function for mips_in_function_epilogue_p.  */
+/* Implement the stack_frame_destroyed_p gdbarch method (16-bit version).
+   This is a helper function for mips_stack_frame_destroyed_p.  */
+
 static int
-mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+mips16_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   CORE_ADDR func_addr = 0, func_end = 0;
 
@@ -6614,17 +6858,20 @@ mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
   return 0;
 }
 
-/* The epilogue is defined here as the area at the end of a function,
+/* Implement the stack_frame_destroyed_p gdbarch method.
+
+   The epilogue is defined here as the area at the end of a function,
    after an instruction which destroys the function's stack frame.  */
+
 static int
-mips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+mips_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   if (mips_pc_is_mips16 (gdbarch, pc))
-    return mips16_in_function_epilogue_p (gdbarch, pc);
+    return mips16_stack_frame_destroyed_p (gdbarch, pc);
   else if (mips_pc_is_micromips (gdbarch, pc))
-    return micromips_in_function_epilogue_p (gdbarch, pc);
+    return micromips_stack_frame_destroyed_p (gdbarch, pc);
   else
-    return mips32_in_function_epilogue_p (gdbarch, pc);
+    return mips32_stack_frame_destroyed_p (gdbarch, pc);
 }
 
 /* Root of all "set mips "/"show mips " commands.  This will eventually be
@@ -6647,9 +6894,9 @@ set_mips_command (char *args, int from_tty)
 /* Commands to show/set the MIPS FPU type.  */
 
 static void
-show_mipsfpu_command (char *args, int from_tty)
+show_mipsfpu_command (const char *args, int from_tty)
 {
-  char *fpu;
+  const char *fpu;
 
   if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_mips)
     {
@@ -6692,7 +6939,7 @@ set_mipsfpu_command (char *args, int from_tty)
 }
 
 static void
-set_mipsfpu_single_command (char *args, int from_tty)
+set_mipsfpu_single_command (const char *args, int from_tty)
 {
   struct gdbarch_info info;
   gdbarch_info_init (&info);
@@ -6706,7 +6953,7 @@ set_mipsfpu_single_command (char *args, int from_tty)
 }
 
 static void
-set_mipsfpu_double_command (char *args, int from_tty)
+set_mipsfpu_double_command (const char *args, int from_tty)
 {
   struct gdbarch_info info;
   gdbarch_info_init (&info);
@@ -6720,7 +6967,7 @@ set_mipsfpu_double_command (char *args, int from_tty)
 }
 
 static void
-set_mipsfpu_none_command (char *args, int from_tty)
+set_mipsfpu_none_command (const char *args, int from_tty)
 {
   struct gdbarch_info info;
   gdbarch_info_init (&info);
@@ -6734,30 +6981,11 @@ set_mipsfpu_none_command (char *args, int from_tty)
 }
 
 static void
-set_mipsfpu_auto_command (char *args, int from_tty)
+set_mipsfpu_auto_command (const char *args, int from_tty)
 {
   mips_fpu_type_auto = 1;
 }
 
-/* Attempt to identify the particular processor model by reading the
-   processor id.  NOTE: cagney/2003-11-15: Firstly it isn't clear that
-   the relevant processor still exists (it dates back to '94) and
-   secondly this is not the way to do this.  The processor type should
-   be set by forcing an architecture change.  */
-
-void
-deprecated_mips_set_processor_regs_hack (void)
-{
-  struct regcache *regcache = get_current_regcache ();
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  ULONGEST prid;
-
-  regcache_cooked_read_unsigned (regcache, MIPS_PRID_REGNUM, &prid);
-  if ((prid & ~0xf) == 0x700)
-    tdep->mips_processor_reg_names = mips_r3041_reg_names;
-}
-
 /* Just like reinit_frame_cache, but with the right arguments to be
    callable as an sfunc.  */
 
@@ -6771,7 +6999,9 @@ reinit_frame_cache_sfunc (char *args, int from_tty,
 static int
 gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info)
 {
-  struct gdbarch *gdbarch = info->application_data;
+  gdb_disassembler *di
+    = static_cast<gdb_disassembler *>(info->application_data);
+  struct gdbarch *gdbarch = di->arch ();
 
   /* FIXME: cagney/2003-06-26: Is this even necessary?  The
      disassembler needs to be able to locally determine the ISA, and
@@ -6795,11 +7025,7 @@ gdb_print_insn_mips (bfd_vma memaddr, struct disassemble_info *info)
        register naming conventions specified by the user.  */
     info->disassembler_options = "gpr-names=32";
 
-  /* Call the appropriate disassembler based on the target endian-ness.  */
-  if (info->endian == BFD_ENDIAN_BIG)
-    return print_insn_big_mips (memaddr, info);
-  else
-    return print_insn_little_mips (memaddr, info);
+  return default_print_insn (memaddr, info);
 }
 
 static int
@@ -6824,169 +7050,104 @@ gdb_print_insn_mips_n64 (bfd_vma memaddr, struct disassemble_info *info)
   return gdb_print_insn_mips (memaddr, info);
 }
 
-/* This function implements gdbarch_breakpoint_from_pc.  It uses the
-   program counter value to determine whether a 16- or 32-bit breakpoint
-   should be used.  It returns a pointer to a string of bytes that encode a
-   breakpoint instruction, stores the length of the string to *lenptr, and
-   adjusts pc (if necessary) to point to the actual memory location where
-   the breakpoint should be inserted.  */
+/* Implement the breakpoint_kind_from_pc gdbarch method.  */
 
-static const gdb_byte *
-mips_breakpoint_from_pc (struct gdbarch *gdbarch,
-                        CORE_ADDR *pcptr, int *lenptr)
+static int
+mips_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
 {
   CORE_ADDR pc = *pcptr;
 
-  if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
+  if (mips_pc_is_mips16 (gdbarch, pc))
     {
-      if (mips_pc_is_mips16 (gdbarch, pc))
-       {
-         static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
-         *pcptr = unmake_compact_addr (pc);
-         *lenptr = sizeof (mips16_big_breakpoint);
-         return mips16_big_breakpoint;
-       }
-      else if (mips_pc_is_micromips (gdbarch, pc))
-       {
-         static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 };
-         static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 };
-         ULONGEST insn;
-         int status;
-         int size;
-
-         insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
-         size = status ? 2
-                       : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4;
-         *pcptr = unmake_compact_addr (pc);
-         *lenptr = size;
-         return (size == 2) ? micromips16_big_breakpoint
-                            : micromips32_big_breakpoint;
-       }
-      else
-       {
-         /* The IDT board uses an unusual breakpoint value, and
-            sometimes gets confused when it sees the usual MIPS
-            breakpoint instruction.  */
-         static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd };
-         static gdb_byte pmon_big_breakpoint[] = { 0, 0, 0, 0xd };
-         static gdb_byte idt_big_breakpoint[] = { 0, 0, 0x0a, 0xd };
-         /* Likewise, IRIX appears to expect a different breakpoint,
-            although this is not apparent until you try to use pthreads.  */
-         static gdb_byte irix_big_breakpoint[] = { 0, 0, 0, 0xd };
-
-         *lenptr = sizeof (big_breakpoint);
-
-         if (strcmp (target_shortname, "mips") == 0)
-           return idt_big_breakpoint;
-         else if (strcmp (target_shortname, "ddb") == 0
-                  || strcmp (target_shortname, "pmon") == 0
-                  || strcmp (target_shortname, "lsi") == 0)
-           return pmon_big_breakpoint;
-         else if (gdbarch_osabi (gdbarch) == GDB_OSABI_IRIX)
-           return irix_big_breakpoint;
-         else
-           return big_breakpoint;
-       }
+      *pcptr = unmake_compact_addr (pc);
+      return MIPS_BP_KIND_MIPS16;
     }
-  else
+  else if (mips_pc_is_micromips (gdbarch, pc))
     {
-      if (mips_pc_is_mips16 (gdbarch, pc))
-       {
-         static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
-         *pcptr = unmake_compact_addr (pc);
-         *lenptr = sizeof (mips16_little_breakpoint);
-         return mips16_little_breakpoint;
-       }
-      else if (mips_pc_is_micromips (gdbarch, pc))
-       {
-         static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 };
-         static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 };
-         ULONGEST insn;
-         int status;
-         int size;
-
-         insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
-         size = status ? 2
-                       : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4;
-         *pcptr = unmake_compact_addr (pc);
-         *lenptr = size;
-         return (size == 2) ? micromips16_little_breakpoint
-                            : micromips32_little_breakpoint;
-       }
+      ULONGEST insn;
+      int status;
+
+      *pcptr = unmake_compact_addr (pc);
+      insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
+      if (status || (mips_insn_size (ISA_MICROMIPS, insn) == 2))
+       return MIPS_BP_KIND_MICROMIPS16;
       else
-       {
-         static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };
-         static gdb_byte pmon_little_breakpoint[] = { 0xd, 0, 0, 0 };
-         static gdb_byte idt_little_breakpoint[] = { 0xd, 0x0a, 0, 0 };
-
-         *lenptr = sizeof (little_breakpoint);
-
-         if (strcmp (target_shortname, "mips") == 0)
-           return idt_little_breakpoint;
-         else if (strcmp (target_shortname, "ddb") == 0
-                  || strcmp (target_shortname, "pmon") == 0
-                  || strcmp (target_shortname, "lsi") == 0)
-           return pmon_little_breakpoint;
-         else
-           return little_breakpoint;
-       }
+       return MIPS_BP_KIND_MICROMIPS32;
     }
+  else
+    return MIPS_BP_KIND_MIPS32;
 }
 
-/* Determine the remote breakpoint kind suitable for the PC.  The following
-   kinds are used:
+/* Implement the sw_breakpoint_from_kind gdbarch method.  */
 
-   * 2 -- 16-bit MIPS16 mode breakpoint,
+static const gdb_byte *
+mips_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
 
-   * 3 -- 16-bit microMIPS mode breakpoint,
+  switch (kind)
+    {
+    case MIPS_BP_KIND_MIPS16:
+      {
+       static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
+       static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
 
-   * 4 -- 32-bit standard MIPS mode breakpoint,
+       *size = 2;
+       if (byte_order_for_code == BFD_ENDIAN_BIG)
+         return mips16_big_breakpoint;
+       else
+         return mips16_little_breakpoint;
+      }
+    case MIPS_BP_KIND_MICROMIPS16:
+      {
+       static gdb_byte micromips16_big_breakpoint[] = { 0x46, 0x85 };
+       static gdb_byte micromips16_little_breakpoint[] = { 0x85, 0x46 };
 
-   * 5 -- 32-bit microMIPS mode breakpoint.  */
+       *size = 2;
 
-static void
-mips_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
-                               int *kindptr)
-{
-  CORE_ADDR pc = *pcptr;
+       if (byte_order_for_code == BFD_ENDIAN_BIG)
+         return micromips16_big_breakpoint;
+       else
+         return micromips16_little_breakpoint;
+      }
+    case MIPS_BP_KIND_MICROMIPS32:
+      {
+       static gdb_byte micromips32_big_breakpoint[] = { 0, 0x5, 0, 0x7 };
+       static gdb_byte micromips32_little_breakpoint[] = { 0x5, 0, 0x7, 0 };
 
-  if (mips_pc_is_mips16 (gdbarch, pc))
-    {
-      *pcptr = unmake_compact_addr (pc);
-      *kindptr = 2;
-    }
-  else if (mips_pc_is_micromips (gdbarch, pc))
-    {
-      ULONGEST insn;
-      int status;
-      int size;
+       *size = 4;
+       if (byte_order_for_code == BFD_ENDIAN_BIG)
+         return micromips32_big_breakpoint;
+       else
+         return micromips32_little_breakpoint;
+      }
+    case MIPS_BP_KIND_MIPS32:
+      {
+       static gdb_byte big_breakpoint[] = { 0, 0x5, 0, 0xd };
+       static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };
 
-      insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, &status);
-      size = status ? 2 : mips_insn_size (ISA_MICROMIPS, insn) == 2 ? 2 : 4;
-      *pcptr = unmake_compact_addr (pc);
-      *kindptr = size | 1;
-    }
-  else
-    *kindptr = 4;
+       *size = 4;
+       if (byte_order_for_code == BFD_ENDIAN_BIG)
+         return big_breakpoint;
+       else
+         return little_breakpoint;
+      }
+    default:
+      gdb_assert_not_reached ("unexpected mips breakpoint kind");
+    };
 }
 
-/* Return non-zero if the ADDR instruction has a branch delay slot
-   (i.e. it is a jump or branch instruction).  This function is based
-   on mips32_next_pc.  */
+/* Return non-zero if the standard MIPS instruction INST has a branch
+   delay slot (i.e. it is a jump or branch instruction).  This function
+   is based on mips32_next_pc.  */
 
 static int
-mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
+mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, ULONGEST inst)
 {
-  unsigned long inst;
-  int status;
   int op;
   int rs;
   int rt;
 
-  inst = mips_fetch_instruction (gdbarch, ISA_MIPS, addr, &status);
-  if (status)
-    return 0;
-
   op = itype_op (inst);
   if ((inst & 0xe0000000) != 0)
     {
@@ -7026,93 +7187,141 @@ mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
       }
 }
 
-/* Return non-zero if the ADDR instruction, which must be a 32-bit
-   instruction if MUSTBE32 is set or can be any instruction otherwise,
-   has a branch delay slot (i.e. it is a non-compact jump instruction).  */
+/* Return non-zero if a standard MIPS instruction at ADDR has a branch
+   delay slot (i.e. it is a jump or branch instruction).  */
 
 static int
-micromips_instruction_has_delay_slot (struct gdbarch *gdbarch,
-                                     CORE_ADDR addr, int mustbe32)
+mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   ULONGEST insn;
   int status;
 
-  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
+  insn = mips_fetch_instruction (gdbarch, ISA_MIPS, addr, &status);
   if (status)
     return 0;
 
-  if (!mustbe32)               /* 16-bit instructions.  */
-    return (micromips_op (insn) == 0x11
-                               /* POOL16C: bits 010001 */
-           && (b5s5_op (insn) == 0xc
+  return mips32_instruction_has_delay_slot (gdbarch, insn);
+}
+
+/* Return non-zero if the microMIPS instruction INSN, comprising the
+   16-bit major opcode word in the high 16 bits and any second word
+   in the low 16 bits, has a branch delay slot (i.e. it is a non-compact
+   jump or branch instruction).  The instruction must be 32-bit if
+   MUSTBE32 is set or can be any instruction otherwise.  */
+
+static int
+micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32)
+{
+  ULONGEST major = insn >> 16;
+
+  switch (micromips_op (major))
+    {
+    /* 16-bit instructions.  */
+    case 0x33:                 /* B16: bits 110011 */
+    case 0x2b:                 /* BNEZ16: bits 101011 */
+    case 0x23:                 /* BEQZ16: bits 100011 */
+      return !mustbe32;
+    case 0x11:                 /* POOL16C: bits 010001 */
+      return (!mustbe32
+             && ((b5s5_op (major) == 0xc
                                /* JR16: bits 010001 01100 */
-               || (b5s5_op (insn) & 0x1e) == 0xe))
+                 || (b5s5_op (major) & 0x1e) == 0xe)));
                                /* JALR16, JALRS16: bits 010001 0111x */
-          || (micromips_op (insn) & 0x37) == 0x23
-                               /* BEQZ16, BNEZ16: bits 10x011 */
-          || micromips_op (insn) == 0x33;
-                               /* B16: bits 110011 */
-
-                               /* 32-bit instructions.  */
-  if (micromips_op (insn) == 0x0)
-                               /* POOL32A: bits 000000 */
-    {
-      insn <<= 16;
-      insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
-      if (status)
-       return 0;
-      return b0s6_op (insn) == 0x3c
-                               /* POOL32Axf: bits 000000 ... 111100 */
-            && (b6s10_ext (insn) & 0x2bf) == 0x3c;
-                               /* JALR, JALR.HB: 000000 000x111100 111100 */
-                               /* JALRS, JALRS.HB: 000000 010x111100 111100 */
-    }
-
-  return (micromips_op (insn) == 0x10
-                               /* POOL32I: bits 010000 */
-         && ((b5s5_op (insn) & 0x1c) == 0x0
+    /* 32-bit instructions.  */
+    case 0x3d:                 /* JAL: bits 111101 */
+    case 0x3c:                 /* JALX: bits 111100 */
+    case 0x35:                 /* J: bits 110101 */
+    case 0x2d:                 /* BNE: bits 101101 */
+    case 0x25:                 /* BEQ: bits 100101 */
+    case 0x1d:                 /* JALS: bits 011101 */
+      return 1;
+    case 0x10:                 /* POOL32I: bits 010000 */
+      return ((b5s5_op (major) & 0x1c) == 0x0
                                /* BLTZ, BLTZAL, BGEZ, BGEZAL: 010000 000xx */
-             || (b5s5_op (insn) & 0x1d) == 0x4
+             || (b5s5_op (major) & 0x1d) == 0x4
                                /* BLEZ, BGTZ: bits 010000 001x0 */
-             || (b5s5_op (insn) & 0x1d) == 0x11
+             || (b5s5_op (major) & 0x1d) == 0x11
                                /* BLTZALS, BGEZALS: bits 010000 100x1 */
-             || ((b5s5_op (insn) & 0x1e) == 0x14
-                 && (insn & 0x3) == 0x0)
+             || ((b5s5_op (major) & 0x1e) == 0x14
+                 && (major & 0x3) == 0x0)
                                /* BC2F, BC2T: bits 010000 1010x xxx00 */
-             || (b5s5_op (insn) & 0x1e) == 0x1a
+             || (b5s5_op (major) & 0x1e) == 0x1a
                                /* BPOSGE64, BPOSGE32: bits 010000 1101x */
-             || ((b5s5_op (insn) & 0x1e) == 0x1c
-                 && (insn & 0x3) == 0x0)
+             || ((b5s5_op (major) & 0x1e) == 0x1c
+                 && (major & 0x3) == 0x0)
                                /* BC1F, BC1T: bits 010000 1110x xxx00 */
-             || ((b5s5_op (insn) & 0x1c) == 0x1c
-                 && (insn & 0x3) == 0x1)))
+             || ((b5s5_op (major) & 0x1c) == 0x1c
+                 && (major & 0x3) == 0x1));
                                /* BC1ANY*: bits 010000 111xx xxx01 */
-        || (micromips_op (insn) & 0x1f) == 0x1d
-                               /* JALS, JAL: bits x11101 */
-        || (micromips_op (insn) & 0x37) == 0x25
-                               /* BEQ, BNE: bits 10x101 */
-        || micromips_op (insn) == 0x35
-                               /* J: bits 110101 */
-        || micromips_op (insn) == 0x3c;
-                               /* JALX: bits 111100 */
+    case 0x0:                  /* POOL32A: bits 000000 */
+      return (b0s6_op (insn) == 0x3c
+                               /* POOL32Axf: bits 000000 ... 111100 */
+             && (b6s10_ext (insn) & 0x2bf) == 0x3c);
+                               /* JALR, JALR.HB: 000000 000x111100 111100 */
+                               /* JALRS, JALRS.HB: 000000 010x111100 111100 */
+    default:
+      return 0;
+    }
 }
 
+/* Return non-zero if a microMIPS instruction at ADDR has a branch delay
+   slot (i.e. it is a non-compact jump instruction).  The instruction
+   must be 32-bit if MUSTBE32 is set or can be any instruction otherwise.  */
+
 static int
-mips16_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr,
-                                  int mustbe32)
+micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                    CORE_ADDR addr, int mustbe32)
 {
-  unsigned short inst;
+  ULONGEST insn;
   int status;
+  int size;
 
-  inst = mips_fetch_instruction (gdbarch, ISA_MIPS16, addr, &status);
+  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
   if (status)
     return 0;
+  size = mips_insn_size (ISA_MICROMIPS, insn);
+  insn <<= 16;
+  if (size == 2 * MIPS_INSN16_SIZE)
+    {
+      insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
+      if (status)
+       return 0;
+    }
+
+  return micromips_instruction_has_delay_slot (insn, mustbe32);
+}
 
-  if (!mustbe32)
-    return (inst & 0xf89f) == 0xe800;  /* JR/JALR (16-bit instruction)  */
+/* Return non-zero if the MIPS16 instruction INST, which must be
+   a 32-bit instruction if MUSTBE32 is set or can be any instruction
+   otherwise, has a branch delay slot (i.e. it is a non-compact jump
+   instruction).  This function is based on mips16_next_pc.  */
+
+static int
+mips16_instruction_has_delay_slot (unsigned short inst, int mustbe32)
+{
+  if ((inst & 0xf89f) == 0xe800)       /* JR/JALR (16-bit instruction)  */
+    return !mustbe32;
   return (inst & 0xf800) == 0x1800;    /* JAL/JALX (32-bit instruction)  */
 }
 
+/* Return non-zero if a MIPS16 instruction at ADDR has a branch delay
+   slot (i.e. it is a non-compact jump instruction).  The instruction
+   must be 32-bit if MUSTBE32 is set or can be any instruction otherwise.  */
+
+static int
+mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                 CORE_ADDR addr, int mustbe32)
+{
+  unsigned short insn;
+  int status;
+
+  insn = mips_fetch_instruction (gdbarch, ISA_MIPS16, addr, &status);
+  if (status)
+    return 0;
+
+  return mips16_instruction_has_delay_slot (insn, mustbe32);
+}
+
 /* Calculate the starting address of the MIPS memory segment BPADDR is in.
    This assumes KSSEG exists.  */
 
@@ -7204,12 +7413,12 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
       /* If the previous instruction has a branch delay slot, we have
          to move the breakpoint to the branch instruction. */
       prev_addr = bpaddr - 4;
-      if (mips32_instruction_has_delay_slot (gdbarch, prev_addr))
+      if (mips32_insn_at_pc_has_delay_slot (gdbarch, prev_addr))
        bpaddr = prev_addr;
     }
   else
     {
-      int (*instruction_has_delay_slot) (struct gdbarch *, CORE_ADDR, int);
+      int (*insn_at_pc_has_delay_slot) (struct gdbarch *, CORE_ADDR, int);
       CORE_ADDR addr, jmpaddr;
       int i;
 
@@ -7223,9 +7432,9 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
          2 bytes, so the idea is the same.
          FIXME: We have to assume that bpaddr is not the second half
          of an extended instruction.  */
-      instruction_has_delay_slot = (mips_pc_is_micromips (gdbarch, bpaddr)
-                                    ? micromips_instruction_has_delay_slot
-                                    : mips16_instruction_has_delay_slot);
+      insn_at_pc_has_delay_slot = (mips_pc_is_micromips (gdbarch, bpaddr)
+                                  ? micromips_insn_at_pc_has_delay_slot
+                                  : mips16_insn_at_pc_has_delay_slot);
 
       jmpaddr = 0;
       addr = bpaddr;
@@ -7234,12 +7443,12 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
          if (unmake_compact_addr (addr) == boundary)
            break;
          addr -= MIPS_INSN16_SIZE;
-         if (i == 1 && instruction_has_delay_slot (gdbarch, addr, 0))
+         if (i == 1 && insn_at_pc_has_delay_slot (gdbarch, addr, 0))
            /* Looks like a JR/JALR at [target-1], but it could be
               the second word of a previous JAL/JALX, so record it
               and check back one more.  */
            jmpaddr = addr;
-         else if (i > 1 && instruction_has_delay_slot (gdbarch, addr, 1))
+         else if (i > 1 && insn_at_pc_has_delay_slot (gdbarch, addr, 1))
            {
              if (i == 2)
                /* Looks like a JAL/JALX at [target-2], but it could also
@@ -7547,8 +7756,8 @@ mips_skip_mips16_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 
   /* If the PC is in __call_stub_* or __fn_stub*, this is one of the
      compiler-generated call or call/return stubs.  */
-  if (strncmp (name, mips_str_fn_stub, strlen (mips_str_fn_stub)) == 0
-      || strncmp (name, mips_str_call_stub, strlen (mips_str_call_stub)) == 0)
+  if (startswith (name, mips_str_fn_stub)
+      || startswith (name, mips_str_call_stub))
     {
       if (pc == start_addr)
        /* This is the 'call' part of a call stub.  Call this helper
@@ -7635,7 +7844,7 @@ mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
   if (msym.minsym == NULL
       || BMSYMBOL_VALUE_ADDRESS (msym) != pc
       || MSYMBOL_LINKAGE_NAME (msym.minsym) == NULL
-      || strncmp (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) != 0)
+      || !startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic."))
     return 0;
 
   /* A two-instruction header.  */
@@ -7684,27 +7893,15 @@ mips_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 
       new_pc = mips_skip_mips16_trampoline_code (frame, pc);
       if (new_pc)
-       {
-         pc = new_pc;
-         if (is_compact_addr (pc))
-           pc = unmake_compact_addr (pc);
-       }
+       pc = new_pc;
 
       new_pc = find_solib_trampoline_target (frame, pc);
       if (new_pc)
-       {
-         pc = new_pc;
-         if (is_compact_addr (pc))
-           pc = unmake_compact_addr (pc);
-       }
+       pc = new_pc;
 
       new_pc = mips_skip_pic_trampoline_code (frame, pc);
       if (new_pc)
-       {
-         pc = new_pc;
-         if (is_compact_addr (pc))
-           pc = unmake_compact_addr (pc);
-       }
+       pc = new_pc;
     }
   while (pc != target_pc);
 
@@ -7729,9 +7926,7 @@ mips_stab_reg_to_regnum (struct gdbarch *gdbarch, int num)
   else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 72 && num < 78)
     regnum = num + mips_regnum (gdbarch)->dspacc - 72;
   else
-    /* This will hopefully (eventually) provoke a warning.  Should
-       we be calling complaint() here?  */
-    return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
+    return -1;
   return gdbarch_num_regs (gdbarch) + regnum;
 }
 
@@ -7754,9 +7949,7 @@ mips_dwarf_dwarf2_ecoff_reg_to_regnum (struct gdbarch *gdbarch, int num)
   else if (mips_regnum (gdbarch)->dspacc != -1 && num >= 66 && num < 72)
     regnum = num + mips_regnum (gdbarch)->dspacc - 66;
   else
-    /* This will hopefully (eventually) provoke a warning.  Should we
-       be calling complaint() here?  */
-    return gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
+    return -1;
   return gdbarch_num_regs (gdbarch) + regnum;
 }
 
@@ -7812,7 +8005,7 @@ mips_find_abi_section (bfd *abfd, asection *sect, void *obj)
   if (*abip != MIPS_ABI_UNKNOWN)
     return;
 
-  if (strncmp (name, ".mdebug.", 8) != 0)
+  if (!startswith (name, ".mdebug."))
     return;
 
   if (strcmp (name, ".mdebug.abi32") == 0)
@@ -7837,11 +8030,11 @@ mips_find_long_section (bfd *abfd, asection *sect, void *obj)
   int *lbp = (int *) obj;
   const char *name = bfd_get_section_name (abfd, sect);
 
-  if (strncmp (name, ".gcc_compiled_long32", 20) == 0)
+  if (startswith (name, ".gcc_compiled_long32"))
     *lbp = 32;
-  else if (strncmp (name, ".gcc_compiled_long64", 20) == 0)
+  else if (startswith (name, ".gcc_compiled_long64"))
     *lbp = 64;
-  else if (strncmp (name, ".gcc_compiled_long", 18) == 0)
+  else if (startswith (name, ".gcc_compiled_long"))
     warning (_("unrecognized .gcc_compiled_longXX"));
 }
 
@@ -7894,7 +8087,7 @@ mips_register_g_packet_guesses (struct gdbarch *gdbarch)
 static struct value *
 value_of_mips_user_reg (struct frame_info *frame, const void *baton)
 {
-  const int *reg_p = baton;
+  const int *reg_p = (const int *) baton;
   return value_of_register (*reg_p, frame);
 }
 
@@ -7916,22 +8109,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   int dspctl;
 
   /* Fill in the OS dependent register numbers and names.  */
-  if (info.osabi == GDB_OSABI_IRIX)
-    {
-      mips_regnum.fp0 = 32;
-      mips_regnum.pc = 64;
-      mips_regnum.cause = 65;
-      mips_regnum.badvaddr = 66;
-      mips_regnum.hi = 67;
-      mips_regnum.lo = 68;
-      mips_regnum.fp_control_status = 69;
-      mips_regnum.fp_implementation_revision = 70;
-      mips_regnum.dspacc = dspacc = -1;
-      mips_regnum.dspctl = dspctl = -1;
-      num_regs = 71;
-      reg_names = mips_irix_reg_names;
-    }
-  else if (info.osabi == GDB_OSABI_LINUX)
+  if (info.osabi == GDB_OSABI_LINUX)
     {
       mips_regnum.fp0 = 38;
       mips_regnum.pc = 37;
@@ -7945,7 +8123,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       mips_regnum.dspctl = -1;
       dspacc = 72;
       dspctl = 78;
-      num_regs = 79;
+      num_regs = 90;
       reg_names = mips_linux_reg_names;
     }
   else
@@ -8064,6 +8242,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          return NULL;
        }
 
+      num_regs = mips_regnum.fp_implementation_revision + 1;
+
       if (dspacc >= 0)
        {
          feature = tdesc_find_feature (info.target_desc,
@@ -8097,6 +8277,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
              mips_regnum.dspacc = dspacc;
              mips_regnum.dspctl = dspctl;
+
+             num_regs = mips_regnum.dspctl + 1;
            }
        }
 
@@ -8167,7 +8349,8 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          /* On Irix, ELF64 executables use the N64 ABI.  The
             pseudo-sections which describe the ABI aren't present
             on IRIX.  (Even for executables created by gcc.)  */
-         if (bfd_get_flavour (info.abfd) == bfd_target_elf_flavour
+         if (info.abfd != NULL
+             && bfd_get_flavour (info.abfd) == bfd_target_elf_flavour
              && elf_elfheader (info.abfd)->e_ident[EI_CLASS] == ELFCLASS64)
            found_abi = MIPS_ABI_N64;
          else
@@ -8268,7 +8451,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        break;
       }
   else if (arches != NULL)
-    fpu_type = gdbarch_tdep (arches->gdbarch)->mips_fpu_type;
+    fpu_type = MIPS_FPU_TYPE (arches->gdbarch);
   else
     fpu_type = MIPS_FPU_DOUBLE;
   if (gdbarch_debug)
@@ -8308,7 +8491,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
          != mips64_transfers_32bit_regs_p)
        continue;
       /* Be pedantic about which FPU is selected.  */
-      if (gdbarch_tdep (arches->gdbarch)->mips_fpu_type != fpu_type)
+      if (MIPS_FPU_TYPE (arches->gdbarch) != fpu_type)
        continue;
 
       if (tdesc_data != NULL)
@@ -8317,7 +8500,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     }
 
   /* Need a new architecture.  Fill in a target specific vector.  */
-  tdep = (struct gdbarch_tdep *) xmalloc (sizeof (struct gdbarch_tdep));
+  tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
   tdep->elf_flags = elf_flags;
   tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
@@ -8360,6 +8543,9 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_elf_make_msymbol_special (gdbarch,
                                        mips_elf_make_msymbol_special);
+  set_gdbarch_make_symbol_special (gdbarch, mips_make_symbol_special);
+  set_gdbarch_adjust_dwarf2_addr (gdbarch, mips_adjust_dwarf2_addr);
+  set_gdbarch_adjust_dwarf2_line (gdbarch, mips_adjust_dwarf2_line);
 
   regnum = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct mips_regnum);
   *regnum = mips_regnum;
@@ -8539,20 +8725,21 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_push_dummy_code (gdbarch, mips_push_dummy_code);
   set_gdbarch_frame_align (gdbarch, mips_frame_align);
 
+  set_gdbarch_print_float_info (gdbarch, mips_print_float_info);
+
   set_gdbarch_convert_register_p (gdbarch, mips_convert_register_p);
   set_gdbarch_register_to_value (gdbarch, mips_register_to_value);
   set_gdbarch_value_to_register (gdbarch, mips_value_to_register);
 
   set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
-  set_gdbarch_breakpoint_from_pc (gdbarch, mips_breakpoint_from_pc);
-  set_gdbarch_remote_breakpoint_from_pc (gdbarch,
-                                        mips_remote_breakpoint_from_pc);
+  set_gdbarch_breakpoint_kind_from_pc (gdbarch, mips_breakpoint_kind_from_pc);
+  set_gdbarch_sw_breakpoint_from_kind (gdbarch, mips_sw_breakpoint_from_kind);
   set_gdbarch_adjust_breakpoint_address (gdbarch,
                                         mips_adjust_breakpoint_address);
 
   set_gdbarch_skip_prologue (gdbarch, mips_skip_prologue);
 
-  set_gdbarch_in_function_epilogue_p (gdbarch, mips_in_function_epilogue_p);
+  set_gdbarch_stack_frame_destroyed_p (gdbarch, mips_stack_frame_destroyed_p);
 
   set_gdbarch_pointer_to_address (gdbarch, signed_pointer_to_address);
   set_gdbarch_address_to_pointer (gdbarch, address_to_signed_pointer);
@@ -8598,7 +8785,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   mips_register_g_packet_guesses (gdbarch);
 
   /* Hook in OS ABI-specific overrides, if they have been registered.  */
-  info.tdep_info = (void *) tdesc_data;
+  info.tdesc_data = tdesc_data;
   gdbarch_init_osabi (info, gdbarch);
 
   /* The hook may have adjusted num_regs, fetch the final value and
@@ -8720,6 +8907,24 @@ show_mips_compression (struct ui_file *file, int from_tty,
                    value);
 }
 
+/* Return a textual name for MIPS FPU type FPU_TYPE.  */
+
+static const char *
+mips_fpu_type_str (enum mips_fpu_type fpu_type)
+{
+  switch (fpu_type)
+    {
+    case MIPS_FPU_NONE:
+      return "none";
+    case MIPS_FPU_SINGLE:
+      return "single";
+    case MIPS_FPU_DOUBLE:
+      return "double";
+    default:
+      return "???";
+    }
+}
+
 static void
 mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 {
@@ -8770,23 +8975,15 @@ mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
   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"
-                      : "???"));
+                     mips_fpu_type_str (MIPS_DEFAULT_FPU_TYPE));
   fprintf_unfiltered (file, "mips_dump_tdep: MIPS_EABI = %d\n",
                      MIPS_EABI (gdbarch));
   fprintf_unfiltered (file,
                      "mips_dump_tdep: MIPS_FPU_TYPE = %d (%s)\n",
                      MIPS_FPU_TYPE (gdbarch),
-                     (MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_NONE ? "none"
-                      : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_SINGLE ? "single"
-                      : MIPS_FPU_TYPE (gdbarch) == MIPS_FPU_DOUBLE ? "double"
-                      : "???"));
+                     mips_fpu_type_str (MIPS_FPU_TYPE (gdbarch)));
 }
 
-extern initialize_file_ftype _initialize_mips_tdep; /* -Wmissing-prototypes */
-
 void
 _initialize_mips_tdep (void)
 {
This page took 0.068104 seconds and 4 git commands to generate.