Remove i386_elf_emit_arch_note
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index cd6891affc12329be64f33f2948f9493f67de43e..6e8ccd688a42af1be95f90654d190c2747b46448 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for the MIPS architecture, for GDB, the GNU Debugger.
 
-   Copyright (C) 1988-2012 Free Software Foundation, Inc.
+   Copyright (C) 1988-2015 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.
@@ -21,8 +21,6 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_string.h"
-#include "gdb_assert.h"
 #include "frame.h"
 #include "inferior.h"
 #include "symtab.h"
@@ -62,6 +60,22 @@ 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 *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.  */
 #define ST0_FR (1 << 26)
@@ -93,6 +107,20 @@ static const char *const mips_abi_strings[] = {
   NULL
 };
 
+/* 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.  */
+static const char mips_compression_mips16[] = "mips16";
+static const char mips_compression_micromips[] = "micromips";
+static const char *const mips_compression_strings[] =
+{
+  mips_compression_mips16,
+  mips_compression_micromips,
+  NULL
+};
+
+static const char *mips_compression_string = mips_compression_mips16;
+
 /* The standard register names, and all the valid aliases for them.  */
 struct register_alias
 {
@@ -157,7 +185,7 @@ const struct register_alias mips_numeric_register_aliases[] = {
 static int mips_fpu_type_auto = 1;
 static enum mips_fpu_type mips_fpu_type = MIPS_DEFAULT_FPU_TYPE;
 
-static int mips_debug = 0;
+static unsigned int mips_debug = 0;
 
 /* Properties (for struct target_desc) describing the g/G packet
    layout.  */
@@ -246,51 +274,176 @@ mips_abi_regsize (struct gdbarch *gdbarch)
     }
 }
 
-/* MIPS16 function addresses are odd (bit 0 is set).  Here are some
-   functions to test, set, or clear bit 0 of addresses.  */
+/* MIPS16/microMIPS function addresses are odd (bit 0 is set).  Here
+   are some functions to handle addresses associated with compressed
+   code including but not limited to testing, setting, or clearing
+   bit 0 of such addresses.  */
 
-static CORE_ADDR
-is_mips16_addr (CORE_ADDR addr)
+/* Return one iff compressed code is the MIPS16 instruction set.  */
+
+static int
+is_mips16_isa (struct gdbarch *gdbarch)
+{
+  return gdbarch_tdep (gdbarch)->mips_isa == ISA_MIPS16;
+}
+
+/* Return one iff compressed code is the microMIPS instruction set.  */
+
+static int
+is_micromips_isa (struct gdbarch *gdbarch)
+{
+  return gdbarch_tdep (gdbarch)->mips_isa == ISA_MICROMIPS;
+}
+
+/* Return one iff ADDR denotes compressed code.  */
+
+static int
+is_compact_addr (CORE_ADDR addr)
 {
   return ((addr) & 1);
 }
 
+/* Return one iff ADDR denotes standard ISA code.  */
+
+static int
+is_mips_addr (CORE_ADDR addr)
+{
+  return !is_compact_addr (addr);
+}
+
+/* Return one iff ADDR denotes MIPS16 code.  */
+
+static int
+is_mips16_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  return is_compact_addr (addr) && is_mips16_isa (gdbarch);
+}
+
+/* Return one iff ADDR denotes microMIPS code.  */
+
+static int
+is_micromips_addr (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  return is_compact_addr (addr) && is_micromips_isa (gdbarch);
+}
+
+/* Strip the ISA (compression) bit off from ADDR.  */
+
 static CORE_ADDR
-unmake_mips16_addr (CORE_ADDR addr)
+unmake_compact_addr (CORE_ADDR addr)
 {
   return ((addr) & ~(CORE_ADDR) 1);
 }
 
+/* Add the ISA (compression) bit to ADDR.  */
+
 static CORE_ADDR
-make_mips16_addr (CORE_ADDR addr)
+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 16-bit function.  The MSB of the minimal symbol's
-   "info" field is used for this purpose.
+   marks it as MIPS16 or microMIPS function.  The MSB of the minimal
+   symbol's "info" field is used for this purpose.
 
-   gdbarch_elf_make_msymbol_special tests whether an ELF symbol is "special",
-   i.e. refers to a 16-bit function, and sets a "special" bit in a
-   minimal symbol to mark it as a 16-bit function
+   gdbarch_elf_make_msymbol_special tests whether an ELF symbol is
+   "special", i.e. refers to a MIPS16 or microMIPS function, and sets
+   one of the "special" bits in a minimal symbol to mark it accordingly.
+   The test checks an ELF-private flag that is valid for true function
+   symbols only; for synthetic symbols such as for PLT stubs that have
+   no ELF-private part at all the MIPS BFD backend arranges for this
+   information to be carried in the asymbol's udata field instead.
 
-   MSYMBOL_IS_SPECIAL   tests the "special" bit in a minimal symbol  */
+   msymbol_is_mips16 and msymbol_is_micromips test the "special" bit
+   in a minimal symbol.  */
 
 static void
 mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym)
 {
-  if (ELF_ST_IS_MIPS16 (((elf_symbol_type *)
-                        (sym))->internal_elf_sym.st_other))
+  elf_symbol_type *elfsym = (elf_symbol_type *) sym;
+  unsigned char st_other;
+
+  if ((sym->flags & BSF_SYNTHETIC) == 0)
+    st_other = elfsym->internal_elf_sym.st_other;
+  else if ((sym->flags & BSF_FUNCTION) != 0)
+    st_other = sym->udata.i;
+  else
+    return;
+
+  if (ELF_ST_IS_MICROMIPS (st_other))
+    {
+      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.  */
+
+static int
+msymbol_is_mips (struct minimal_symbol *msym)
+{
+  return !(MSYMBOL_TARGET_FLAG_MIPS16 (msym)
+          | MSYMBOL_TARGET_FLAG_MICROMIPS (msym));
+}
+
+/* Return one iff MSYM refers to MIPS16 code.  */
+
+static int
+msymbol_is_mips16 (struct minimal_symbol *msym)
+{
+  return MSYMBOL_TARGET_FLAG_MIPS16 (msym);
+}
+
+/* Return one iff MSYM refers to microMIPS code.  */
+
 static int
-msymbol_is_special (struct minimal_symbol *msym)
+msymbol_is_micromips (struct minimal_symbol *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)
 {
-  return MSYMBOL_TARGET_FLAG_1 (msym);
+  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.
@@ -686,14 +839,14 @@ mips_ax_pseudo_register_push_stack (struct gdbarch *gdbarch,
   return 0;
 }
 
-/* Table to translate MIPS16 register field to actual register number.  */
-static int mips16_to_32_reg[8] = { 16, 17, 2, 3, 4, 5, 6, 7 };
+/* Table to translate 3-bit register field to actual register number.  */
+static const signed char mips_reg3_to_reg[8] = { 16, 17, 2, 3, 4, 5, 6, 7 };
 
 /* Heuristic_proc_start may hunt through the text section for a long
    time across a 2400 baud serial line.  Allows the user to limit this
    search.  */
 
-static unsigned int heuristic_fence_post = 0;
+static int heuristic_fence_post = 0;
 
 /* Number of bytes of storage in the actual machine representation for
    register N.  NOTE: This defines the pseudo register type so need to
@@ -751,8 +904,8 @@ static int
 mips_convert_register_p (struct gdbarch *gdbarch,
                         int regnum, struct type *type)
 {
-  return mips_convert_register_float_case_p (gdbarch, regnum, type)
-      || mips_convert_register_gpreg_case_p (gdbarch, regnum, type);
+  return (mips_convert_register_float_case_p (gdbarch, regnum, type)
+         || mips_convert_register_gpreg_case_p (gdbarch, regnum, type));
 }
 
 static int
@@ -910,7 +1063,6 @@ static struct type *
 mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
 {
   const int num_regs = gdbarch_num_regs (gdbarch);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   int rawnum = regnum % num_regs;
   struct type *rawtype;
 
@@ -921,8 +1073,7 @@ mips_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
   if (TYPE_LENGTH (rawtype) == 0)
     return rawtype;
 
-  if (rawnum >= mips_regnum (gdbarch)->fp0
-      && rawnum < mips_regnum (gdbarch)->fp0 + 32)
+  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;
@@ -995,7 +1146,7 @@ static void
 show_mask_address (struct ui_file *file, int from_tty,
                   struct cmd_list_element *c, const char *value)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (target_gdbarch);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (target_gdbarch ());
 
   deprecated_show_value_hack (file, from_tty, c, value);
   switch (mask_address_var)
@@ -1017,22 +1168,155 @@ show_mask_address (struct ui_file *file, int from_tty,
     }
 }
 
+/* Tell if the program counter value in MEMADDR is in a standard ISA
+   function.  */
+
+int
+mips_pc_is_mips (CORE_ADDR memaddr)
+{
+  struct bound_minimal_symbol sym;
+
+  /* Flags indicating that this is a MIPS16 or microMIPS function is
+     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 (make_compact_addr (memaddr));
+  if (sym.minsym)
+    return msymbol_is_mips (sym.minsym);
+  else
+    return is_mips_addr (memaddr);
+}
+
 /* Tell if the program counter value in MEMADDR is in a MIPS16 function.  */
 
 int
-mips_pc_is_mips16 (CORE_ADDR memaddr)
+mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr)
 {
-  struct minimal_symbol *sym;
+  struct bound_minimal_symbol sym;
 
   /* A flag indicating that this is a MIPS16 function is stored by
      elfread.c in the high bit of the info field.  Use this to decide
-     if the function is MIPS16 or normal MIPS.  Otherwise if bit 0 of
-     the address is set, assume this is a MIPS16 address.  */
-  sym = lookup_minimal_symbol_by_pc (memaddr);
-  if (sym)
-    return msymbol_is_special (sym);
+     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 (make_compact_addr (memaddr));
+  if (sym.minsym)
+    return msymbol_is_mips16 (sym.minsym);
+  else
+    return is_mips16_addr (gdbarch, memaddr);
+}
+
+/* Tell if the program counter value in MEMADDR is in a microMIPS function.  */
+
+int
+mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr)
+{
+  struct bound_minimal_symbol sym;
+
+  /* A flag indicating that this is a microMIPS function is stored by
+     elfread.c in the high bit of the info field.  Use this to decide
+     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 (make_compact_addr (memaddr));
+  if (sym.minsym)
+    return msymbol_is_micromips (sym.minsym);
+  else
+    return is_micromips_addr (gdbarch, memaddr);
+}
+
+/* Tell the ISA type of the function the program counter value in MEMADDR
+   is in.  */
+
+static enum mips_isa
+mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr)
+{
+  struct bound_minimal_symbol sym;
+
+  /* A flag indicating that this is a MIPS16 or a microMIPS function
+     is stored by elfread.c in the high bit of the info field.  Use
+     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 (make_compact_addr (memaddr));
+  if (sym.minsym)
+    {
+      if (msymbol_is_micromips (sym.minsym))
+       return ISA_MICROMIPS;
+      else if (msymbol_is_mips16 (sym.minsym))
+       return ISA_MIPS16;
+      else
+       return ISA_MIPS;
+    }
   else
-    return is_mips16_addr (memaddr);
+    {
+      if (is_mips_addr (memaddr))
+       return ISA_MIPS;
+      else if (is_micromips_addr (gdbarch, memaddr))
+       return ISA_MICROMIPS;
+      else
+       return ISA_MIPS16;
+    }
+}
+
+/* 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.  */
@@ -1061,14 +1345,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.  */
@@ -1081,11 +1364,9 @@ static CORE_ADDR
 mips_read_pc (struct regcache *regcache)
 {
   int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
-  ULONGEST pc;
+  LONGEST pc;
 
   regcache_cooked_read_signed (regcache, regnum, &pc);
-  if (is_mips16_addr (pc))
-    pc = unmake_mips16_addr (pc);
   return pc;
 }
 
@@ -1095,8 +1376,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_mips16_addr (pc))
-    pc = unmake_mips16_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
@@ -1106,15 +1385,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_mips16_addr (pc))
-       pc = unmake_mips16_addr (pc);
       if (mips_in_frame_stub (pc))
-       {
-         pc = frame_unwind_register_signed
-                (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
-         if (is_mips16_addr (pc))
-           pc = unmake_mips16_addr (pc);
-       }
+       pc = frame_unwind_register_signed
+              (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
     }
   return pc;
 }
@@ -1148,33 +1421,44 @@ mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
   int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
 
-  if (mips_pc_is_mips16 (pc))
-    regcache_cooked_write_unsigned (regcache, regnum, make_mips16_addr (pc));
-  else
-    regcache_cooked_write_unsigned (regcache, regnum, pc);
+  regcache_cooked_write_unsigned (regcache, regnum, pc);
 }
 
-/* Fetch and return instruction from the specified location.  If the PC
-   is odd, assume it's a MIPS16 instruction; otherwise MIPS32.  */
+/* Fetch and return instruction from the specified location.  Handle
+   MIPS16/microMIPS as appropriate.  */
 
 static ULONGEST
-mips_fetch_instruction (struct gdbarch *gdbarch, CORE_ADDR addr)
+mips_fetch_instruction (struct gdbarch *gdbarch,
+                       enum mips_isa isa, CORE_ADDR addr, int *statusp)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[MIPS_INSN32_SIZE];
   int instlen;
   int status;
 
-  if (mips_pc_is_mips16 (addr))
+  switch (isa)
     {
+    case ISA_MICROMIPS:
+    case ISA_MIPS16:
       instlen = MIPS_INSN16_SIZE;
-      addr = unmake_mips16_addr (addr);
+      addr = unmake_compact_addr (addr);
+      break;
+    case ISA_MIPS:
+      instlen = MIPS_INSN32_SIZE;
+      break;
+    default:
+      internal_error (__FILE__, __LINE__, _("invalid ISA"));
+      break;
     }
-  else
-    instlen = MIPS_INSN32_SIZE;
   status = target_read_memory (addr, buf, instlen);
+  if (statusp != NULL)
+    *statusp = status;
   if (status)
-    memory_error (status, addr);
+    {
+      if (statusp == NULL)
+       memory_error (status, addr);
+      return 0;
+    }
   return extract_unsigned_integer (buf, instlen, byte_order);
 }
 
@@ -1195,6 +1479,63 @@ mips_fetch_instruction (struct gdbarch *gdbarch, CORE_ADDR addr)
 #define rtype_shamt(x) ((x >> 6) & 0x1f)
 #define rtype_funct(x) (x & 0x3f)
 
+/* MicroMIPS instruction fields.  */
+#define micromips_op(x) ((x) >> 10)
+
+/* 16-bit/32-bit-high-part instruction formats, B and S refer to the lowest
+   bit and the size respectively of the field extracted.  */
+#define b0s4_imm(x) ((x) & 0xf)
+#define b0s5_imm(x) ((x) & 0x1f)
+#define b0s5_reg(x) ((x) & 0x1f)
+#define b0s7_imm(x) ((x) & 0x7f)
+#define b0s10_imm(x) ((x) & 0x3ff)
+#define b1s4_imm(x) (((x) >> 1) & 0xf)
+#define b1s9_imm(x) (((x) >> 1) & 0x1ff)
+#define b2s3_cc(x) (((x) >> 2) & 0x7)
+#define b4s2_regl(x) (((x) >> 4) & 0x3)
+#define b5s5_op(x) (((x) >> 5) & 0x1f)
+#define b5s5_reg(x) (((x) >> 5) & 0x1f)
+#define b6s4_op(x) (((x) >> 6) & 0xf)
+#define b7s3_reg(x) (((x) >> 7) & 0x7)
+
+/* 32-bit instruction formats, B and S refer to the lowest bit and the size
+   respectively of the field extracted.  */
+#define b0s6_op(x) ((x) & 0x3f)
+#define b0s11_op(x) ((x) & 0x7ff)
+#define b0s12_imm(x) ((x) & 0xfff)
+#define b0s16_imm(x) ((x) & 0xffff)
+#define b0s26_imm(x) ((x) & 0x3ffffff)
+#define b6s10_ext(x) (((x) >> 6) & 0x3ff)
+#define b11s5_reg(x) (((x) >> 11) & 0x1f)
+#define b12s4_op(x) (((x) >> 12) & 0xf)
+
+/* Return the size in bytes of the instruction INSN encoded in the ISA
+   instruction set.  */
+
+static int
+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))
+        return 2 * MIPS_INSN16_SIZE;
+      else
+        return MIPS_INSN16_SIZE;
+    case ISA_MIPS16:
+      if ((insn & 0xf800) == 0xf000)
+       return 2 * MIPS_INSN16_SIZE;
+      else
+       return MIPS_INSN16_SIZE;
+    case ISA_MIPS:
+       return MIPS_INSN32_SIZE;
+    }
+  internal_error (__FILE__, __LINE__, _("invalid ISA"));
+}
+
 static LONGEST
 mips32_relative_offset (ULONGEST inst)
 {
@@ -1231,23 +1572,53 @@ mips32_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
   return pc;
 }
 
+/* Return nonzero if the gdbarch is an Octeon series.  */
+
+static int
+is_octeon (struct gdbarch *gdbarch)
+{
+  const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch);
+
+  return (info->mach == bfd_mach_mips_octeon
+         || info->mach == bfd_mach_mips_octeonp
+         || info->mach == bfd_mach_mips_octeon2);
+}
+
+/* Return true if the OP represents the Octeon's BBIT instruction.  */
+
+static int
+is_octeon_bbit_op (int op, struct gdbarch *gdbarch)
+{
+  if (!is_octeon (gdbarch))
+    return 0;
+  /* BBIT0 is encoded as LWC2: 110 010.  */
+  /* BBIT032 is encoded as LDC2: 110 110.  */
+  /* BBIT1 is encoded as SWC2: 111 010.  */
+  /* BBIT132 is encoded as SDC2: 111 110.  */
+  if (op == 50 || op == 54 || op == 58 || op == 62)
+    return 1;
+  return 0;
+}
+
+
 /* Determine where to set a single step breakpoint while considering
    branch prediction.  */
+
 static CORE_ADDR
 mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   unsigned long inst;
   int op;
-  inst = mips_fetch_instruction (gdbarch, pc);
+  inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
+  op = itype_op (inst);
   if ((inst & 0xe0000000) != 0)                /* Not a special, jump or branch
                                           instruction.  */
     {
-      if (itype_op (inst) >> 2 == 5)
+      if (op >> 2 == 5)
        /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx */
        {
-         op = (itype_op (inst) & 0x03);
-         switch (op)
+         switch (op & 0x03)
            {
            case 0:             /* BEQL */
              goto equal_branch;
@@ -1261,18 +1632,18 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
              pc += 4;
            }
        }
-      else if (itype_op (inst) == 17 && itype_rs (inst) == 8)
+      else if (op == 17 && itype_rs (inst) == 8)
        /* BC1F, BC1FL, BC1T, BC1TL: 010001 01000 */
        pc = mips32_bc1_pc (gdbarch, frame, inst, pc + 4, 1);
-      else if (itype_op (inst) == 17 && itype_rs (inst) == 9
+      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);
-      else if (itype_op (inst) == 17 && itype_rs (inst) == 10
+      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);
-      else if (itype_op (inst) == 29)
+      else if (op == 29)
        /* JALX: 011101 */
        /* The new PC will be alternate mode.  */
        {
@@ -1282,6 +1653,25 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
          /* Add 1 to indicate 16-bit mode -- invert ISA mode.  */
          pc = ((pc + 4) & ~(CORE_ADDR) 0x0fffffff) + reg + 1;
        }
+      else if (is_octeon_bbit_op (op, gdbarch))
+       {
+         int bit, branch_if;
+
+         branch_if = op == 58 || op == 62;
+         bit = itype_rt (inst);
+
+         /* Take into account the *32 instructions.  */
+         if (op == 54 || op == 62)
+           bit += 32;
+
+         if (((get_frame_register_signed (frame,
+                                          itype_rs (inst)) >> bit) & 1)
+              == branch_if)
+           pc += mips32_relative_offset (inst) + 4;
+          else
+           pc += 8;        /* After the delay slot.  */
+       }
+
       else
        pc += 4;                /* Not a branch, next instruction is easy.  */
     }
@@ -1289,7 +1679,7 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
     {                          /* This gets way messy.  */
 
       /* Further subdivide into SPECIAL, REGIMM and other.  */
-      switch (op = itype_op (inst) & 0x07)     /* Extract bits 28,27,26.  */
+      switch (op & 0x07)       /* Extract bits 28,27,26.  */
        {
        case 0:         /* SPECIAL */
          op = rtype_funct (inst);
@@ -1409,96 +1799,367 @@ mips32_next_pc (struct frame_info *frame, CORE_ADDR pc)
   return pc;
 }                              /* mips32_next_pc */
 
-/* Decoding the next place to set a breakpoint is irregular for the
-   mips 16 variant, but fortunately, there fewer instructions.  We have
-   to cope ith extensions for 16 bit instructions and a pair of actual
-   32 bit instructions.  We dont want to set a single step instruction
-   on the extend instruction either.  */
+/* Extract the 7-bit signed immediate offset from the microMIPS instruction
+   INSN.  */
 
-/* Lots of mips16 instruction formats */
-/* Predicting jumps requires itype,ritype,i8type
-   and their extensions      extItype,extritype,extI8type.  */
-enum mips16_inst_fmts
-{
-  itype,                       /* 0  immediate 5,10 */
-  ritype,                      /* 1   5,3,8 */
-  rrtype,                      /* 2   5,3,3,5 */
-  rritype,                     /* 3   5,3,3,5 */
-  rrrtype,                     /* 4   5,3,3,3,2 */
-  rriatype,                    /* 5   5,3,3,1,4 */
-  shifttype,                   /* 6   5,3,3,3,2 */
-  i8type,                      /* 7   5,3,8 */
-  i8movtype,                   /* 8   5,3,3,5 */
-  i8mov32rtype,                        /* 9   5,3,5,3 */
-  i64type,                     /* 10  5,3,8 */
-  ri64type,                    /* 11  5,3,3,5 */
-  jalxtype,                    /* 12  5,1,5,5,16 - a 32 bit instruction */
-  exiItype,                    /* 13  5,6,5,5,1,1,1,1,1,1,5 */
-  extRitype,                   /* 14  5,6,5,5,3,1,1,1,5 */
-  extRRItype,                  /* 15  5,5,5,5,3,3,5 */
-  extRRIAtype,                 /* 16  5,7,4,5,3,3,1,4 */
-  EXTshifttype,                        /* 17  5,5,1,1,1,1,1,1,5,3,3,1,1,1,2 */
-  extI8type,                   /* 18  5,6,5,5,3,1,1,1,5 */
-  extI64type,                  /* 19  5,6,5,5,3,1,1,1,5 */
-  extRi64type,                 /* 20  5,6,5,5,3,3,5 */
-  extshift64type               /* 21  5,5,1,1,1,1,1,1,5,1,1,1,3,5 */
-};
-/* I am heaping all the fields of the formats into one structure and
-   then, only the fields which are involved in instruction extension.  */
-struct upk_mips16
+static LONGEST
+micromips_relative_offset7 (ULONGEST insn)
 {
-  CORE_ADDR offset;
-  unsigned int regx;           /* Function in i8 type.  */
-  unsigned int regy;
-};
+  return ((b0s7_imm (insn) ^ 0x40) - 0x40) << 1;
+}
 
+/* Extract the 10-bit signed immediate offset from the microMIPS instruction
+   INSN.  */
 
-/* The EXT-I, EXT-ri nad EXT-I8 instructions all have the same format
-   for the bits which make up the immediate extension.  */
+static LONGEST
+micromips_relative_offset10 (ULONGEST insn)
+{
+  return ((b0s10_imm (insn) ^ 0x200) - 0x200) << 1;
+}
 
-static CORE_ADDR
-extended_offset (unsigned int extension)
+/* Extract the 16-bit signed immediate offset from the microMIPS instruction
+   INSN.  */
+
+static LONGEST
+micromips_relative_offset16 (ULONGEST insn)
 {
-  CORE_ADDR value;
+  return ((b0s16_imm (insn) ^ 0x8000) - 0x8000) << 1;
+}
 
-  value = (extension >> 16) & 0x1f;    /* Extract 15:11.  */
-  value = value << 6;
-  value |= (extension >> 21) & 0x3f;   /* Extract 10:5.  */
-  value = value << 5;
-  value |= extension & 0x1f;           /* Extract 4:0.  */
+/* Return the size in bytes of the microMIPS instruction at the address PC.  */
 
-  return value;
+static int
+micromips_pc_insn_size (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  ULONGEST insn;
+
+  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
+  return mips_insn_size (ISA_MICROMIPS, insn);
 }
 
-/* Only call this function if you know that this is an extendable
-   instruction.  It won't malfunction, but why make excess remote memory
-   references?  If the immediate operands get sign extended or something,
-   do it after the extension is performed.  */
-/* FIXME: Every one of these cases needs to worry about sign extension
-   when the offset is to be used in relative addressing.  */
+/* Calculate the address of the next microMIPS instruction to execute
+   after the INSN coprocessor 1 conditional branch instruction at the
+   address PC.  COUNT denotes the number of coprocessor condition bits
+   examined by the branch.  */
 
-static unsigned int
-fetch_mips_16 (struct gdbarch *gdbarch, CORE_ADDR pc)
+static CORE_ADDR
+micromips_bc1_pc (struct gdbarch *gdbarch, struct frame_info *frame,
+                 ULONGEST insn, CORE_ADDR pc, int count)
 {
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  gdb_byte buf[8];
-  pc &= 0xfffffffe;            /* Clear the low order bit.  */
-  target_read_memory (pc, buf, 2);
-  return extract_unsigned_integer (buf, 2, byte_order);
+  int fcsr = mips_regnum (gdbarch)->fp_control_status;
+  int cnum = b2s3_cc (insn >> 16) & (count - 1);
+  int tf = b5s5_op (insn >> 16) & 1;
+  int mask = (1 << count) - 1;
+  ULONGEST fcs;
+  int cond;
+
+  if (fcsr == -1)
+    /* No way to handle; it'll most likely trap anyway.  */
+    return pc;
+
+  fcs = get_frame_register_unsigned (frame, fcsr);
+  cond = ((fcs >> 24) & 0xfe) | ((fcs >> 23) & 0x01);
+
+  if (((cond >> cnum) & mask) != mask * !tf)
+    pc += micromips_relative_offset16 (insn);
+  else
+    pc += micromips_pc_insn_size (gdbarch, pc);
+
+  return pc;
 }
 
-static void
-unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
-              unsigned int extension,
-              unsigned int inst,
-              enum mips16_inst_fmts insn_format, struct upk_mips16 *upk)
+/* Calculate the address of the next microMIPS instruction to execute
+   after the instruction at the address PC.  */
+
+static CORE_ADDR
+micromips_next_pc (struct frame_info *frame, CORE_ADDR pc)
 {
-  CORE_ADDR offset;
-  int regx;
-  int regy;
-  switch (insn_format)
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+  ULONGEST insn;
+
+  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
+  pc += MIPS_INSN16_SIZE;
+  switch (mips_insn_size (ISA_MICROMIPS, insn))
     {
-    case itype:
+    /* 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;
+      insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
+      pc += MIPS_INSN16_SIZE;
+      switch (micromips_op (insn >> 16))
+       {
+       case 0x00: /* POOL32A: bits 000000 */
+         if (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 */
+           pc = get_frame_register_signed (frame, b0s5_reg (insn >> 16));
+         break;
+
+       case 0x10: /* POOL32I: bits 010000 */
+         switch (b5s5_op (insn >> 16))
+           {
+           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)
+               pc += micromips_relative_offset16 (insn);
+             else
+               pc += micromips_pc_insn_size (gdbarch, pc);
+             break;
+
+           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)
+               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)
+               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)
+               pc += micromips_relative_offset16 (insn);
+             break;
+
+           case 0x06: /* BGTZ: bits 010000 00110 */
+             if (get_frame_register_signed (frame,
+                                            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)
+               pc += micromips_relative_offset16 (insn);
+             break;
+
+           case 0x14: /* BC2F: bits 010000 10100 xxx00 */
+           case 0x15: /* BC2T: bits 010000 10101 xxx00 */
+             if (((insn >> 16) & 0x3) == 0x0)
+               /* BC2F, BC2T: don't know how to handle these.  */
+               break;
+             break;
+
+           case 0x1a: /* BPOSGE64: bits 010000 11010 */
+           case 0x1b: /* BPOSGE32: bits 010000 11011 */
+             {
+               unsigned int pos = (b5s5_op (insn >> 16) & 1) ? 32 : 64;
+               int dspctl = mips_regnum (gdbarch)->dspctl;
+
+               if (dspctl == -1)
+                 /* No way to handle; it'll most likely trap anyway.  */
+                 break;
+
+               if ((get_frame_register_unsigned (frame,
+                                                 dspctl) & 0x7f) >= pos)
+                 pc += micromips_relative_offset16 (insn);
+               else
+                 pc += micromips_pc_insn_size (gdbarch, pc);
+             }
+             break;
+
+           case 0x1c: /* BC1F: bits 010000 11100 xxx00 */
+                      /* BC1ANY2F: bits 010000 11100 xxx01 */
+           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,
+                                      ((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);
+             break;
+           }
+         break;
+
+       case 0x1d: /* JALS: bits 011101 */
+       case 0x35: /* J: bits 110101 */
+       case 0x3d: /* JAL: bits 111101 */
+           pc = ((pc | 0x7fffffe) ^ 0x7fffffe) | (b0s26_imm (insn) << 1);
+         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)))
+             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)))
+             pc += micromips_relative_offset16 (insn);
+           else
+             pc += micromips_pc_insn_size (gdbarch, pc);
+         break;
+
+       case 0x3c: /* JALX: bits 111100 */
+           pc = ((pc | 0xfffffff) ^ 0xfffffff) | (b0s26_imm (insn) << 2);
+         break;
+       }
+      break;
+
+    /* 16-bit instructions.  */
+    case MIPS_INSN16_SIZE:
+      switch (micromips_op (insn))
+       {
+       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));
+         else if (b5s5_op (insn) == 0x18)
+           /* JRADDIUSP: bits 010001 11000 */
+           pc = get_frame_register_signed (frame, 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)
+             pc += micromips_relative_offset7 (insn);
+           else
+             pc += micromips_pc_insn_size (gdbarch, pc);
+         }
+         break;
+
+       case 0x2b: /* BNEZ16: bits 101011 */
+         {
+           int rs = mips_reg3_to_reg[b7s3_reg (insn)];
+
+           if (get_frame_register_signed (frame, rs) != 0)
+             pc += micromips_relative_offset7 (insn);
+           else
+             pc += micromips_pc_insn_size (gdbarch, pc);
+         }
+         break;
+
+       case 0x33: /* B16: bits 110011 */
+         pc += micromips_relative_offset10 (insn);
+         break;
+       }
+      break;
+    }
+
+  return pc;
+}
+
+/* Decoding the next place to set a breakpoint is irregular for the
+   mips 16 variant, but fortunately, there fewer instructions.  We have
+   to cope ith extensions for 16 bit instructions and a pair of actual
+   32 bit instructions.  We dont want to set a single step instruction
+   on the extend instruction either.  */
+
+/* Lots of mips16 instruction formats */
+/* Predicting jumps requires itype,ritype,i8type
+   and their extensions      extItype,extritype,extI8type.  */
+enum mips16_inst_fmts
+{
+  itype,                       /* 0  immediate 5,10 */
+  ritype,                      /* 1   5,3,8 */
+  rrtype,                      /* 2   5,3,3,5 */
+  rritype,                     /* 3   5,3,3,5 */
+  rrrtype,                     /* 4   5,3,3,3,2 */
+  rriatype,                    /* 5   5,3,3,1,4 */
+  shifttype,                   /* 6   5,3,3,3,2 */
+  i8type,                      /* 7   5,3,8 */
+  i8movtype,                   /* 8   5,3,3,5 */
+  i8mov32rtype,                        /* 9   5,3,5,3 */
+  i64type,                     /* 10  5,3,8 */
+  ri64type,                    /* 11  5,3,3,5 */
+  jalxtype,                    /* 12  5,1,5,5,16 - a 32 bit instruction */
+  exiItype,                    /* 13  5,6,5,5,1,1,1,1,1,1,5 */
+  extRitype,                   /* 14  5,6,5,5,3,1,1,1,5 */
+  extRRItype,                  /* 15  5,5,5,5,3,3,5 */
+  extRRIAtype,                 /* 16  5,7,4,5,3,3,1,4 */
+  EXTshifttype,                        /* 17  5,5,1,1,1,1,1,1,5,3,3,1,1,1,2 */
+  extI8type,                   /* 18  5,6,5,5,3,1,1,1,5 */
+  extI64type,                  /* 19  5,6,5,5,3,1,1,1,5 */
+  extRi64type,                 /* 20  5,6,5,5,3,3,5 */
+  extshift64type               /* 21  5,5,1,1,1,1,1,1,5,1,1,1,3,5 */
+};
+/* I am heaping all the fields of the formats into one structure and
+   then, only the fields which are involved in instruction extension.  */
+struct upk_mips16
+{
+  CORE_ADDR offset;
+  unsigned int regx;           /* Function in i8 type.  */
+  unsigned int regy;
+};
+
+
+/* The EXT-I, EXT-ri nad EXT-I8 instructions all have the same format
+   for the bits which make up the immediate extension.  */
+
+static CORE_ADDR
+extended_offset (unsigned int extension)
+{
+  CORE_ADDR value;
+
+  value = (extension >> 16) & 0x1f;    /* Extract 15:11.  */
+  value = value << 6;
+  value |= (extension >> 21) & 0x3f;   /* Extract 10:5.  */
+  value = value << 5;
+  value |= extension & 0x1f;           /* Extract 4:0.  */
+
+  return value;
+}
+
+/* Only call this function if you know that this is an extendable
+   instruction.  It won't malfunction, but why make excess remote memory
+   references?  If the immediate operands get sign extended or something,
+   do it after the extension is performed.  */
+/* FIXME: Every one of these cases needs to worry about sign extension
+   when the offset is to be used in relative addressing.  */
+
+static unsigned int
+fetch_mips_16 (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  gdb_byte buf[8];
+
+  pc = unmake_compact_addr (pc);       /* Clear the low order bit.  */
+  target_read_memory (pc, buf, 2);
+  return extract_unsigned_integer (buf, 2, byte_order);
+}
+
+static void
+unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
+              unsigned int extension,
+              unsigned int inst,
+              enum mips16_inst_fmts insn_format, struct upk_mips16 *upk)
+{
+  CORE_ADDR offset;
+  int regx;
+  int regy;
+  switch (insn_format)
+    {
+    case itype:
       {
        CORE_ADDR value;
        if (extension)
@@ -1543,8 +2204,8 @@ unpack_mips16 (struct gdbarch *gdbarch, CORE_ADDR pc,
        unsigned int nexthalf;
        value = ((inst & 0x1f) << 5) | ((inst >> 5) & 0x1f);
        value = value << 16;
-       nexthalf = mips_fetch_instruction (gdbarch, pc + 2);  /* low bit
-                                                                still set.  */
+       nexthalf = mips_fetch_instruction (gdbarch, ISA_MIPS16, pc + 2, NULL);
+                                               /* Low bit still set.  */
        value |= nexthalf;
        offset = value;
        regx = -1;
@@ -1560,10 +2221,13 @@ 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
@@ -1578,7 +2242,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
@@ -1586,7 +2250,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
@@ -1598,9 +2262,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, mips16_to_32_reg[upk.regx]);
+       reg = get_frame_register_signed (frame, 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;
@@ -1610,9 +2274,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, mips16_to_32_reg[upk.regx]);
+       reg = get_frame_register_signed (frame, 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;
@@ -1626,8 +2290,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        reg = get_frame_register_signed (frame, 24);  /* Test register is 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;
@@ -1643,7 +2306,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
            upk.regx = (insn >> 8) & 0x07;
            upk.regy = (insn >> 5) & 0x07;
            if ((upk.regy & 1) == 0)
-             reg = mips16_to_32_reg[upk.regx];
+             reg = mips_reg3_to_reg[upk.regx];
            else
              reg = 31;         /* Function return instruction.  */
            pc = get_frame_register_signed (frame, reg);
@@ -1682,17 +2345,63 @@ mips16_next_pc (struct frame_info *frame, CORE_ADDR pc)
 /* The mips_next_pc function supports single_step when the remote
    target monitor or stub is not developed enough to do a single_step.
    It works by decoding the current instruction and predicting where a
-   branch will go.  This isnt hard because all the data is available.
-   The MIPS32 and MIPS16 variants are quite different.  */
+   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)
 {
-  if (mips_pc_is_mips16 (pc))
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+
+  if (mips_pc_is_mips16 (gdbarch, pc))
     return mips16_next_pc (frame, pc);
+  else if (mips_pc_is_micromips (gdbarch, pc))
+    return micromips_next_pc (frame, pc);
   else
     return mips32_next_pc (frame, 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
 {
   CORE_ADDR base;
@@ -1770,6 +2479,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;
@@ -1780,11 +2493,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.  */
@@ -1797,15 +2512,23 @@ 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;
 
       /* Fetch and decode the instruction.  */
-      inst = (unsigned short) mips_fetch_instruction (gdbarch, cur_pc);
+      inst = (unsigned short) mips_fetch_instruction (gdbarch, ISA_MIPS16,
+                                                     cur_pc, NULL);
 
       /* Normally we ignore extend instructions.  However, if it is
          not followed by a valid prologue instruction, then this
@@ -1836,13 +2559,13 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
       else if ((inst & 0xf800) == 0xd000)      /* sw reg,n($sp) */
        {
          offset = mips16_get_imm (prev_inst, inst, 8, 4, 0);
-         reg = mips16_to_32_reg[(inst & 0x700) >> 8];
+         reg = mips_reg3_to_reg[(inst & 0x700) >> 8];
          set_reg_offset (gdbarch, this_cache, reg, sp + offset);
        }
       else if ((inst & 0xff00) == 0xf900)      /* sd reg,n($sp) */
        {
          offset = mips16_get_imm (prev_inst, inst, 5, 8, 0);
-         reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
+         reg = mips_reg3_to_reg[(inst & 0xe0) >> 5];
          set_reg_offset (gdbarch, this_cache, reg, sp + offset);
        }
       else if ((inst & 0xff00) == 0x6200)      /* sw $ra,n($sp) */
@@ -1870,13 +2593,13 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
       else if ((inst & 0xFF00) == 0xd900)      /* sw reg,offset($s1) */
        {
          offset = mips16_get_imm (prev_inst, inst, 5, 4, 0);
-         reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
+         reg = mips_reg3_to_reg[(inst & 0xe0) >> 5];
          set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset);
        }
       else if ((inst & 0xFF00) == 0x7900)      /* sd reg,offset($s1) */
        {
          offset = mips16_get_imm (prev_inst, inst, 5, 8, 0);
-         reg = mips16_to_32_reg[(inst & 0xe0) >> 5];
+         reg = mips_reg3_to_reg[(inst & 0xe0) >> 5];
          set_reg_offset (gdbarch, this_cache, reg, frame_addr + offset);
        }
       else if ((inst & 0xf81f) == 0xe809
@@ -1888,21 +2611,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,
@@ -2055,11 +2797,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;
 }
@@ -2129,8 +2872,9 @@ static int
 mips_insn16_frame_sniffer (const struct frame_unwind *self,
                           struct frame_info *this_frame, void **this_cache)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
-  if (mips_pc_is_mips16 (pc))
+  if (mips_pc_is_mips16 (gdbarch, pc))
     return 1;
   return 0;
 }
@@ -2165,13 +2909,462 @@ static const struct frame_base mips_insn16_frame_base =
 static const struct frame_base *
 mips_insn16_frame_base_sniffer (struct frame_info *this_frame)
 {
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR pc = get_frame_pc (this_frame);
-  if (mips_pc_is_mips16 (pc))
+  if (mips_pc_is_mips16 (gdbarch, pc))
     return &mips_insn16_frame_base;
   else
     return NULL;
 }
 
+/* Decode a 9-bit signed immediate argument of ADDIUSP -- -2 is mapped
+   to -258, -1 -- to -257, 0 -- to 256, 1 -- to 257 and other values are
+   interpreted directly, and then multiplied by 4.  */
+
+static int
+micromips_decode_imm9 (int imm)
+{
+  imm = (imm ^ 0x100) - 0x100;
+  if (imm > -3 && imm < 2)
+    imm ^= 0x100;
+  return imm << 2;
+}
+
+/* Analyze the function prologue from START_PC to LIMIT_PC.  Return
+   the address of the first instruction past the prologue.  */
+
+static CORE_ADDR
+micromips_scan_prologue (struct gdbarch *gdbarch,
+                        CORE_ADDR start_pc, CORE_ADDR limit_pc,
+                        struct frame_info *this_frame,
+                        struct mips_frame_cache *this_cache)
+{
+  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 */
+  CORE_ADDR sp;
+  long offset;
+  long sp_adj;
+  long v1_off = 0;             /* The assumption is LUI will replace it.  */
+  int reglist;
+  int breg;
+  int dreg;
+  int sreg;
+  int treg;
+  int loc;
+  int op;
+  int s;
+  int i;
+
+  /* Can be called when there's no process, and hence when there's no
+     THIS_FRAME.  */
+  if (this_frame != NULL)
+    sp = get_frame_register_signed (this_frame,
+                                   gdbarch_num_regs (gdbarch)
+                                   + MIPS_SP_REGNUM);
+  else
+    sp = 0;
+
+  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 += 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;
+         insn |= mips_fetch_instruction (gdbarch,
+                                         ISA_MICROMIPS, cur_pc + loc, NULL);
+         loc += MIPS_INSN16_SIZE;
+         switch (micromips_op (insn >> 16))
+           {
+           /* Record $sp/$fp adjustment.  */
+           /* Discard (D)ADDU $gp,$jp used for PIC code.  */
+           case 0x0: /* POOL32A: bits 000000 */
+           case 0x16: /* POOL32S: bits 010110 */
+             op = b0s11_op (insn);
+             sreg = b0s5_reg (insn >> 16);
+             treg = b5s5_reg (insn >> 16);
+             dreg = b11s5_reg (insn);
+             if (op == 0x1d0
+                               /* SUBU: bits 000000 00111010000 */
+                               /* DSUBU: bits 010110 00111010000 */
+                 && dreg == MIPS_SP_REGNUM && sreg == MIPS_SP_REGNUM
+                 && treg == 3)
+                               /* (D)SUBU $sp, $v1 */
+                   sp_adj = v1_off;
+             else if (op != 0x150
+                               /* ADDU: bits 000000 00101010000 */
+                               /* DADDU: bits 010110 00101010000 */
+                      || dreg != 28 || sreg != 28 || treg != MIPS_T9_REGNUM)
+               this_non_prologue_insn = 1;
+             break;
+
+           case 0x8: /* POOL32B: bits 001000 */
+             op = b12s4_op (insn);
+             breg = b0s5_reg (insn >> 16);
+             reglist = sreg = b5s5_reg (insn >> 16);
+             offset = (b0s12_imm (insn) ^ 0x800) - 0x800;
+             if ((op == 0x9 || op == 0xc)
+                               /* SWP: bits 001000 1001 */
+                               /* SDP: bits 001000 1100 */
+                 && breg == MIPS_SP_REGNUM && sreg < MIPS_RA_REGNUM)
+                               /* S[DW]P reg,offset($sp) */
+               {
+                 s = 4 << ((b12s4_op (insn) & 0x4) == 0x4);
+                 set_reg_offset (gdbarch, this_cache,
+                                 sreg, sp + offset);
+                 set_reg_offset (gdbarch, this_cache,
+                                 sreg + 1, sp + offset + s);
+               }
+             else if ((op == 0xd || op == 0xf)
+                               /* SWM: bits 001000 1101 */
+                               /* SDM: bits 001000 1111 */
+                      && breg == MIPS_SP_REGNUM
+                               /* SWM reglist,offset($sp) */
+                      && ((reglist >= 1 && reglist <= 9)
+                          || (reglist >= 16 && reglist <= 25)))
+               {
+                 int sreglist = min(reglist & 0xf, 8);
+
+                 s = 4 << ((b12s4_op (insn) & 0x2) == 0x2);
+                 for (i = 0; i < sreglist; i++)
+                   set_reg_offset (gdbarch, this_cache, 16 + i, sp + s * i);
+                 if ((reglist & 0xf) > 8)
+                   set_reg_offset (gdbarch, this_cache, 30, sp + s * i++);
+                 if ((reglist & 0x10) == 0x10)
+                   set_reg_offset (gdbarch, this_cache,
+                                   MIPS_RA_REGNUM, sp + s * i++);
+               }
+             else
+               this_non_prologue_insn = 1;
+             break;
+
+           /* Record $sp/$fp adjustment.  */
+           /* Discard (D)ADDIU $gp used for PIC code.  */
+           case 0xc: /* ADDIU: bits 001100 */
+           case 0x17: /* DADDIU: bits 010111 */
+             sreg = b0s5_reg (insn >> 16);
+             dreg = b5s5_reg (insn >> 16);
+             offset = (b0s16_imm (insn) ^ 0x8000) - 0x8000;
+             if (sreg == MIPS_SP_REGNUM && dreg == MIPS_SP_REGNUM)
+                               /* (D)ADDIU $sp, imm */
+               sp_adj = offset;
+             else if (sreg == MIPS_SP_REGNUM && dreg == 30)
+                               /* (D)ADDIU $fp, $sp, imm */
+               {
+                 frame_addr = sp + offset;
+                 frame_adjust = offset;
+                 frame_reg = 30;
+               }
+             else if (sreg != 28 || dreg != 28)
+                               /* (D)ADDIU $gp, imm */
+               this_non_prologue_insn = 1;
+             break;
+
+           /* LUI $v1 is used for larger $sp adjustments.  */
+           /* Discard LUI $gp used for PIC code.  */
+           case 0x10: /* POOL32I: bits 010000 */
+             if (b5s5_op (insn >> 16) == 0xd
+                               /* LUI: bits 010000 001101 */
+                 && b0s5_reg (insn >> 16) == 3)
+                               /* LUI $v1, imm */
+               v1_off = ((b0s16_imm (insn) << 16) ^ 0x80000000) - 0x80000000;
+             else if (b5s5_op (insn >> 16) != 0xd
+                               /* LUI: bits 010000 001101 */
+                      || b0s5_reg (insn >> 16) != 28)
+                               /* LUI $gp, imm */
+               this_non_prologue_insn = 1;
+             break;
+
+           /* ORI $v1 is used for larger $sp adjustments.  */
+           case 0x14: /* ORI: bits 010100 */
+             sreg = b0s5_reg (insn >> 16);
+             dreg = b5s5_reg (insn >> 16);
+             if (sreg == 3 && dreg == 3)
+                               /* ORI $v1, imm */
+               v1_off |= b0s16_imm (insn);
+             else
+               this_non_prologue_insn = 1;
+             break;
+
+           case 0x26: /* SWC1: bits 100110 */
+           case 0x2e: /* SDC1: bits 101110 */
+             breg = b0s5_reg (insn >> 16);
+             if (breg != MIPS_SP_REGNUM)
+                               /* S[DW]C1 reg,offset($sp) */
+               this_non_prologue_insn = 1;
+             break;
+
+           case 0x36: /* SD: bits 110110 */
+           case 0x3e: /* SW: bits 111110 */
+             breg = b0s5_reg (insn >> 16);
+             sreg = b5s5_reg (insn >> 16);
+             offset = (b0s16_imm (insn) ^ 0x8000) - 0x8000;
+             if (breg == MIPS_SP_REGNUM)
+                               /* S[DW] reg,offset($sp) */
+               set_reg_offset (gdbarch, this_cache, sreg, sp + offset);
+             else
+               this_non_prologue_insn = 1;
+             break;
+
+           default:
+             /* 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.  */
+       case MIPS_INSN16_SIZE:
+         switch (micromips_op (insn))
+           {
+           case 0x3: /* MOVE: bits 000011 */
+             sreg = b0s5_reg (insn);
+             dreg = b5s5_reg (insn);
+             if (sreg == MIPS_SP_REGNUM && dreg == 30)
+                               /* MOVE  $fp, $sp */
+               {
+                 frame_addr = sp;
+                 frame_reg = 30;
+               }
+             else if ((sreg & 0x1c) != 0x4)
+                               /* MOVE  reg, $a0-$a3 */
+               this_non_prologue_insn = 1;
+             break;
+
+           case 0x11: /* POOL16C: bits 010001 */
+             if (b6s4_op (insn) == 0x5)
+                               /* SWM: bits 010001 0101 */
+               {
+                 offset = ((b0s4_imm (insn) << 2) ^ 0x20) - 0x20;
+                 reglist = b4s2_regl (insn);
+                 for (i = 0; i <= reglist; i++)
+                   set_reg_offset (gdbarch, this_cache, 16 + i, sp + 4 * i);
+                 set_reg_offset (gdbarch, this_cache,
+                                 MIPS_RA_REGNUM, sp + 4 * i++);
+               }
+             else
+               this_non_prologue_insn = 1;
+             break;
+
+           case 0x13: /* POOL16D: bits 010011 */
+             if ((insn & 0x1) == 0x1)
+                               /* ADDIUSP: bits 010011 1 */
+               sp_adj = micromips_decode_imm9 (b1s9_imm (insn));
+             else if (b5s5_reg (insn) == MIPS_SP_REGNUM)
+                               /* ADDIUS5: bits 010011 0 */
+                               /* ADDIUS5 $sp, imm */
+               sp_adj = (b1s4_imm (insn) ^ 8) - 8;
+             else
+               this_non_prologue_insn = 1;
+             break;
+
+           case 0x32: /* SWSP: bits 110010 */
+             offset = b0s5_imm (insn) << 2;
+             sreg = b5s5_reg (insn);
+             set_reg_offset (gdbarch, this_cache, sreg, sp + offset);
+             break;
+
+           default:
+             /* 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;
+       }
+      if (sp_adj < 0)
+       frame_offset -= sp_adj;
+
+      non_prologue_insns += this_non_prologue_insn;
+
+      /* 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;
+    }
+
+  if (this_cache != NULL)
+    {
+      this_cache->base =
+       (get_frame_register_signed (this_frame,
+                                   gdbarch_num_regs (gdbarch) + frame_reg)
+        + frame_offset - frame_adjust);
+      /* FIXME: brobecker/2004-10-10: Just as in the mips32 case, we should
+        be able to get rid of the assignment below, evetually. But it's
+        still needed for now.  */
+      this_cache->saved_regs[gdbarch_num_regs (gdbarch)
+                            + mips_regnum (gdbarch)->pc]
+       = this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM];
+    }
+
+  /* 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;
+}
+
+/* Heuristic unwinder for procedures using microMIPS instructions.
+   Procedures that use the 32-bit instruction set are handled by the
+   mips_insn32 unwinder.  Likewise MIPS16 and the mips_insn16 unwinder. */
+
+static struct mips_frame_cache *
+mips_micro_frame_cache (struct frame_info *this_frame, void **this_cache)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct mips_frame_cache *cache;
+
+  if ((*this_cache) != NULL)
+    return (*this_cache);
+
+  cache = FRAME_OBSTACK_ZALLOC (struct mips_frame_cache);
+  (*this_cache) = cache;
+  cache->saved_regs = trad_frame_alloc_saved_regs (this_frame);
+
+  /* Analyze the function prologue.  */
+  {
+    const CORE_ADDR pc = get_frame_address_in_block (this_frame);
+    CORE_ADDR start_addr;
+
+    find_pc_partial_function (pc, NULL, &start_addr, NULL);
+    if (start_addr == 0)
+      start_addr = heuristic_proc_start (get_frame_arch (this_frame), pc);
+    /* We can't analyze the prologue if we couldn't find the begining
+       of the function.  */
+    if (start_addr == 0)
+      return cache;
+
+    micromips_scan_prologue (gdbarch, start_addr, pc, this_frame, *this_cache);
+  }
+
+  /* gdbarch_sp_regnum contains the value and not the address.  */
+  trad_frame_set_value (cache->saved_regs,
+                       gdbarch_num_regs (gdbarch) + MIPS_SP_REGNUM,
+                       cache->base);
+
+  return (*this_cache);
+}
+
+static void
+mips_micro_frame_this_id (struct frame_info *this_frame, void **this_cache,
+                         struct frame_id *this_id)
+{
+  struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
+                                                         this_cache);
+  /* This marks the outermost frame.  */
+  if (info->base == 0)
+    return;
+  (*this_id) = frame_id_build (info->base, get_frame_func (this_frame));
+}
+
+static struct value *
+mips_micro_frame_prev_register (struct frame_info *this_frame,
+                               void **this_cache, int regnum)
+{
+  struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
+                                                         this_cache);
+  return trad_frame_get_prev_register (this_frame, info->saved_regs, regnum);
+}
+
+static int
+mips_micro_frame_sniffer (const struct frame_unwind *self,
+                         struct frame_info *this_frame, void **this_cache)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  CORE_ADDR pc = get_frame_pc (this_frame);
+
+  if (mips_pc_is_micromips (gdbarch, pc))
+    return 1;
+  return 0;
+}
+
+static const struct frame_unwind mips_micro_frame_unwind =
+{
+  NORMAL_FRAME,
+  default_frame_unwind_stop_reason,
+  mips_micro_frame_this_id,
+  mips_micro_frame_prev_register,
+  NULL,
+  mips_micro_frame_sniffer
+};
+
+static CORE_ADDR
+mips_micro_frame_base_address (struct frame_info *this_frame,
+                              void **this_cache)
+{
+  struct mips_frame_cache *info = mips_micro_frame_cache (this_frame,
+                                                         this_cache);
+  return info->base;
+}
+
+static const struct frame_base mips_micro_frame_base =
+{
+  &mips_micro_frame_unwind,
+  mips_micro_frame_base_address,
+  mips_micro_frame_base_address,
+  mips_micro_frame_base_address
+};
+
+static const struct frame_base *
+mips_micro_frame_base_sniffer (struct frame_info *this_frame)
+{
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  CORE_ADDR pc = get_frame_pc (this_frame);
+
+  if (mips_pc_is_micromips (gdbarch, pc))
+    return &mips_micro_frame_base;
+  else
+    return NULL;
+}
+
 /* Mark all the registers as unset in the saved_regs array
    of THIS_CACHE.  Do nothing if THIS_CACHE is null.  */
 
@@ -2202,17 +3395,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
@@ -2228,27 +3426,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, cur_pc);
+      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
@@ -2259,19 +3469,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;
@@ -2279,8 +3489,9 @@ restart:
              frame_reg = 30;
              frame_addr = get_frame_register_signed
                (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
@@ -2329,7 +3540,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) */
@@ -2349,6 +3560,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 */
@@ -2357,31 +3569,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)
@@ -2399,14 +3612,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
@@ -2420,7 +3631,7 @@ restart:
 /* Heuristic unwinder for procedures using 32-bit instructions (covers
    both 32-bit and 64-bit MIPS ISAs).  Procedures using 16-bit
    instructions (a.k.a. MIPS16) are handled by the mips_insn16
-   unwinder.  */
+   unwinder.  Likewise microMIPS and the mips_micro unwinder. */
 
 static struct mips_frame_cache *
 mips_insn32_frame_cache (struct frame_info *this_frame, void **this_cache)
@@ -2485,7 +3696,7 @@ mips_insn32_frame_sniffer (const struct frame_unwind *self,
                           struct frame_info *this_frame, void **this_cache)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
-  if (! mips_pc_is_mips16 (pc))
+  if (mips_pc_is_mips (pc))
     return 1;
   return 0;
 }
@@ -2521,7 +3732,7 @@ static const struct frame_base *
 mips_insn32_frame_base_sniffer (struct frame_info *this_frame)
 {
   CORE_ADDR pc = get_frame_pc (this_frame);
-  if (! mips_pc_is_mips16 (pc))
+  if (mips_pc_is_mips (pc))
     return &mips_insn32_frame_base;
   else
     return NULL;
@@ -2587,29 +3798,21 @@ mips_stub_frame_sniffer (const struct frame_unwind *self,
   gdb_byte dummy[4];
   struct obj_section *s;
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
-  struct minimal_symbol *msym;
+  struct bound_minimal_symbol msym;
 
   /* Use the stub unwinder for unreadable code.  */
   if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
     return 1;
 
-  if (in_plt_section (pc, NULL))
-    return 1;
-
-  /* Binutils for MIPS puts lazy resolution stubs into .MIPS.stubs.  */
-  s = find_pc_section (pc);
-
-  if (s != NULL
-      && strcmp (bfd_get_section_name (s->objfile->obfd, s->the_bfd_section),
-                ".MIPS.stubs") == 0)
+  if (in_plt_section (pc) || in_mips_stubs_section (pc))
     return 1;
 
   /* Calling a PIC function from a non-PIC function passes through a
      stub.  The stub for foo is named ".pic.foo".  */
   msym = lookup_minimal_symbol_by_pc (pc);
-  if (msym != NULL
-      && SYMBOL_LINKAGE_NAME (msym) != NULL
-      && strncmp (SYMBOL_LINKAGE_NAME (msym), ".pic.", 5) == 0)
+  if (msym.minsym != NULL
+      && MSYMBOL_LINKAGE_NAME (msym.minsym) != NULL
+      && startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic."))
     return 1;
 
   return 0;
@@ -2658,9 +3861,6 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  if (is_mips16_addr (addr))
-    addr = unmake_mips16_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
@@ -2682,34 +3882,33 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
     return addr;
 }
 
-/* Instructions used during single-stepping of atomic sequences.  */
-#define LL_OPCODE 0x30
-#define LLD_OPCODE 0x34
-#define SC_OPCODE 0x38
-#define SCD_OPCODE 0x3c
 
 /* Checks for an atomic sequence of instructions beginning with a LL/LLD
    instruction and ending with a SC/SCD instruction.  If such a sequence
    is found, attempt to step through it.  A breakpoint is placed at the end of 
    the sequence.  */
 
+/* Instructions used during single-stepping of atomic sequences, standard
+   ISA version.  */
+#define LL_OPCODE 0x30
+#define LLD_OPCODE 0x34
+#define SC_OPCODE 0x38
+#define SCD_OPCODE 0x3c
+
 static int
-deal_with_atomic_sequence (struct gdbarch *gdbarch,
-                          struct address_space *aspace, CORE_ADDR pc)
+mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
+                               struct address_space *aspace, CORE_ADDR pc)
 {
   CORE_ADDR breaks[2] = {-1, -1};
   CORE_ADDR loc = pc;
   CORE_ADDR branch_bp; /* Breakpoint at branch instruction's destination.  */
-  unsigned long insn;
+  ULONGEST insn;
   int insn_count;
   int index;
   int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */  
   const int atomic_sequence_length = 16; /* Instruction sequence length.  */
 
-  if (pc & 0x01)
-    return 0;
-
-  insn = mips_fetch_instruction (gdbarch, loc);
+  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;
@@ -2720,7 +3919,7 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch,
     {
       int is_branch = 0;
       loc += MIPS_INSN32_SIZE;
-      insn = mips_fetch_instruction (gdbarch, loc);
+      insn = mips_fetch_instruction (gdbarch, ISA_MIPS, loc, NULL);
 
       /* Assume that there is at most one branch in the atomic
         sequence.  If a branch is found, put a breakpoint in its
@@ -2736,55 +3935,215 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch,
                       || ((itype_rt (insn) & 0x1e) == 0
                           && itype_rs (insn) == 0)); /* BPOSGE* */
          break;
-       case 2: /* J */
-       case 3: /* JAL */
-         return 0; /* fallback to the standard single-step code.  */
-       case 4: /* BEQ */
-       case 5: /* BNE */
-       case 6: /* BLEZ */
-       case 7: /* BGTZ */
-       case 20: /* BEQL */
-       case 21: /* BNEL */
-       case 22: /* BLEZL */
-       case 23: /* BGTTL */
-         is_branch = 1;
+       case 2: /* J */
+       case 3: /* JAL */
+         return 0; /* fallback to the standard single-step code.  */
+       case 4: /* BEQ */
+       case 5: /* BNE */
+       case 6: /* BLEZ */
+       case 7: /* BGTZ */
+       case 20: /* BEQL */
+       case 21: /* BNEL */
+       case 22: /* BLEZL */
+       case 23: /* BGTTL */
+         is_branch = 1;
+         break;
+       case 17: /* COP1 */
+         is_branch = ((itype_rs (insn) == 9 || itype_rs (insn) == 10)
+                      && (itype_rt (insn) & 0x2) == 0);
+         if (is_branch) /* BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T */
+           break;
+       /* Fall through.  */
+       case 18: /* COP2 */
+       case 19: /* COP3 */
+         is_branch = (itype_rs (insn) == 8); /* BCzF, BCzFL, BCzT, BCzTL */
+         break;
+       }
+      if (is_branch)
+       {
+         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.  */
+         breaks[1] = branch_bp;
+         last_breakpoint++;
+       }
+
+      if (itype_op (insn) == SC_OPCODE || itype_op (insn) == SCD_OPCODE)
+       break;
+    }
+
+  /* Assume that the atomic sequence ends with a sc/scd instruction.  */
+  if (itype_op (insn) != SC_OPCODE && itype_op (insn) != SCD_OPCODE)
+    return 0;
+
+  loc += MIPS_INSN32_SIZE;
+
+  /* Insert a breakpoint right after the end of the atomic sequence.  */
+  breaks[0] = loc;
+
+  /* Check for duplicated breakpoints.  Check also for a breakpoint
+     placed (branch instruction's destination) in the atomic sequence.  */
+  if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
+    last_breakpoint = 0;
+
+  /* Effectively inserts the breakpoints.  */
+  for (index = 0; index <= last_breakpoint; index++)
+    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+
+  return 1;
+}
+
+static int
+micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
+                                    struct address_space *aspace,
+                                    CORE_ADDR pc)
+{
+  const int atomic_sequence_length = 16; /* Instruction sequence length.  */
+  int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed).  */
+  CORE_ADDR breaks[2] = {-1, -1};
+  CORE_ADDR branch_bp = 0; /* Breakpoint at branch instruction's
+                             destination.  */
+  CORE_ADDR loc = pc;
+  int sc_found = 0;
+  ULONGEST insn;
+  int insn_count;
+  int index;
+
+  /* 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;
+  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;
+  loc += MIPS_INSN16_SIZE;
+
+  /* Assume all atomic sequences end with an sc/scd instruction.  Assume
+     that no atomic sequence is longer than "atomic_sequence_length"
+     instructions.  */
+  for (insn_count = 0;
+       !sc_found && insn_count < atomic_sequence_length;
+       ++insn_count)
+    {
+      int is_branch = 0;
+
+      insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
+      loc += MIPS_INSN16_SIZE;
+
+      /* Assume that there is at most one conditional branch in the
+         atomic sequence.  If a branch is found, put a breakpoint in
+         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))
+           {
+           case 0x10: /* POOL32I: bits 010000 */
+             if ((b5s5_op (insn) & 0x18) != 0x0
+                               /* BLTZ, BLTZAL, BGEZ, BGEZAL: 010000 000xx */
+                               /* BLEZ, BNEZC, BGTZ, BEQZC: 010000 001xx */
+                 && (b5s5_op (insn) & 0x1d) != 0x11
+                               /* BLTZALS, BGEZALS: bits 010000 100x1 */
+                 && ((b5s5_op (insn) & 0x1e) != 0x14
+                     || (insn & 0x3) != 0x0)
+                               /* BC2F, BC2T: bits 010000 1010x xxx00 */
+                 && (b5s5_op (insn) & 0x1e) != 0x1a
+                               /* BPOSGE64, BPOSGE32: bits 010000 1101x */
+                 && ((b5s5_op (insn) & 0x1e) != 0x1c
+                     || (insn & 0x3) != 0x0)
+                               /* BC1F, BC1T: bits 010000 1110x xxx00 */
+                 && ((b5s5_op (insn) & 0x1c) != 0x1c
+                     || (insn & 0x3) != 0x1))
+                               /* BC1ANY*: bits 010000 111xx xxx01 */
+               break;
+             /* Fall through.  */
+
+           case 0x25: /* BEQ: bits 100101 */
+           case 0x2d: /* BNE: bits 101101 */
+             insn <<= 16;
+             insn |= mips_fetch_instruction (gdbarch,
+                                             ISA_MICROMIPS, loc, NULL);
+             branch_bp = (loc + MIPS_INSN16_SIZE
+                          + micromips_relative_offset16 (insn));
+             is_branch = 1;
+             break;
+
+           case 0x00: /* POOL32A: bits 000000 */
+             insn <<= 16;
+             insn |= mips_fetch_instruction (gdbarch,
+                                             ISA_MICROMIPS, loc, NULL);
+             if (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 */
+               break;
+             /* Fall through.  */
+
+           case 0x1d: /* JALS: bits 011101 */
+           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. */
+
+           case 0x18: /* POOL32C: bits 011000 */
+             if ((b12s4_op (insn) & 0xb) == 0xb)
+                               /* SC, SCD: bits 011000 1x11 */
+               sc_found = 1;
+             break;
+           }
+         loc += MIPS_INSN16_SIZE;
          break;
-       case 17: /* COP1 */
-         is_branch = ((itype_rs (insn) == 9 || itype_rs (insn) == 10)
-                      && (itype_rt (insn) & 0x2) == 0);
-         if (is_branch) /* BC1ANY2F, BC1ANY2T, BC1ANY4F, BC1ANY4T */
-           break;
-       /* Fall through.  */
-       case 18: /* COP2 */
-       case 19: /* COP3 */
-         is_branch = (itype_rs (insn) == 8); /* BCzF, BCzFL, BCzT, BCzTL */
+
+       /* 16-bit instructions.  */
+       case MIPS_INSN16_SIZE:
+         switch (micromips_op (insn))
+           {
+           case 0x23: /* BEQZ16: bits 100011 */
+           case 0x2b: /* BNEZ16: bits 101011 */
+             branch_bp = loc + micromips_relative_offset7 (insn);
+             is_branch = 1;
+             break;
+
+           case 0x11: /* POOL16C: bits 010001 */
+             if ((b5s5_op (insn) & 0x1c) != 0xc
+                               /* JR16, JRC, JALR16, JALRS16: 010001 011xx */
+                 && b5s5_op (insn) != 0x18)
+                               /* JRADDIUSP: bits 010001 11000 */
+               break;
+             return 0; /* Fall back to the standard single-step code. */
+
+           case 0x33: /* B16: bits 110011 */
+             return 0; /* Fall back to the standard single-step code. */
+           }
          break;
        }
       if (is_branch)
        {
-         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.  */
          breaks[1] = branch_bp;
          last_breakpoint++;
        }
-
-      if (itype_op (insn) == SC_OPCODE || itype_op (insn) == SCD_OPCODE)
-       break;
     }
-
-  /* Assume that the atomic sequence ends with a sc/scd instruction.  */
-  if (itype_op (insn) != SC_OPCODE && itype_op (insn) != SCD_OPCODE)
+  if (!sc_found)
     return 0;
 
-  loc += MIPS_INSN32_SIZE;
-
   /* Insert a breakpoint right after the end of the atomic sequence.  */
   breaks[0] = loc;
 
   /* Check for duplicated breakpoints.  Check also for a breakpoint
-     placed (branch instruction's destination) in the atomic sequence */
+     placed (branch instruction's destination) in the atomic sequence */
   if (last_breakpoint && pc <= breaks[1] && breaks[1] <= breaks[0])
     last_breakpoint = 0;
 
@@ -2795,6 +4154,18 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch,
   return 1;
 }
 
+static int
+deal_with_atomic_sequence (struct gdbarch *gdbarch,
+                          struct address_space *aspace, CORE_ADDR pc)
+{
+  if (mips_pc_is_mips (pc))
+    return mips_deal_with_atomic_sequence (gdbarch, aspace, pc);
+  else if (mips_pc_is_micromips (gdbarch, pc))
+    return micromips_deal_with_atomic_sequence (gdbarch, aspace, pc);
+  else
+    return 0;
+}
+
 /* mips_software_single_step() is called just before we want to resume
    the inferior, if we want to single-step it but there is no hardware
    or kernel single-step support (MIPS on GNU/Linux for example).  We find
@@ -2827,10 +4198,10 @@ mips_about_to_return (struct gdbarch *gdbarch, CORE_ADDR pc)
   ULONGEST hint;
 
   /* This used to check for MIPS16, but this piece of code is never
-     called for MIPS16 functions.  */
-  gdb_assert (!mips_pc_is_mips16 (pc));
+     called for MIPS16 functions.  And likewise microMIPS ones.  */
+  gdb_assert (mips_pc_is_mips (pc));
 
-  insn = mips_fetch_instruction (gdbarch, pc);
+  insn = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
   hint = 0x7c0;
   return (insn & ~hint) == 0x3e00008;                  /* jr(.hb) $ra */
 }
@@ -2855,10 +4226,10 @@ heuristic_proc_start (struct gdbarch *gdbarch, CORE_ADDR pc)
   if (start_pc == 0)
     return 0;
 
-  if (heuristic_fence_post == UINT_MAX || fence < VM_MIN_ADDRESS)
+  if (heuristic_fence_post == -1 || fence < VM_MIN_ADDRESS)
     fence = VM_MIN_ADDRESS;
 
-  instlen = mips_pc_is_mips16 (pc) ? MIPS_INSN16_SIZE : MIPS_INSN32_SIZE;
+  instlen = mips_pc_is_mips (pc) ? MIPS_INSN32_SIZE : MIPS_INSN16_SIZE;
 
   inf = current_inferior ();
 
@@ -2903,7 +4274,7 @@ heuristic-fence-post' command.\n",
 
        return 0;
       }
-    else if (mips_pc_is_mips16 (start_pc))
+    else if (mips_pc_is_mips16 (gdbarch, start_pc))
       {
        unsigned short inst;
 
@@ -2915,12 +4286,13 @@ heuristic-fence-post' command.\n",
           addiu sp,-n
           daddiu sp,-n
           extend -n followed by 'addiu sp,+n' or 'daddiu sp,+n'.  */
-       inst = mips_fetch_instruction (gdbarch, start_pc);
+       inst = mips_fetch_instruction (gdbarch, ISA_MIPS16, start_pc, NULL);
        if ((inst & 0xff80) == 0x6480)          /* save */
          {
            if (start_pc - instlen >= fence)
              {
-               inst = mips_fetch_instruction (gdbarch, start_pc - instlen);
+               inst = mips_fetch_instruction (gdbarch, ISA_MIPS16,
+                                              start_pc - instlen, NULL);
                if ((inst & 0xf800) == 0xf000)  /* extend */
                  start_pc -= instlen;
              }
@@ -2938,6 +4310,67 @@ heuristic-fence-post' command.\n",
        else
          seen_adjsp = 0;
       }
+    else if (mips_pc_is_micromips (gdbarch, start_pc))
+      {
+       ULONGEST insn;
+       int stop = 0;
+       long offset;
+       int dreg;
+       int sreg;
+
+       /* On microMIPS, any one of the following is likely to be the
+          start of a function:
+          ADDIUSP -imm
+          (D)ADDIU $sp, -imm
+          LUI $gp, imm  */
+       insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
+       switch (micromips_op (insn))
+         {
+         case 0xc: /* ADDIU: bits 001100 */
+         case 0x17: /* DADDIU: bits 010111 */
+           sreg = b0s5_reg (insn);
+           dreg = b5s5_reg (insn);
+           insn <<= 16;
+           insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS,
+                                           pc + MIPS_INSN16_SIZE, NULL);
+           offset = (b0s16_imm (insn) ^ 0x8000) - 0x8000;
+           if (sreg == MIPS_SP_REGNUM && dreg == MIPS_SP_REGNUM
+                               /* (D)ADDIU $sp, imm */
+               && offset < 0)
+             stop = 1;
+           break;
+
+         case 0x10: /* POOL32I: bits 010000 */
+           if (b5s5_op (insn) == 0xd
+                               /* LUI: bits 010000 001101 */
+               && b0s5_reg (insn >> 16) == 28)
+                               /* LUI $gp, imm */
+             stop = 1;
+           break;
+
+         case 0x13: /* POOL16D: bits 010011 */
+           if ((insn & 0x1) == 0x1)
+                               /* ADDIUSP: bits 010011 1 */
+             {
+               offset = micromips_decode_imm9 (b1s9_imm (insn));
+               if (offset < 0)
+                               /* ADDIUSP -imm */
+                 stop = 1;
+             }
+           else
+                               /* ADDIUS5: bits 010011 0 */
+             {
+               dreg = b5s5_reg (insn);
+               offset = (b1s4_imm (insn) ^ 8) - 8;
+               if (dreg == MIPS_SP_REGNUM && offset < 0)
+                               /* ADDIUS5  $sp, -imm */
+                 stop = 1;
+             }
+           break;
+         }
+       if (stop)
+         break;
+      }
     else if (mips_about_to_return (gdbarch, start_pc))
       {
        /* Skip return and its delay slot.  */
@@ -3020,11 +4453,18 @@ mips_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
                      CORE_ADDR *real_pc, CORE_ADDR *bp_addr,
                      struct regcache *regcache)
 {
-  CORE_ADDR nop_addr;
   static gdb_byte nop_insn[] = { 0, 0, 0, 0 };
+  CORE_ADDR nop_addr;
+  CORE_ADDR bp_slot;
 
   /* Reserve enough room on the stack for our breakpoint instruction.  */
-  *bp_addr = sp - sizeof (nop_insn);
+  bp_slot = sp - sizeof (nop_insn);
+
+  /* Return to microMIPS mode if calling microMIPS code to avoid
+     triggering an address error exception on processors that only
+     support microMIPS execution.  */
+  *bp_addr = (mips_pc_is_micromips (gdbarch, funaddr)
+             ? make_compact_addr (bp_slot) : bp_slot);
 
   /* The breakpoint layer automatically adjusts the address of
      breakpoints inserted in a branch delay slot.  With enough
@@ -3033,7 +4473,7 @@ mips_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
      trigger the adjustement, and break the function call entirely.
      So, we reserve those 4 bytes and write a nop instruction
      to prevent that from happening.  */
-  nop_addr = *bp_addr - sizeof (nop_insn);
+  nop_addr = bp_slot - sizeof (nop_insn);
   write_memory (nop_addr, nop_insn, sizeof (nop_insn));
   sp = mips_frame_align (gdbarch, nop_addr);
 
@@ -3054,7 +4494,6 @@ mips_eabi_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int argnum;
   int len = 0;
   int stack_offset = 0;
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR func_addr = find_function_addr (function, NULL);
   int regsize = mips_abi_regsize (gdbarch);
@@ -3120,25 +4559,9 @@ 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_mips16 (addr))
-           {
-             store_signed_integer (valbuf, len, byte_order, 
-                                   make_mips16_addr (addr));
-             val = valbuf;
-           }
-         else
-           val = value_contents (arg);
-       }
       /* The EABI passes structures that do not fit in a register by
          reference.  */
-      else if (len > regsize
+      if (len > regsize
          && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
        {
          store_unsigned_integer (valbuf, regsize, byte_order,
@@ -3462,7 +4885,6 @@ mips_n32n64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int argnum;
   int len = 0;
   int stack_offset = 0;
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR func_addr = find_function_addr (function, NULL);
 
@@ -3919,7 +5341,6 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int argnum;
   int len = 0;
   int stack_offset = 0;
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR func_addr = find_function_addr (function, NULL);
 
@@ -3944,13 +5365,12 @@ mips_o32_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       struct type *arg_type = check_typedef (value_type (args[argnum]));
-      int arglen = TYPE_LENGTH (arg_type);
 
       /* Align to double-word if necessary.  */
       if (mips_type_needs_double_align (arg_type))
        len = align_up (len, MIPS32_REGSIZE * 2);
       /* Allocate space on the stack.  */
-      len += align_up (arglen, MIPS32_REGSIZE);
+      len += align_up (TYPE_LENGTH (arg_type), MIPS32_REGSIZE);
     }
   sp -= align_up (len, 16);
 
@@ -4226,8 +5646,8 @@ mips_o32_return_value (struct gdbarch *gdbarch, struct value *function,
                       gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   CORE_ADDR func_addr = function ? find_function_addr (function, NULL) : 0;
+  int mips16 = mips_pc_is_mips16 (gdbarch, func_addr);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int mips16 = mips_pc_is_mips16 (func_addr);
   enum mips_fval_reg fval_reg;
 
   fval_reg = readbuf ? mips16 ? mips_fval_gpr : mips_fval_fpr : mips_fval_both;
@@ -4449,7 +5869,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   int argnum;
   int len = 0;
   int stack_offset = 0;
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR func_addr = find_function_addr (function, NULL);
 
@@ -4474,10 +5893,9 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       struct type *arg_type = check_typedef (value_type (args[argnum]));
-      int arglen = TYPE_LENGTH (arg_type);
 
       /* Allocate space on the stack.  */
-      len += align_up (arglen, MIPS64_REGSIZE);
+      len += align_up (TYPE_LENGTH (arg_type), MIPS64_REGSIZE);
     }
   sp -= align_up (len, 16);
 
@@ -4508,7 +5926,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);
@@ -4521,21 +5938,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_mips16 (addr))
-           {
-             store_signed_integer (valbuf, len, byte_order, 
-                                   make_mips16_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
@@ -4694,8 +6096,8 @@ mips_o64_return_value (struct gdbarch *gdbarch, struct value *function,
                       gdb_byte *readbuf, const gdb_byte *writebuf)
 {
   CORE_ADDR func_addr = function ? find_function_addr (function, NULL) : 0;
+  int mips16 = mips_pc_is_mips16 (gdbarch, func_addr);
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int mips16 = mips_pc_is_mips16 (func_addr);
   enum mips_fval_reg fval_reg;
 
   fval_reg = readbuf ? mips16 ? mips_fval_gpr : mips_fval_fpr : mips_fval_both;
@@ -4805,7 +6207,7 @@ mips_read_fp_register_single (struct frame_info *frame, int regno,
   int raw_size = register_size (gdbarch, regno);
   gdb_byte *raw_buffer = alloca (raw_size);
 
-  if (!frame_register_read (frame, regno, raw_buffer))
+  if (!deprecated_frame_register_read (frame, regno, raw_buffer))
     error (_("can't read register %d (%s)"),
           regno, gdbarch_register_name (gdbarch, regno));
   if (raw_size == 8)
@@ -4842,7 +6244,7 @@ mips_read_fp_register_double (struct frame_info *frame, int regno,
     {
       /* We have a 64-bit value for this register, and we should use
          all 64 bits.  */
-      if (!frame_register_read (frame, regno, rare_buffer))
+      if (!deprecated_frame_register_read (frame, regno, rare_buffer))
        error (_("can't read register %d (%s)"),
               regno, gdbarch_register_name (gdbarch, regno));
     }
@@ -4968,12 +6370,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);
 
@@ -4994,6 +6390,94 @@ mips_print_register (struct ui_file *file, struct frame_info *frame,
                              &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.  */
 
@@ -5075,7 +6559,7 @@ 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 (!frame_register_read (frame, regnum, raw_buffer))
+      if (!deprecated_frame_register_read (frame, regnum, raw_buffer))
        error (_("can't read register %d (%s)"),
               regnum, gdbarch_register_name (gdbarch, regnum));
       /* pad small registers */
@@ -5137,42 +6621,32 @@ mips_print_registers_info (struct gdbarch *gdbarch, struct ui_file *file,
     }
 }
 
-/* Is this a branch with a delay slot?  */
-
-static int
-is_delayed (unsigned long insn)
-{
-  int i;
-  for (i = 0; i < NUMOPCODES; ++i)
-    if (mips_opcodes[i].pinfo != INSN_MACRO
-       && (insn & mips_opcodes[i].mask) == mips_opcodes[i].match)
-      break;
-  return (i < NUMOPCODES
-         && (mips_opcodes[i].pinfo & (INSN_UNCOND_BRANCH_DELAY
-                                      | INSN_COND_BRANCH_DELAY
-                                      | INSN_COND_BRANCH_LIKELY)));
-}
-
 static int
 mips_single_step_through_delay (struct gdbarch *gdbarch,
                                struct frame_info *frame)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   CORE_ADDR pc = get_frame_pc (frame);
-  gdb_byte buf[MIPS_INSN32_SIZE];
-
-  /* There is no branch delay slot on MIPS16.  */
-  if (mips_pc_is_mips16 (pc))
-    return 0;
-
-  if (!breakpoint_here_p (get_frame_address_space (frame), pc + 4))
+  struct address_space *aspace;
+  enum mips_isa isa;
+  ULONGEST insn;
+  int status;
+  int size;
+
+  if ((mips_pc_is_mips (pc)
+       && !mips32_insn_at_pc_has_delay_slot (gdbarch, pc))
+      || (mips_pc_is_micromips (gdbarch, pc)
+         && !micromips_insn_at_pc_has_delay_slot (gdbarch, pc, 0))
+      || (mips_pc_is_mips16 (gdbarch, pc)
+         && !mips16_insn_at_pc_has_delay_slot (gdbarch, pc, 0)))
     return 0;
 
-  if (!safe_frame_unwind_memory (frame, pc, buf, sizeof buf))
-    /* If error reading memory, guess that it is not a delayed
-       branch.  */
-    return 0;
-  return is_delayed (extract_unsigned_integer (buf, sizeof buf, byte_order));
+  isa = mips_pc_isa (gdbarch, pc);
+  /* _has_delay_slot above will have validated the read.  */
+  insn = mips_fetch_instruction (gdbarch, isa, pc, NULL);
+  size = mips_insn_size (isa, insn);
+  aspace = get_frame_address_space (frame);
+  return breakpoint_here_p (aspace, pc + size) != no_breakpoint_here;
 }
 
 /* To skip prologues, I use this predicate.  Returns either PC itself
@@ -5211,8 +6685,10 @@ mips_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc)
   if (limit_pc == 0)
     limit_pc = pc + 100;          /* Magic.  */
 
-  if (mips_pc_is_mips16 (pc))
+  if (mips_pc_is_mips16 (gdbarch, pc))
     return mips16_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
+  else if (mips_pc_is_micromips (gdbarch, pc))
+    return micromips_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
   else
     return mips32_scan_prologue (gdbarch, pc, limit_pc, NULL, NULL);
 }
@@ -5239,7 +6715,7 @@ mips32_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
          unsigned long high_word;
          unsigned long inst;
 
-         inst = mips_fetch_instruction (gdbarch, pc);
+         inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
          high_word = (inst >> 16) & 0xffff;
 
          if (high_word != 0x27bd       /* addiu $sp,$sp,offset */
@@ -5255,6 +6731,107 @@ 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.  */
+
+static int
+micromips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  CORE_ADDR func_addr = 0;
+  CORE_ADDR func_end = 0;
+  CORE_ADDR addr;
+  ULONGEST insn;
+  long offset;
+  int dreg;
+  int sreg;
+  int loc;
+
+  if (!find_pc_partial_function (pc, NULL, &func_addr, &func_end))
+    return 0;
+
+  /* The microMIPS epilogue is max. 12 bytes long.  */
+  addr = func_end - 12;
+
+  if (addr < func_addr + 2)
+    addr = func_addr + 2;
+  if (pc < addr)
+    return 0;
+
+  for (; pc < func_end; pc += loc)
+    {
+      loc = 0;
+      insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, pc, NULL);
+      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;
+         insn |= mips_fetch_instruction (gdbarch,
+                                         ISA_MICROMIPS, pc + loc, NULL);
+         loc += MIPS_INSN16_SIZE;
+         switch (micromips_op (insn >> 16))
+           {
+           case 0xc: /* ADDIU: bits 001100 */
+           case 0x17: /* DADDIU: bits 010111 */
+             sreg = b0s5_reg (insn >> 16);
+             dreg = b5s5_reg (insn >> 16);
+             offset = (b0s16_imm (insn) ^ 0x8000) - 0x8000;
+             if (sreg == MIPS_SP_REGNUM && dreg == MIPS_SP_REGNUM
+                           /* (D)ADDIU $sp, imm */
+                 && offset >= 0)
+               break;
+             return 0;
+
+           default:
+             return 0;
+           }
+         break;
+
+       /* 16-bit instructions.  */
+       case MIPS_INSN16_SIZE:
+         switch (micromips_op (insn))
+           {
+           case 0x3: /* MOVE: bits 000011 */
+             sreg = b0s5_reg (insn);
+             dreg = b5s5_reg (insn);
+             if (sreg == 0 && dreg == 0)
+                               /* MOVE $zero, $zero aka NOP */
+               break;
+             return 0;
+
+           case 0x11: /* POOL16C: bits 010001 */
+             if (b5s5_op (insn) == 0x18
+                               /* JRADDIUSP: bits 010011 11000 */
+                 || (b5s5_op (insn) == 0xd
+                               /* JRC: bits 010011 01101 */
+                     && b0s5_reg (insn) == MIPS_RA_REGNUM))
+                               /* JRC $ra */
+               break;
+             return 0;
+
+           case 0x13: /* POOL16D: bits 010011 */
+             offset = micromips_decode_imm9 (b1s9_imm (insn));
+             if ((insn & 0x1) == 0x1
+                               /* ADDIUSP: bits 010011 1 */
+                 && offset > 0)
+               break;
+             return 0;
+
+           default:
+             return 0;
+           }
+       }
+    }
+
+  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.  */
 static int
@@ -5276,7 +6853,7 @@ mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
        {
          unsigned short inst;
 
-         inst = mips_fetch_instruction (gdbarch, pc);
+         inst = mips_fetch_instruction (gdbarch, ISA_MIPS16, pc, NULL);
 
          if ((inst & 0xf800) == 0xf000)        /* extend */
            continue;
@@ -5300,8 +6877,10 @@ mips16_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 static int
 mips_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
-  if (mips_pc_is_mips16 (pc))
+  if (mips_pc_is_mips16 (gdbarch, pc))
     return mips16_in_function_epilogue_p (gdbarch, pc);
+  else if (mips_pc_is_micromips (gdbarch, pc))
+    return micromips_in_function_epilogue_p (gdbarch, pc);
   else
     return mips32_in_function_epilogue_p (gdbarch, pc);
 }
@@ -5330,7 +6909,7 @@ show_mipsfpu_command (char *args, int from_tty)
 {
   char *fpu;
 
-  if (gdbarch_bfd_arch_info (target_gdbarch)->arch != bfd_arch_mips)
+  if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_mips)
     {
       printf_unfiltered
        ("The MIPS floating-point coprocessor is unknown "
@@ -5338,7 +6917,7 @@ show_mipsfpu_command (char *args, int from_tty)
       return;
     }
 
-  switch (MIPS_FPU_TYPE (target_gdbarch))
+  switch (MIPS_FPU_TYPE (target_gdbarch ()))
     {
     case MIPS_FPU_SINGLE:
       fpu = "single-precision";
@@ -5450,15 +7029,20 @@ 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;
+
   /* FIXME: cagney/2003-06-26: Is this even necessary?  The
      disassembler needs to be able to locally determine the ISA, and
      not rely on GDB.  Otherwize the stand-alone 'objdump -d' will not
      work.  */
-  if (mips_pc_is_mips16 (memaddr))
+  if (mips_pc_is_mips16 (gdbarch, memaddr))
     info->mach = bfd_mach_mips16;
+  else if (mips_pc_is_micromips (gdbarch, memaddr))
+    info->mach = bfd_mach_mips_micromips;
 
   /* Round down the instruction address to the appropriate boundary.  */
-  memaddr &= (info->mach == bfd_mach_mips16 ? ~1 : ~3);
+  memaddr &= (info->mach == bfd_mach_mips16
+             || info->mach == bfd_mach_mips_micromips) ? ~1 : ~3;
 
   /* Set the disassembler options.  */
   if (!info->disassembler_options)
@@ -5509,15 +7093,33 @@ static const gdb_byte *
 mips_breakpoint_from_pc (struct gdbarch *gdbarch,
                         CORE_ADDR *pcptr, int *lenptr)
 {
+  CORE_ADDR pc = *pcptr;
+
   if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
     {
-      if (mips_pc_is_mips16 (*pcptr))
+      if (mips_pc_is_mips16 (gdbarch, pc))
        {
          static gdb_byte mips16_big_breakpoint[] = { 0xe8, 0xa5 };
-         *pcptr = unmake_mips16_addr (*pcptr);
+         *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
@@ -5546,13 +7148,29 @@ mips_breakpoint_from_pc (struct gdbarch *gdbarch,
     }
   else
     {
-      if (mips_pc_is_mips16 (*pcptr))
+      if (mips_pc_is_mips16 (gdbarch, pc))
        {
          static gdb_byte mips16_little_breakpoint[] = { 0xa5, 0xe8 };
-         *pcptr = unmake_mips16_addr (*pcptr);
+         *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;
+       }
       else
        {
          static gdb_byte little_breakpoint[] = { 0xd, 0, 0x5, 0 };
@@ -5573,31 +7191,61 @@ mips_breakpoint_from_pc (struct gdbarch *gdbarch,
     }
 }
 
-/* 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.  */
+/* Determine the remote breakpoint kind suitable for the PC.  The following
+   kinds are used:
+
+   * 2 -- 16-bit MIPS16 mode breakpoint,
+
+   * 3 -- 16-bit microMIPS mode breakpoint,
+
+   * 4 -- 32-bit standard MIPS mode breakpoint,
+
+   * 5 -- 32-bit microMIPS mode breakpoint.  */
+
+static void
+mips_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
+                               int *kindptr)
+{
+  CORE_ADDR pc = *pcptr;
+
+  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;
+
+      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;
+}
+
+/* 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)
 {
-  gdb_byte buf[MIPS_INSN32_SIZE];
-  unsigned long inst;
-  int status;
   int op;
   int rs;
   int rt;
 
-  status = target_read_memory (addr, buf, MIPS_INSN32_SIZE);
-  if (status)
-    return 0;
-
-  inst = mips_fetch_instruction (gdbarch, addr);
   op = itype_op (inst);
   if ((inst & 0xe0000000) != 0)
     {
       rs = itype_rs (inst);
       rt = itype_rt (inst);
-      return (op >> 2 == 5     /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx  */
+      return (is_octeon_bbit_op (op, gdbarch) 
+             || op >> 2 == 5   /* BEQL, BNEL, BLEZL, BGTZL: bits 0101xx  */
              || op == 29       /* JALX: bits 011101  */
              || (op == 17
                  && (rs == 8
@@ -5630,28 +7278,139 @@ 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
+mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
+{
+  ULONGEST insn;
+  int status;
+
+  insn = mips_fetch_instruction (gdbarch, ISA_MIPS, addr, &status);
+  if (status)
+    return 0;
+
+  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 (major) & 0x1e) == 0xe)));
+                               /* JALR16, JALRS16: bits 010001 0111x */
+    /* 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 (major) & 0x1d) == 0x4
+                               /* BLEZ, BGTZ: bits 010000 001x0 */
+             || (b5s5_op (major) & 0x1d) == 0x11
+                               /* BLTZALS, BGEZALS: bits 010000 100x1 */
+             || ((b5s5_op (major) & 0x1e) == 0x14
+                 && (major & 0x3) == 0x0)
+                               /* BC2F, BC2T: bits 010000 1010x xxx00 */
+             || (b5s5_op (major) & 0x1e) == 0x1a
+                               /* BPOSGE64, BPOSGE32: bits 010000 1101x */
+             || ((b5s5_op (major) & 0x1e) == 0x1c
+                 && (major & 0x3) == 0x0)
+                               /* BC1F, BC1T: bits 010000 1110x xxx00 */
+             || ((b5s5_op (major) & 0x1c) == 0x1c
+                 && (major & 0x3) == 0x1));
+                               /* BC1ANY*: bits 010000 111xx xxx01 */
+    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)
 {
-  gdb_byte buf[MIPS_INSN16_SIZE];
-  unsigned short inst;
+  ULONGEST insn;
   int status;
 
-  status = target_read_memory (addr, buf, MIPS_INSN16_SIZE);
+  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
   if (status)
     return 0;
+  insn <<= 16;
+  if (mips_insn_size (ISA_MICROMIPS, insn) == 2 * MIPS_INSN16_SIZE)
+    {
+      insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
+      if (status)
+       return 0;
+    }
 
-  inst = mips_fetch_instruction (gdbarch, addr);
-  if (!mustbe32)
-    return (inst & 0xf89f) == 0xe800;  /* JR/JALR (16-bit instruction)  */
+  return micromips_instruction_has_delay_slot (insn, mustbe32);
+}
+
+/* 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.  */
 
@@ -5735,7 +7494,7 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
       && func_addr > boundary && func_addr <= bpaddr)
     boundary = func_addr;
 
-  if (!mips_pc_is_mips16 (bpaddr))
+  if (mips_pc_is_mips (bpaddr))
     {
       if (bpaddr == boundary)
        return bpaddr;
@@ -5743,36 +7502,42 @@ 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 (*insn_at_pc_has_delay_slot) (struct gdbarch *, CORE_ADDR, int);
       CORE_ADDR addr, jmpaddr;
       int i;
 
-      boundary = unmake_mips16_addr (boundary);
+      boundary = unmake_compact_addr (boundary);
 
       /* The only MIPS16 instructions with delay slots are JAL, JALX,
          JALR and JR.  An absolute JAL/JALX is always 4 bytes long,
          so try for that first, then try the 2 byte JALR/JR.
+         The microMIPS ASE has a whole range of jumps and branches
+         with delay slots, some of which take 4 bytes and some take
+         2 bytes, so the idea is the same.
          FIXME: We have to assume that bpaddr is not the second half
          of an extended instruction.  */
+      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;
       for (i = 1; i < 4; i++)
        {
-         if (unmake_mips16_addr (addr) == boundary)
+         if (unmake_compact_addr (addr) == boundary)
            break;
-         addr -= 2;
-         if (i == 1 && mips16_instruction_has_delay_slot (gdbarch, addr, 0))
+         addr -= MIPS_INSN16_SIZE;
+         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
-                  && mips16_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
@@ -5917,7 +7682,7 @@ mips_get_mips16_fn_stub_pc (struct frame_info *frame, CORE_ADDR pc)
        status == 0 && target_pc == 0 && i < 20;
        i++, pc += MIPS_INSN32_SIZE)
     {
-      ULONGEST inst = mips_fetch_instruction (gdbarch, pc);
+      ULONGEST inst = mips_fetch_instruction (gdbarch, ISA_MIPS, pc, NULL);
       CORE_ADDR imm;
       int rt;
       int rs;
@@ -6080,8 +7845,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
@@ -6156,7 +7921,7 @@ mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-  struct minimal_symbol *msym;
+  struct bound_minimal_symbol msym;
   int i;
   gdb_byte stub_code[16];
   int32_t stub_words[4];
@@ -6165,18 +7930,18 @@ mips_skip_pic_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
      instructions inserted before foo or a three instruction sequence
      which jumps to foo.  */
   msym = lookup_minimal_symbol_by_pc (pc);
-  if (msym == NULL
-      || SYMBOL_VALUE_ADDRESS (msym) != pc
-      || SYMBOL_LINKAGE_NAME (msym) == NULL
-      || strncmp (SYMBOL_LINKAGE_NAME (msym), ".pic.", 5) != 0)
+  if (msym.minsym == NULL
+      || BMSYMBOL_VALUE_ADDRESS (msym) != pc
+      || MSYMBOL_LINKAGE_NAME (msym.minsym) == NULL
+      || !startswith (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic."))
     return 0;
 
   /* A two-instruction header.  */
-  if (MSYMBOL_SIZE (msym) == 8)
+  if (MSYMBOL_SIZE (msym.minsym) == 8)
     return pc + 8;
 
   /* A three-instruction (plus delay slot) trampoline.  */
-  if (MSYMBOL_SIZE (msym) == 16)
+  if (MSYMBOL_SIZE (msym.minsym) == 16)
     {
       if (target_read_memory (pc, stub_code, 16) != 0)
        return 0;
@@ -6217,27 +7982,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_mips16_addr (pc))
-           pc = unmake_mips16_addr (pc);
-       }
+       pc = new_pc;
 
       new_pc = find_solib_trampoline_target (frame, pc);
       if (new_pc)
-       {
-         pc = new_pc;
-         if (is_mips16_addr (pc))
-           pc = unmake_mips16_addr (pc);
-       }
+       pc = new_pc;
 
       new_pc = mips_skip_pic_trampoline_code (frame, pc);
       if (new_pc)
-       {
-         pc = new_pc;
-         if (is_mips16_addr (pc))
-           pc = unmake_mips16_addr (pc);
-       }
+       pc = new_pc;
     }
   while (pc != target_pc);
 
@@ -6345,7 +8098,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)
@@ -6370,11 +8123,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"));
 }
 
@@ -6390,6 +8143,23 @@ global_mips_abi (void)
   internal_error (__FILE__, __LINE__, _("unknown ABI string"));
 }
 
+/* Return the default compressed instruction set, either of MIPS16
+   or microMIPS, selected when none could have been determined from
+   the ELF header of the binary being executed (or no binary has been
+   selected.  */
+
+static enum mips_isa
+global_mips_compression (void)
+{
+  int i;
+
+  for (i = 0; mips_compression_strings[i] != NULL; i++)
+    if (mips_compression_strings[i] == mips_compression_string)
+      return (enum mips_isa) i;
+
+  internal_error (__FILE__, __LINE__, _("unknown compressed ISA string"));
+}
+
 static void
 mips_register_g_packet_guesses (struct gdbarch *gdbarch)
 {
@@ -6424,9 +8194,10 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   int i, num_regs;
   enum mips_fpu_type fpu_type;
   struct tdesc_arch_data *tdesc_data = NULL;
-  int elf_fpu_type = 0;
+  int elf_fpu_type = Val_GNU_MIPS_ABI_FP_ANY;
   const char **reg_names;
   struct mips_regnum mips_regnum, *regnum;
+  enum mips_isa mips_isa;
   int dspacc;
   int dspctl;
 
@@ -6720,6 +8491,17 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
     fprintf_unfiltered (gdb_stdlog, "mips_gdbarch_init: mips_abi = %d\n",
                        mips_abi);
 
+  /* Determine the default compressed ISA.  */
+  if ((elf_flags & EF_MIPS_ARCH_ASE_MICROMIPS) != 0
+      && (elf_flags & EF_MIPS_ARCH_ASE_M16) == 0)
+    mips_isa = ISA_MICROMIPS;
+  else if ((elf_flags & EF_MIPS_ARCH_ASE_M16) != 0
+          && (elf_flags & EF_MIPS_ARCH_ASE_MICROMIPS) == 0)
+    mips_isa = ISA_MIPS16;
+  else
+    mips_isa = global_mips_compression ();
+  mips_compression_string = mips_compression_strings[mips_isa];
+
   /* Also used when doing an architecture lookup.  */
   if (gdbarch_debug)
     fprintf_unfiltered (gdb_stdlog,
@@ -6737,17 +8519,17 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   if (!mips_fpu_type_auto)
     fpu_type = mips_fpu_type;
-  else if (elf_fpu_type != 0)
+  else if (elf_fpu_type != Val_GNU_MIPS_ABI_FP_ANY)
     {
       switch (elf_fpu_type)
        {
-       case 1:
+       case Val_GNU_MIPS_ABI_FP_DOUBLE:
          fpu_type = MIPS_FPU_DOUBLE;
          break;
-       case 2:
+       case Val_GNU_MIPS_ABI_FP_SINGLE:
          fpu_type = MIPS_FPU_SINGLE;
          break;
-       case 3:
+       case Val_GNU_MIPS_ABI_FP_SOFT:
        default:
          /* Soft float or unknown.  */
          fpu_type = MIPS_FPU_NONE;
@@ -6798,12 +8580,14 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
        arches != NULL;
        arches = gdbarch_list_lookup_by_info (arches->next, &info))
     {
-      /* MIPS needs to be pedantic about which ABI the object is
-         using.  */
+      /* MIPS needs to be pedantic about which ABI and the compressed
+         ISA variation the object is using.  */
       if (gdbarch_tdep (arches->gdbarch)->elf_flags != elf_flags)
        continue;
       if (gdbarch_tdep (arches->gdbarch)->mips_abi != mips_abi)
        continue;
+      if (gdbarch_tdep (arches->gdbarch)->mips_isa != mips_isa)
+       continue;
       /* Need to be pedantic about which register virtual size is
          used.  */
       if (gdbarch_tdep (arches->gdbarch)->mips64_transfers_32bit_regs_p
@@ -6825,13 +8609,10 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   tdep->mips64_transfers_32bit_regs_p = mips64_transfers_32bit_regs_p;
   tdep->found_abi = found_abi;
   tdep->mips_abi = mips_abi;
+  tdep->mips_isa = mips_isa;
   tdep->mips_fpu_type = fpu_type;
   tdep->register_size_valid_p = 0;
   tdep->register_size = 0;
-  tdep->gregset = NULL;
-  tdep->gregset64 = NULL;
-  tdep->fpregset = NULL;
-  tdep->fpregset64 = NULL;
 
   if (info.target_desc)
     {
@@ -6865,6 +8646,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;
@@ -7044,12 +8828,16 @@ 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_adjust_breakpoint_address (gdbarch,
                                         mips_adjust_breakpoint_address);
 
@@ -7114,10 +8902,12 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   dwarf2_append_unwinders (gdbarch);
   frame_unwind_append_unwinder (gdbarch, &mips_stub_frame_unwind);
   frame_unwind_append_unwinder (gdbarch, &mips_insn16_frame_unwind);
+  frame_unwind_append_unwinder (gdbarch, &mips_micro_frame_unwind);
   frame_unwind_append_unwinder (gdbarch, &mips_insn32_frame_unwind);
   frame_base_append_sniffer (gdbarch, dwarf2_frame_base_sniffer);
   frame_base_append_sniffer (gdbarch, mips_stub_frame_base_sniffer);
   frame_base_append_sniffer (gdbarch, mips_insn16_frame_base_sniffer);
+  frame_base_append_sniffer (gdbarch, mips_micro_frame_base_sniffer);
   frame_base_append_sniffer (gdbarch, mips_insn32_frame_base_sniffer);
 
   if (tdesc_data)
@@ -7179,7 +8969,7 @@ show_mips_abi (struct ui_file *file,
               struct cmd_list_element *ignored_cmd,
               const char *ignored_value)
 {
-  if (gdbarch_bfd_arch_info (target_gdbarch)->arch != bfd_arch_mips)
+  if (gdbarch_bfd_arch_info (target_gdbarch ())->arch != bfd_arch_mips)
     fprintf_filtered
       (file, 
        "The MIPS ABI is unknown because the current architecture "
@@ -7187,7 +8977,7 @@ show_mips_abi (struct ui_file *file,
   else
     {
       enum mips_abi global_abi = global_mips_abi ();
-      enum mips_abi actual_abi = mips_abi (target_gdbarch);
+      enum mips_abi actual_abi = mips_abi (target_gdbarch ());
       const char *actual_abi_str = mips_abi_strings[actual_abi];
 
       if (global_abi == MIPS_ABI_UNKNOWN)
@@ -7211,6 +9001,16 @@ show_mips_abi (struct ui_file *file,
     }
 }
 
+/* Print out which MIPS compressed ISA encoding is used.  */
+
+static void
+show_mips_compression (struct ui_file *file, int from_tty,
+                      struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (file, _("The compressed ISA encoding used is %s.\n"),
+                   value);
+}
+
 static void
 mips_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
 {
@@ -7327,6 +9127,23 @@ This option can be set to one of:\n\
                        show_mips_abi,
                        &setmipscmdlist, &showmipscmdlist);
 
+  /* Allow the user to set the ISA to assume for compressed code if ELF
+     file flags don't tell or there is no program file selected.  This
+     setting is updated whenever unambiguous ELF file flags are interpreted,
+     and carried over to subsequent sessions.  */
+  add_setshow_enum_cmd ("compression", class_obscure, mips_compression_strings,
+                       &mips_compression_string, _("\
+Set the compressed ISA encoding used by MIPS code."), _("\
+Show the compressed ISA encoding used by MIPS code."), _("\
+Select the compressed ISA encoding used in functions that have no symbol\n\
+information available.  The encoding can be set to either of:\n\
+  mips16\n\
+  micromips\n\
+and is updated automatically from ELF file flags if available."),
+                       mips_abi_update,
+                       show_mips_compression,
+                       &setmipscmdlist, &showmipscmdlist);
+
   /* Let the user turn off floating point and set the fence post for
      heuristic_proc_start.  */
 
@@ -7398,13 +9215,13 @@ that would transfer 32 bits for some registers (e.g. SR, FSR) and\n\
                           &setlist, &showlist);
 
   /* Debug this files internals.  */
-  add_setshow_zinteger_cmd ("mips", class_maintenance,
-                           &mips_debug, _("\
+  add_setshow_zuinteger_cmd ("mips", class_maintenance,
+                            &mips_debug, _("\
 Set mips debugging."), _("\
 Show mips debugging."), _("\
 When non-zero, mips specific debugging is enabled."),
-                           NULL,
-                           NULL, /* FIXME: i18n: Mips debugging is
-                                    currently %s.  */
-                           &setdebuglist, &showdebuglist);
+                            NULL,
+                            NULL, /* FIXME: i18n: Mips debugging is
+                                     currently %s.  */
+                            &setdebuglist, &showdebuglist);
 }
This page took 0.07271 seconds and 4 git commands to generate.