MIPS: Keep the ISA bit in compressed code addresses
[deliverable/binutils-gdb.git] / gdb / mips-tdep.c
index 792ae6ef7f98d2fb5c3eaf4a5a61376cad8cffe0..5a5a7164336ea21b531f2a2b7de98e31830bd18d 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-2014 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,11 +60,18 @@ static const struct objfile_data *mips_pdr_data;
 
 static struct type *mips_register_type (struct gdbarch *gdbarch, int regnum);
 
-static int mips32_instruction_has_delay_slot (struct gdbarch *, CORE_ADDR);
-static int micromips_instruction_has_delay_slot (struct gdbarch *, CORE_ADDR,
-                                                int);
-static int mips16_instruction_has_delay_slot (struct gdbarch *, CORE_ADDR,
-                                             int);
+static int mips32_instruction_has_delay_slot (struct gdbarch *gdbarch,
+                                             ULONGEST inst);
+static int micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32);
+static int mips16_instruction_has_delay_slot (unsigned short inst,
+                                             int mustbe32);
+
+static int mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                            CORE_ADDR addr);
+static int micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                               CORE_ADDR addr, int mustbe32);
+static int mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                            CORE_ADDR addr, int mustbe32);
 
 /* 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.  */
@@ -335,6 +340,15 @@ make_compact_addr (CORE_ADDR addr)
   return ((addr) | (CORE_ADDR) 1);
 }
 
+/* Extern version of unmake_compact_addr; we use a separate function
+   so that unmake_compact_addr can be inlined throughout this file.  */
+
+CORE_ADDR
+mips_unmake_compact_addr (CORE_ADDR addr)
+{
+  return unmake_compact_addr (addr);
+}
+
 /* Functions for setting and testing a bit in a minimal symbol that
    marks it as MIPS16 or microMIPS function.  The MSB of the minimal
    symbol's "info" field is used for this purpose.
@@ -343,8 +357,9 @@ make_compact_addr (CORE_ADDR addr)
    "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; in particular synthetic symbols such as for PLT stubs
-   have no ELF-private part at all.
+   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_mips16 and msymbol_is_micromips test the "special" bit
    in a minimal symbol.  */
@@ -353,14 +368,25 @@ static void
 mips_elf_make_msymbol_special (asymbol * sym, struct minimal_symbol *msym)
 {
   elf_symbol_type *elfsym = (elf_symbol_type *) sym;
+  unsigned char st_other;
 
-  if ((sym->flags & BSF_SYNTHETIC) != 0)
+  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 (elfsym->internal_elf_sym.st_other))
-    MSYMBOL_TARGET_FLAG_2 (msym) = 1;
-  else if (ELF_ST_IS_MIPS16 (elfsym->internal_elf_sym.st_other))
-    MSYMBOL_TARGET_FLAG_1 (msym) = 1;
+  if (ELF_ST_IS_MICROMIPS (st_other))
+    {
+      MSYMBOL_TARGET_FLAG_2 (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;
+      SET_MSYMBOL_VALUE_ADDRESS (msym, MSYMBOL_VALUE_RAW_ADDRESS (msym) | 1);
+    }
 }
 
 /* Return one iff MSYM refers to standard ISA code.  */
@@ -387,6 +413,35 @@ msymbol_is_micromips (struct minimal_symbol *msym)
   return MSYMBOL_TARGET_FLAG_2 (msym);
 }
 
+/* Set the ISA bit in the main symbol too, complementing the corresponding
+   minimal symbol setting and reflecting the run-time value of the symbol.
+   The need for comes from the ISA bit having been cleared as code in
+   `_bfd_mips_elf_symbol_processing' separated it into the ELF symbol's
+   `st_other' STO_MIPS16 or STO_MICROMIPS annotation, making the values
+   of symbols referring to compressed code different in GDB to the values
+   used by actual code.  That in turn makes them evaluate incorrectly in
+   expressions, producing results different to what the same expressions
+   yield when compiled into the program being debugged.  */
+
+static void
+mips_make_symbol_special (struct symbol *sym, struct objfile *objfile)
+{
+  if (SYMBOL_CLASS (sym) == LOC_BLOCK)
+    {
+      /* We are in symbol reading so it is OK to cast away constness.  */
+      struct block *block = (struct block *) SYMBOL_BLOCK_VALUE (sym);
+      CORE_ADDR compact_block_start;
+      struct bound_minimal_symbol msym;
+
+      compact_block_start = BLOCK_START (block) | 1;
+      msym = lookup_minimal_symbol_by_pc (compact_block_start);
+      if (msym.minsym && !msymbol_is_mips (msym.minsym))
+       {
+         BLOCK_START (block) = compact_block_start;
+       }
+    }
+}
+
 /* XFER a value from the big/little/left end of the register.
    Depending on the size of the value it might occupy the entire
    register or just part of it.  Make an allowance for this, aligning
@@ -787,7 +842,7 @@ static const signed char mips_reg3_to_reg[8] = { 16, 17, 2, 3, 4, 5, 6, 7 };
    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
@@ -1115,15 +1170,15 @@ show_mask_address (struct ui_file *file, int from_tty,
 int
 mips_pc_is_mips (CORE_ADDR memaddr)
 {
-  struct minimal_symbol *sym;
+  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 (memaddr);
-  if (sym)
-    return msymbol_is_mips (sym);
+  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);
 }
@@ -1133,15 +1188,15 @@ mips_pc_is_mips (CORE_ADDR memaddr)
 int
 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.  Otherwise if bit 0 of the address is
      set, then ELF file flags will tell if this is a MIPS16 function.  */
-  sym = lookup_minimal_symbol_by_pc (memaddr);
-  if (sym)
-    return msymbol_is_mips16 (sym);
+  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);
 }
@@ -1151,16 +1206,16 @@ mips_pc_is_mips16 (struct gdbarch *gdbarch, CORE_ADDR memaddr)
 int
 mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr)
 {
-  struct minimal_symbol *sym;
+  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 (memaddr);
-  if (sym)
-    return msymbol_is_micromips (sym);
+  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);
 }
@@ -1171,19 +1226,19 @@ mips_pc_is_micromips (struct gdbarch *gdbarch, CORE_ADDR memaddr)
 static enum mips_isa
 mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr)
 {
-  struct minimal_symbol *sym;
+  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 (memaddr);
-  if (sym)
+  sym = lookup_minimal_symbol_by_pc (make_compact_addr (memaddr));
+  if (sym.minsym)
     {
-      if (msymbol_is_micromips (sym))
+      if (msymbol_is_micromips (sym.minsym))
        return ISA_MICROMIPS;
-      else if (msymbol_is_mips16 (sym))
+      else if (msymbol_is_mips16 (sym.minsym))
        return ISA_MIPS16;
       else
        return ISA_MIPS;
@@ -1199,6 +1254,67 @@ mips_pc_isa (struct gdbarch *gdbarch, CORE_ADDR memaddr)
     }
 }
 
+/* Set the ISA bit correctly in the PC, used by DWARF-2 machinery.
+   The need for comes from the ISA bit having been cleared, making
+   addresses in FDE, range records, etc. referring to compressed code
+   different to those in line information, the symbol table and finally
+   the PC register.  That in turn confuses many operations.  */
+
+static CORE_ADDR
+mips_adjust_dwarf2_addr (CORE_ADDR pc)
+{
+  pc = unmake_compact_addr (pc);
+  return mips_pc_is_mips (pc) ? pc : make_compact_addr (pc);
+}
+
+/* Recalculate the line record requested so that the resulting PC has
+   the ISA bit set correctly, used by DWARF-2 machinery.  The need for
+   this adjustment comes from some records associated with compressed
+   code having the ISA bit cleared, most notably at function prologue
+   ends.  The ISA bit is in this context retrieved from the minimal
+   symbol covering the address requested, which in turn has been
+   constructed from the binary's symbol table rather than DWARF-2
+   information.  The correct setting of the ISA bit is required for
+   breakpoint addresses to correctly match against the stop PC.
+
+   As line entries can specify relative address adjustments we need to
+   keep track of the absolute value of the last line address recorded
+   in line information, so that we can calculate the actual address to
+   apply the ISA bit adjustment to.  We use PC for this tracking and
+   keep the original address there.
+
+   As such relative address adjustments can be odd within compressed
+   code we need to keep track of the last line address with the ISA
+   bit adjustment applied too, as the original address may or may not
+   have had the ISA bit set.  We use ADJ_PC for this tracking and keep
+   the adjusted address there.
+
+   For relative address adjustments we then use these variables to
+   calculate the address intended by line information, which will be
+   PC-relative, and return an updated adjustment carrying ISA bit
+   information, which will be ADJ_PC-relative.  For absolute address
+   adjustments we just return the same address that we store in ADJ_PC
+   too.
+
+   As the first line entry can be relative to an implied address value
+   of 0 we need to have the initial address set up that we store in PC
+   and ADJ_PC.  This is arranged with a call from `dwarf_decode_lines_1'
+   that sets PC to 0 and ADJ_PC accordingly, usually 0 as well.  */
+
+static CORE_ADDR
+mips_adjust_dwarf2_line (CORE_ADDR addr, int rel)
+{
+  static CORE_ADDR adj_pc;
+  static CORE_ADDR pc;
+  CORE_ADDR isa_pc;
+
+  pc = rel ? pc + addr : addr;
+  isa_pc = mips_adjust_dwarf2_addr (pc);
+  addr = rel ? isa_pc - adj_pc : isa_pc;
+  adj_pc = isa_pc;
+  return addr;
+}
+
 /* Various MIPS16 thunk (aka stub or trampoline) names.  */
 
 static const char mips_str_mips16_call_stub[] = "__mips16_call_stub_";
@@ -1245,11 +1361,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_compact_addr (pc))
-    pc = unmake_compact_addr (pc);
   return pc;
 }
 
@@ -1259,8 +1373,6 @@ mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
   CORE_ADDR pc;
 
   pc = frame_unwind_register_signed (next_frame, gdbarch_pc_regnum (gdbarch));
-  if (is_compact_addr (pc))
-    pc = unmake_compact_addr (pc);
   /* macro/2012-04-20: This hack skips over MIPS16 call thunks as
      intermediate frames.  In this case we can get the caller's address
      from $ra, or if $ra contains an address within a thunk as well, then
@@ -1270,15 +1382,9 @@ mips_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
     {
       pc = frame_unwind_register_signed
             (next_frame, gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM);
-      if (is_compact_addr (pc))
-       pc = unmake_compact_addr (pc);
       if (mips_in_frame_stub (pc))
-       {
-         pc = frame_unwind_register_signed
-                (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
-         if (is_compact_addr (pc))
-           pc = unmake_compact_addr (pc);
-       }
+       pc = frame_unwind_register_signed
+              (next_frame, gdbarch_num_regs (gdbarch) + MIPS_S2_REGNUM);
     }
   return pc;
 }
@@ -1312,10 +1418,7 @@ mips_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
   int regnum = gdbarch_pc_regnum (get_regcache_arch (regcache));
 
-  if (mips_pc_is_mips (pc))
-    regcache_cooked_write_unsigned (regcache, regnum, pc);
-  else
-    regcache_cooked_write_unsigned (regcache, regnum, make_compact_addr (pc));
+  regcache_cooked_write_unsigned (regcache, regnum, pc);
 }
 
 /* Fetch and return instruction from the specified location.  Handle
@@ -2036,7 +2139,8 @@ fetch_mips_16 (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   gdb_byte buf[8];
-  pc &= 0xfffffffe;            /* Clear the low order bit.  */
+
+  pc = unmake_compact_addr (pc);       /* Clear the low order bit.  */
   target_read_memory (pc, buf, 2);
   return extract_unsigned_integer (buf, 2, byte_order);
 }
@@ -2114,10 +2218,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
@@ -2132,7 +2239,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
@@ -2140,7 +2247,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
@@ -2154,7 +2261,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
        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;
@@ -2166,7 +2273,7 @@ extended_mips16_next_pc (struct frame_info *frame, CORE_ADDR pc,
        unpack_mips16 (gdbarch, pc, extension, insn, ritype, &upk);
        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;
@@ -2180,8 +2287,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;
@@ -2236,7 +2342,7 @@ 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.
+   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)
@@ -2251,6 +2357,48 @@ mips_next_pc (struct frame_info *frame, CORE_ADDR pc)
     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;
@@ -2328,6 +2476,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;
@@ -2338,11 +2490,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.  */
@@ -2355,9 +2509,16 @@ mips16_scan_prologue (struct gdbarch *gdbarch,
 
   if (limit_pc > start_pc + 200)
     limit_pc = start_pc + 200;
+  prev_pc = start_pc;
 
+  /* Permit at most one non-prologue non-control-transfer instruction
+     in the middle which may have been reordered by the compiler for
+     optimisation.  */
   for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += MIPS_INSN16_SIZE)
     {
+      this_non_prologue_insn = 0;
+      in_delay_slot = 0;
+
       /* Save the previous instruction.  If it's an EXTEND, we'll extract
          the immediate offset extension from it in mips16_get_imm.  */
       prev_inst = inst;
@@ -2447,21 +2608,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,
@@ -2614,11 +2794,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;
 }
@@ -2755,7 +2936,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
                         struct frame_info *this_frame,
                         struct mips_frame_cache *this_cache)
 {
-  CORE_ADDR end_prologue_addr = 0;
+  CORE_ADDR end_prologue_addr;
   int prev_non_prologue_insn = 0;
   int frame_reg = MIPS_SP_REGNUM;
   int this_non_prologue_insn;
@@ -2763,6 +2944,8 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
   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 */
@@ -2799,6 +2982,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
   for (cur_pc = start_pc; cur_pc < limit_pc; cur_pc += loc)
     {
       this_non_prologue_insn = 0;
+      in_delay_slot = 0;
       sp_adj = 0;
       loc = 0;
       insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, cur_pc, NULL);
@@ -2905,7 +3089,7 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
              break;
 
            /* LUI $v1 is used for larger $sp adjustments.  */
-           /* Discard LUI $gp is used for PIC code.  */
+           /* Discard LUI $gp used for PIC code.  */
            case 0x10: /* POOL32I: bits 010000 */
              if (b5s5_op (insn >> 16) == 0xd
                                /* LUI: bits 010000 001101 */
@@ -2951,9 +3135,15 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
              break;
 
            default:
-             this_non_prologue_insn = 1;
+             /* The instruction in the delay slot can be a part
+                of the prologue, so move forward once more.  */
+             if (micromips_instruction_has_delay_slot (insn, 0))
+               in_delay_slot = 1;
+             else
+               this_non_prologue_insn = 1;
              break;
            }
+         insn >>= 16;
          break;
 
        /* 16-bit instructions.  */
@@ -3008,7 +3198,12 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
              break;
 
            default:
-             this_non_prologue_insn = 1;
+             /* The instruction in the delay slot can be a part
+                of the prologue, so move forward once more.  */
+             if (micromips_instruction_has_delay_slot (insn << 16, 0))
+               in_delay_slot = 1;
+             else
+               this_non_prologue_insn = 1;
              break;
            }
          break;
@@ -3017,13 +3212,16 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
        frame_offset -= sp_adj;
 
       non_prologue_insns += this_non_prologue_insn;
-      /* Enough non-prologue insns seen or positive stack adjustment? */
-      if (end_prologue_addr == 0 && (non_prologue_insns > 1 || sp_adj > 0))
-       {
-         end_prologue_addr = prev_non_prologue_insn ? prev_pc : cur_pc;
-         break;
-       }
+
+      /* A jump or branch, enough non-prologue insns seen or positive
+         stack adjustment?  If so, then we must have reached the end
+         of the prologue by now.  */
+      if (prev_delay_slot || non_prologue_insns > 1 || sp_adj > 0
+         || micromips_instruction_is_compact_branch (insn))
+       break;
+
       prev_non_prologue_insn = this_non_prologue_insn;
+      prev_delay_slot = in_delay_slot;
       prev_pc = cur_pc;
     }
 
@@ -3041,13 +3239,12 @@ micromips_scan_prologue (struct gdbarch *gdbarch,
        = this_cache->saved_regs[gdbarch_num_regs (gdbarch) + MIPS_RA_REGNUM];
     }
 
-  /* If we didn't reach the end of the prologue when scanning the function
-     instructions, then set end_prologue_addr to the address of the
-     instruction immediately after the last one we scanned.  Unless the
-     last one looked like a non-prologue instruction (and we looked ahead),
-     in which case use its address instead.  */
-  if (end_prologue_addr == 0)
-    end_prologue_addr = prev_non_prologue_insn ? prev_pc : cur_pc;
+  /* Set end_prologue_addr to the address of the instruction immediately
+     after the last one we scanned.  Unless the last one looked like a
+     non-prologue instruction (and we looked ahead), in which case use
+     its address instead.  */
+  end_prologue_addr
+    = prev_non_prologue_insn || prev_delay_slot ? prev_pc : cur_pc;
 
   return end_prologue_addr;
 }
@@ -3195,17 +3392,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
@@ -3221,13 +3423,23 @@ 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;
       int reg;
 
+      this_non_prologue_insn = 0;
+      in_delay_slot = 0;
+
       /* Fetch the instruction.  */
       inst = (unsigned long) mips_fetch_instruction (gdbarch, ISA_MIPS,
                                                     cur_pc, NULL);
@@ -3273,6 +3485,7 @@ 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));
              if (alloca_adjust > 0)
@@ -3343,6 +3556,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 */
@@ -3351,31 +3565,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)
@@ -3393,14 +3608,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
@@ -3581,29 +3794,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
+      && strncmp (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) == 0)
     return 1;
 
   return 0;
@@ -3652,9 +3857,6 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
-  if (is_compact_addr (addr))
-    addr = unmake_compact_addr (addr);
-
   if (mips_mask_address_p (tdep) && (((ULONGEST) addr) >> 32 == 0xffffffffUL))
     /* This hack is a work-around for existing boards using PMON, the
        simulator, and any other 64-bit targets that doesn't have true
@@ -3943,7 +4145,7 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
 
   /* Effectively inserts the breakpoints.  */
   for (index = 0; index <= last_breakpoint; index++)
-      insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
+    insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
 
   return 1;
 }
@@ -4020,7 +4222,7 @@ 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_mips (pc) ? MIPS_INSN32_SIZE : MIPS_INSN16_SIZE;
@@ -4353,25 +4555,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_mips (addr))
-           val = value_contents (arg);
-         else
-           {
-             store_signed_integer (valbuf, len, byte_order, 
-                                   make_compact_addr (addr));
-             val = valbuf;
-           }
-       }
       /* The EABI passes structures that do not fit in a register by
          reference.  */
-      else if (len > regsize
+      if (len > regsize
          && (typecode == TYPE_CODE_STRUCT || typecode == TYPE_CODE_UNION))
        {
          store_unsigned_integer (valbuf, regsize, byte_order,
@@ -5736,7 +5922,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);
@@ -5749,21 +5934,6 @@ mips_o64_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
       val = value_contents (arg);
 
-      /* Function pointer arguments to mips16 code need to be made into
-         mips16 pointers.  */
-      if (typecode == TYPE_CODE_PTR
-          && TYPE_CODE (TYPE_TARGET_TYPE (arg_type)) == TYPE_CODE_FUNC)
-       {
-         CORE_ADDR addr = extract_signed_integer (value_contents (arg),
-                                                  len, byte_order);
-         if (!mips_pc_is_mips (addr))
-           {
-             store_signed_integer (valbuf, len, byte_order, 
-                                   make_compact_addr (addr));
-             val = valbuf;
-           }
-       }
-
       /* Floating point arguments passed in registers have to be
          treated specially.  On 32-bit architectures, doubles are
          passed in register pairs; the even FP register gets the
@@ -6196,12 +6366,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);
 
@@ -6378,11 +6542,11 @@ mips_single_step_through_delay (struct gdbarch *gdbarch,
   int size;
 
   if ((mips_pc_is_mips (pc)
-       && !mips32_instruction_has_delay_slot (gdbarch, pc))
+       && !mips32_insn_at_pc_has_delay_slot (gdbarch, pc))
       || (mips_pc_is_micromips (gdbarch, pc)
-         && !micromips_instruction_has_delay_slot (gdbarch, pc, 0))
+         && !micromips_insn_at_pc_has_delay_slot (gdbarch, pc, 0))
       || (mips_pc_is_mips16 (gdbarch, pc)
-         && !mips16_instruction_has_delay_slot (gdbarch, pc, 0)))
+         && !mips16_insn_at_pc_has_delay_slot (gdbarch, pc, 0)))
     return 0;
 
   isa = mips_pc_isa (gdbarch, pc);
@@ -6972,23 +7136,17 @@ mips_remote_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr,
     *kindptr = 4;
 }
 
-/* Return non-zero if the ADDR instruction has a branch delay slot
-   (i.e. it is a jump or branch instruction).  This function is based
-   on mips32_next_pc.  */
+/* Return non-zero if the standard MIPS instruction INST has a branch
+   delay slot (i.e. it is a jump or branch instruction).  This function
+   is based on mips32_next_pc.  */
 
 static int
-mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
+mips32_instruction_has_delay_slot (struct gdbarch *gdbarch, ULONGEST inst)
 {
-  unsigned long inst;
-  int status;
   int op;
   int rs;
   int rt;
 
-  inst = mips_fetch_instruction (gdbarch, ISA_MIPS, addr, &status);
-  if (status)
-    return 0;
-
   op = itype_op (inst);
   if ((inst & 0xe0000000) != 0)
     {
@@ -7028,93 +7186,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
-micromips_instruction_has_delay_slot (struct gdbarch *gdbarch,
-                                     CORE_ADDR addr, int mustbe32)
+mips32_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr)
 {
   ULONGEST insn;
   int status;
 
-  insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
+  insn = mips_fetch_instruction (gdbarch, ISA_MIPS, addr, &status);
   if (status)
     return 0;
 
-  if (!mustbe32)               /* 16-bit instructions.  */
-    return (micromips_op (insn) == 0x11
-                               /* POOL16C: bits 010001 */
-           && (b5s5_op (insn) == 0xc
+  return mips32_instruction_has_delay_slot (gdbarch, insn);
+}
+
+/* Return non-zero if the microMIPS instruction INSN, comprising the
+   16-bit major opcode word in the high 16 bits and any second word
+   in the low 16 bits, has a branch delay slot (i.e. it is a non-compact
+   jump or branch instruction).  The instruction must be 32-bit if
+   MUSTBE32 is set or can be any instruction otherwise.  */
+
+static int
+micromips_instruction_has_delay_slot (ULONGEST insn, int mustbe32)
+{
+  ULONGEST major = insn >> 16;
+
+  switch (micromips_op (major))
+    {
+    /* 16-bit instructions.  */
+    case 0x33:                 /* B16: bits 110011 */
+    case 0x2b:                 /* BNEZ16: bits 101011 */
+    case 0x23:                 /* BEQZ16: bits 100011 */
+      return !mustbe32;
+    case 0x11:                 /* POOL16C: bits 010001 */
+      return (!mustbe32
+             && ((b5s5_op (major) == 0xc
                                /* JR16: bits 010001 01100 */
-               || (b5s5_op (insn) & 0x1e) == 0xe))
+                 || (b5s5_op (major) & 0x1e) == 0xe)));
                                /* JALR16, JALRS16: bits 010001 0111x */
-          || (micromips_op (insn) & 0x37) == 0x23
-                               /* BEQZ16, BNEZ16: bits 10x011 */
-          || micromips_op (insn) == 0x33;
-                               /* B16: bits 110011 */
-
-                               /* 32-bit instructions.  */
-  if (micromips_op (insn) == 0x0)
-                               /* POOL32A: bits 000000 */
-    {
-      insn <<= 16;
-      insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, addr, &status);
-      if (status)
-       return 0;
-      return b0s6_op (insn) == 0x3c
-                               /* POOL32Axf: bits 000000 ... 111100 */
-            && (b6s10_ext (insn) & 0x2bf) == 0x3c;
-                               /* JALR, JALR.HB: 000000 000x111100 111100 */
-                               /* JALRS, JALRS.HB: 000000 010x111100 111100 */
-    }
-
-  return (micromips_op (insn) == 0x10
-                               /* POOL32I: bits 010000 */
-         && ((b5s5_op (insn) & 0x1c) == 0x0
+    /* 32-bit instructions.  */
+    case 0x3d:                 /* JAL: bits 111101 */
+    case 0x3c:                 /* JALX: bits 111100 */
+    case 0x35:                 /* J: bits 110101 */
+    case 0x2d:                 /* BNE: bits 101101 */
+    case 0x25:                 /* BEQ: bits 100101 */
+    case 0x1d:                 /* JALS: bits 011101 */
+      return 1;
+    case 0x10:                 /* POOL32I: bits 010000 */
+      return ((b5s5_op (major) & 0x1c) == 0x0
                                /* BLTZ, BLTZAL, BGEZ, BGEZAL: 010000 000xx */
-             || (b5s5_op (insn) & 0x1d) == 0x4
+             || (b5s5_op (major) & 0x1d) == 0x4
                                /* BLEZ, BGTZ: bits 010000 001x0 */
-             || (b5s5_op (insn) & 0x1d) == 0x11
+             || (b5s5_op (major) & 0x1d) == 0x11
                                /* BLTZALS, BGEZALS: bits 010000 100x1 */
-             || ((b5s5_op (insn) & 0x1e) == 0x14
-                 && (insn & 0x3) == 0x0)
+             || ((b5s5_op (major) & 0x1e) == 0x14
+                 && (major & 0x3) == 0x0)
                                /* BC2F, BC2T: bits 010000 1010x xxx00 */
-             || (b5s5_op (insn) & 0x1e) == 0x1a
+             || (b5s5_op (major) & 0x1e) == 0x1a
                                /* BPOSGE64, BPOSGE32: bits 010000 1101x */
-             || ((b5s5_op (insn) & 0x1e) == 0x1c
-                 && (insn & 0x3) == 0x0)
+             || ((b5s5_op (major) & 0x1e) == 0x1c
+                 && (major & 0x3) == 0x0)
                                /* BC1F, BC1T: bits 010000 1110x xxx00 */
-             || ((b5s5_op (insn) & 0x1c) == 0x1c
-                 && (insn & 0x3) == 0x1)))
+             || ((b5s5_op (major) & 0x1c) == 0x1c
+                 && (major & 0x3) == 0x1));
                                /* BC1ANY*: bits 010000 111xx xxx01 */
-        || (micromips_op (insn) & 0x1f) == 0x1d
-                               /* JALS, JAL: bits x11101 */
-        || (micromips_op (insn) & 0x37) == 0x25
-                               /* BEQ, BNE: bits 10x101 */
-        || micromips_op (insn) == 0x35
-                               /* J: bits 110101 */
-        || micromips_op (insn) == 0x3c;
-                               /* JALX: bits 111100 */
+    case 0x0:                  /* POOL32A: bits 000000 */
+      return (b0s6_op (insn) == 0x3c
+                               /* POOL32Axf: bits 000000 ... 111100 */
+             && (b6s10_ext (insn) & 0x2bf) == 0x3c);
+                               /* JALR, JALR.HB: 000000 000x111100 111100 */
+                               /* JALRS, JALRS.HB: 000000 010x111100 111100 */
+    default:
+      return 0;
+    }
 }
 
+/* Return non-zero if a microMIPS instruction at ADDR has a branch delay
+   slot (i.e. it is a non-compact jump instruction).  The instruction
+   must be 32-bit if MUSTBE32 is set or can be any instruction otherwise.  */
+
 static int
-mips16_instruction_has_delay_slot (struct gdbarch *gdbarch, CORE_ADDR addr,
-                                  int mustbe32)
+micromips_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                    CORE_ADDR addr, int mustbe32)
 {
-  unsigned short inst;
+  ULONGEST insn;
   int status;
 
-  inst = mips_fetch_instruction (gdbarch, ISA_MIPS16, addr, &status);
+  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;
+    }
+
+  return micromips_instruction_has_delay_slot (insn, mustbe32);
+}
 
-  if (!mustbe32)
-    return (inst & 0xf89f) == 0xe800;  /* JR/JALR (16-bit instruction)  */
+/* Return non-zero if the MIPS16 instruction INST, which must be
+   a 32-bit instruction if MUSTBE32 is set or can be any instruction
+   otherwise, has a branch delay slot (i.e. it is a non-compact jump
+   instruction).  This function is based on mips16_next_pc.  */
+
+static int
+mips16_instruction_has_delay_slot (unsigned short inst, int mustbe32)
+{
+  if ((inst & 0xf89f) == 0xe800)       /* JR/JALR (16-bit instruction)  */
+    return !mustbe32;
   return (inst & 0xf800) == 0x1800;    /* JAL/JALX (32-bit instruction)  */
 }
 
+/* Return non-zero if a MIPS16 instruction at ADDR has a branch delay
+   slot (i.e. it is a non-compact jump instruction).  The instruction
+   must be 32-bit if MUSTBE32 is set or can be any instruction otherwise.  */
+
+static int
+mips16_insn_at_pc_has_delay_slot (struct gdbarch *gdbarch,
+                                 CORE_ADDR addr, int mustbe32)
+{
+  unsigned short insn;
+  int status;
+
+  insn = mips_fetch_instruction (gdbarch, ISA_MIPS16, addr, &status);
+  if (status)
+    return 0;
+
+  return mips16_instruction_has_delay_slot (insn, mustbe32);
+}
+
 /* Calculate the starting address of the MIPS memory segment BPADDR is in.
    This assumes KSSEG exists.  */
 
@@ -7206,12 +7410,12 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
       /* If the previous instruction has a branch delay slot, we have
          to move the breakpoint to the branch instruction. */
       prev_addr = bpaddr - 4;
-      if (mips32_instruction_has_delay_slot (gdbarch, prev_addr))
+      if (mips32_insn_at_pc_has_delay_slot (gdbarch, prev_addr))
        bpaddr = prev_addr;
     }
   else
     {
-      int (*instruction_has_delay_slot) (struct gdbarch *, CORE_ADDR, int);
+      int (*insn_at_pc_has_delay_slot) (struct gdbarch *, CORE_ADDR, int);
       CORE_ADDR addr, jmpaddr;
       int i;
 
@@ -7225,9 +7429,9 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
          2 bytes, so the idea is the same.
          FIXME: We have to assume that bpaddr is not the second half
          of an extended instruction.  */
-      instruction_has_delay_slot = (mips_pc_is_micromips (gdbarch, bpaddr)
-                                    ? micromips_instruction_has_delay_slot
-                                    : mips16_instruction_has_delay_slot);
+      insn_at_pc_has_delay_slot = (mips_pc_is_micromips (gdbarch, bpaddr)
+                                  ? micromips_insn_at_pc_has_delay_slot
+                                  : mips16_insn_at_pc_has_delay_slot);
 
       jmpaddr = 0;
       addr = bpaddr;
@@ -7236,12 +7440,12 @@ mips_adjust_breakpoint_address (struct gdbarch *gdbarch, CORE_ADDR bpaddr)
          if (unmake_compact_addr (addr) == boundary)
            break;
          addr -= MIPS_INSN16_SIZE;
-         if (i == 1 && instruction_has_delay_slot (gdbarch, addr, 0))
+         if (i == 1 && insn_at_pc_has_delay_slot (gdbarch, addr, 0))
            /* Looks like a JR/JALR at [target-1], but it could be
               the second word of a previous JAL/JALX, so record it
               and check back one more.  */
            jmpaddr = addr;
-         else if (i > 1 && instruction_has_delay_slot (gdbarch, addr, 1))
+         else if (i > 1 && insn_at_pc_has_delay_slot (gdbarch, addr, 1))
            {
              if (i == 2)
                /* Looks like a JAL/JALX at [target-2], but it could also
@@ -7625,7 +7829,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];
@@ -7634,18 +7838,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
+      || strncmp (MSYMBOL_LINKAGE_NAME (msym.minsym), ".pic.", 5) != 0)
     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;
@@ -7686,27 +7890,15 @@ mips_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
 
       new_pc = mips_skip_mips16_trampoline_code (frame, pc);
       if (new_pc)
-       {
-         pc = new_pc;
-         if (is_compact_addr (pc))
-           pc = unmake_compact_addr (pc);
-       }
+       pc = new_pc;
 
       new_pc = find_solib_trampoline_target (frame, pc);
       if (new_pc)
-       {
-         pc = new_pc;
-         if (is_compact_addr (pc))
-           pc = unmake_compact_addr (pc);
-       }
+       pc = new_pc;
 
       new_pc = mips_skip_pic_trampoline_code (frame, pc);
       if (new_pc)
-       {
-         pc = new_pc;
-         if (is_compact_addr (pc))
-           pc = unmake_compact_addr (pc);
-       }
+       pc = new_pc;
     }
   while (pc != target_pc);
 
@@ -7910,7 +8102,7 @@ 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;
@@ -8235,17 +8427,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;
@@ -8296,12 +8488,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
@@ -8327,10 +8521,6 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   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)
     {
@@ -8364,6 +8554,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;
This page took 0.049054 seconds and 4 git commands to generate.