Automatic date update in version.in
[deliverable/binutils-gdb.git] / gdb / nios2-tdep.c
index 988b9fc3a976cdbd6d66f5ee70b70cd9a007fc27..c2683b5e3a79fd2110a535258ecc44c683a2cb70 100644 (file)
@@ -1,5 +1,5 @@
 /* Target-machine dependent code for Nios II, for GDB.
 /* Target-machine dependent code for Nios II, for GDB.
-   Copyright (C) 2012-2015 Free Software Foundation, Inc.
+   Copyright (C) 2012-2019 Free Software Foundation, Inc.
    Contributed by Peter Brookes (pbrookes@altera.com)
    and Andrew Draper (adraper@altera.com).
    Contributed by Mentor Graphics, Inc.
    Contributed by Peter Brookes (pbrookes@altera.com)
    and Andrew Draper (adraper@altera.com).
    Contributed by Mentor Graphics, Inc.
 #include "value.h"
 #include "symfile.h"
 #include "arch-utils.h"
 #include "value.h"
 #include "symfile.h"
 #include "arch-utils.h"
-#include "floatformat.h"
 #include "infcall.h"
 #include "regset.h"
 #include "target-descriptions.h"
 
 /* To get entry_point_address.  */
 #include "objfiles.h"
 #include "infcall.h"
 #include "regset.h"
 #include "target-descriptions.h"
 
 /* To get entry_point_address.  */
 #include "objfiles.h"
-
-/* Nios II ISA specific encodings and macros.  */
-#include "opcode/nios2.h"
+#include <algorithm>
 
 /* Nios II specific header.  */
 #include "nios2-tdep.h"
 
 /* Nios II specific header.  */
 #include "nios2-tdep.h"
 
 /* Control debugging information emitted in this file.  */
 
 
 /* Control debugging information emitted in this file.  */
 
-static int nios2_debug = 0;
+static bool nios2_debug = false;
 
 /* The following structures are used in the cache for prologue
    analysis; see the reg_value and reg_saved tables in
    struct nios2_unwind_cache, respectively.  */
 
 
 /* The following structures are used in the cache for prologue
    analysis; see the reg_value and reg_saved tables in
    struct nios2_unwind_cache, respectively.  */
 
-/* struct reg_value is used to record that a register has the same value
-   as reg at the given offset from the start of a function.  */
+/* struct reg_value is used to record that a register has reg's initial
+   value at the start of a function plus the given constant offset.
+   If reg == 0, then the value is just the offset.
+   If reg < 0, then the value is unknown.  */
 
 struct reg_value
 {
   int reg;
 
 struct reg_value
 {
   int reg;
-  unsigned int offset;
+  int offset;
 };
 
 /* struct reg_saved is used to record that a register value has been saved at
 };
 
 /* struct reg_saved is used to record that a register value has been saved at
@@ -141,17 +140,15 @@ static int nios2_dwarf2gdb_regno_map[] =
   NIOS2_MPUACC_REGNUM     /* 48 */
 };
 
   NIOS2_MPUACC_REGNUM     /* 48 */
 };
 
+gdb_static_assert (ARRAY_SIZE (nios2_dwarf2gdb_regno_map) == NIOS2_NUM_REGS);
 
 /* Implement the dwarf2_reg_to_regnum gdbarch method.  */
 
 static int
 nios2_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dw_reg)
 {
 
 /* Implement the dwarf2_reg_to_regnum gdbarch method.  */
 
 static int
 nios2_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dw_reg)
 {
-  if (dw_reg < 0 || dw_reg > NIOS2_NUM_REGS)
-    {
-      warning (_("Dwarf-2 uses unmapped register #%d"), dw_reg);
-      return dw_reg;
-    }
+  if (dw_reg < 0 || dw_reg >= NIOS2_NUM_REGS)
+    return -1;
 
   return nios2_dwarf2gdb_regno_map[dw_reg];
 }
 
   return nios2_dwarf2gdb_regno_map[dw_reg];
 }
@@ -212,13 +209,13 @@ nios2_extract_return_value (struct gdbarch *gdbarch, struct type *valtype,
 
   /* Return values of up to 8 bytes are returned in $r2 $r3.  */
   if (len <= register_size (gdbarch, NIOS2_R2_REGNUM))
 
   /* Return values of up to 8 bytes are returned in $r2 $r3.  */
   if (len <= register_size (gdbarch, NIOS2_R2_REGNUM))
-    regcache_cooked_read (regcache, NIOS2_R2_REGNUM, valbuf);
+    regcache->cooked_read (NIOS2_R2_REGNUM, valbuf);
   else
     {
       gdb_assert (len <= (register_size (gdbarch, NIOS2_R2_REGNUM)
                          + register_size (gdbarch, NIOS2_R3_REGNUM)));
   else
     {
       gdb_assert (len <= (register_size (gdbarch, NIOS2_R2_REGNUM)
                          + register_size (gdbarch, NIOS2_R3_REGNUM)));
-      regcache_cooked_read (regcache, NIOS2_R2_REGNUM, valbuf);
-      regcache_cooked_read (regcache, NIOS2_R3_REGNUM, valbuf + 4);
+      regcache->cooked_read (NIOS2_R2_REGNUM, valbuf);
+      regcache->cooked_read (NIOS2_R3_REGNUM, valbuf + 4);
     }
 }
 
     }
 }
 
@@ -233,13 +230,13 @@ nios2_store_return_value (struct gdbarch *gdbarch, struct type *valtype,
 
   /* Return values of up to 8 bytes are returned in $r2 $r3.  */
   if (len <= register_size (gdbarch, NIOS2_R2_REGNUM))
 
   /* Return values of up to 8 bytes are returned in $r2 $r3.  */
   if (len <= register_size (gdbarch, NIOS2_R2_REGNUM))
-    regcache_cooked_write (regcache, NIOS2_R2_REGNUM, valbuf);
+    regcache->cooked_write (NIOS2_R2_REGNUM, valbuf);
   else
     {
       gdb_assert (len <= (register_size (gdbarch, NIOS2_R2_REGNUM)
                          + register_size (gdbarch, NIOS2_R3_REGNUM)));
   else
     {
       gdb_assert (len <= (register_size (gdbarch, NIOS2_R2_REGNUM)
                          + register_size (gdbarch, NIOS2_R3_REGNUM)));
-      regcache_cooked_write (regcache, NIOS2_R2_REGNUM, valbuf);
-      regcache_cooked_write (regcache, NIOS2_R3_REGNUM, valbuf + 4);
+      regcache->cooked_write (NIOS2_R2_REGNUM, valbuf);
+      regcache->cooked_write (NIOS2_R3_REGNUM, valbuf + 4);
     }
 }
 
     }
 }
 
@@ -287,8 +284,16 @@ nios2_fetch_insn (struct gdbarch *gdbarch, CORE_ADDR pc,
   unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
   unsigned int insn;
 
   unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
   unsigned int insn;
 
-  if (!safe_read_memory_integer (pc, NIOS2_OPCODE_SIZE,
-                                gdbarch_byte_order (gdbarch), &memword))
+  if (mach == bfd_mach_nios2r2)
+    {
+      if (!safe_read_memory_integer (pc, NIOS2_OPCODE_SIZE,
+                                    BFD_ENDIAN_LITTLE, &memword)
+         && !safe_read_memory_integer (pc, NIOS2_CDX_OPCODE_SIZE,
+                                       BFD_ENDIAN_LITTLE, &memword))
+       return NULL;
+    }
+  else if (!safe_read_memory_integer (pc, NIOS2_OPCODE_SIZE,
+                                     gdbarch_byte_order (gdbarch), &memword))
     return NULL;
 
   insn = (unsigned int) memword;
     return NULL;
 
   insn = (unsigned int) memword;
@@ -305,13 +310,38 @@ static int
 nios2_match_add (uint32_t insn, const struct nios2_opcode *op,
                 unsigned long mach, int *ra, int *rb, int *rc)
 {
 nios2_match_add (uint32_t insn, const struct nios2_opcode *op,
                 unsigned long mach, int *ra, int *rb, int *rc)
 {
-  if (op->match == MATCH_R1_ADD || op->match == MATCH_R1_MOV)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && (op->match == MATCH_R1_ADD || op->match == MATCH_R1_MOV))
     {
       *ra = GET_IW_R_A (insn);
       *rb = GET_IW_R_B (insn);
       *rc = GET_IW_R_C (insn);
       return 1;
     }
     {
       *ra = GET_IW_R_A (insn);
       *rb = GET_IW_R_B (insn);
       *rc = GET_IW_R_C (insn);
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_ADD || op->match == MATCH_R2_MOV)
+    {
+      *ra = GET_IW_F3X6L5_A (insn);
+      *rb = GET_IW_F3X6L5_B (insn);
+      *rc = GET_IW_F3X6L5_C (insn);
+      return 1;
+    }
+  else if (op->match == MATCH_R2_ADD_N)
+    {
+      *ra = nios2_r2_reg3_mappings[GET_IW_T3X1_A3 (insn)];
+      *rb = nios2_r2_reg3_mappings[GET_IW_T3X1_B3 (insn)];
+      *rc = nios2_r2_reg3_mappings[GET_IW_T3X1_C3 (insn)];
+      return 1;
+    }
+  else if (op->match == MATCH_R2_MOV_N)
+    {
+      *ra = GET_IW_F2_A (insn);
+      *rb = 0;
+      *rc = GET_IW_F2_B (insn);
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -322,13 +352,31 @@ static int
 nios2_match_sub (uint32_t insn, const struct nios2_opcode *op,
                 unsigned long mach, int *ra, int *rb, int *rc)
 {
 nios2_match_sub (uint32_t insn, const struct nios2_opcode *op,
                 unsigned long mach, int *ra, int *rb, int *rc)
 {
-  if (op->match == MATCH_R1_SUB)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && op->match == MATCH_R1_SUB)
     {
       *ra = GET_IW_R_A (insn);
       *rb = GET_IW_R_B (insn);
       *rc = GET_IW_R_C (insn);
       return 1;
     }
     {
       *ra = GET_IW_R_A (insn);
       *rb = GET_IW_R_B (insn);
       *rc = GET_IW_R_C (insn);
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_SUB)
+    {
+      *ra = GET_IW_F3X6L5_A (insn);
+      *rb = GET_IW_F3X6L5_B (insn);
+      *rc = GET_IW_F3X6L5_C (insn);
+      return 1;
+    }
+  else if (op->match == MATCH_R2_SUB_N)
+    {
+      *ra = nios2_r2_reg3_mappings[GET_IW_T3X1_A3 (insn)];
+      *rb = nios2_r2_reg3_mappings[GET_IW_T3X1_B3 (insn)];
+      *rc = nios2_r2_reg3_mappings[GET_IW_T3X1_C3 (insn)];
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -340,13 +388,49 @@ static int
 nios2_match_addi (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, int *ra, int *rb, int *imm)
 {
 nios2_match_addi (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, int *ra, int *rb, int *imm)
 {
-  if (op->match == MATCH_R1_ADDI)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && op->match == MATCH_R1_ADDI)
     {
       *ra = GET_IW_I_A (insn);
       *rb = GET_IW_I_B (insn);
       *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
       return 1;
     }
     {
       *ra = GET_IW_I_A (insn);
       *rb = GET_IW_I_B (insn);
       *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_ADDI)
+    {
+      *ra = GET_IW_F2I16_A (insn);
+      *rb = GET_IW_F2I16_B (insn);
+      *imm = (signed) (GET_IW_F2I16_IMM16 (insn) << 16) >> 16;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_ADDI_N || op->match == MATCH_R2_SUBI_N)
+    {
+      *ra = nios2_r2_reg3_mappings[GET_IW_T2X1I3_A3 (insn)];
+      *rb = nios2_r2_reg3_mappings[GET_IW_T2X1I3_B3 (insn)];
+      *imm = nios2_r2_asi_n_mappings[GET_IW_T2X1I3_IMM3 (insn)];
+      if (op->match == MATCH_R2_SUBI_N)
+       *imm = - (*imm);
+      return 1;
+    }
+  else if (op->match == MATCH_R2_SPADDI_N)
+    {
+      *ra = nios2_r2_reg3_mappings[GET_IW_T1I7_A3 (insn)];
+      *rb = NIOS2_SP_REGNUM;
+      *imm = GET_IW_T1I7_IMM7 (insn) << 2;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_SPINCI_N || op->match == MATCH_R2_SPDECI_N)
+    {
+      *ra = NIOS2_SP_REGNUM;
+      *rb = NIOS2_SP_REGNUM;
+      *imm = GET_IW_X1I7_IMM7 (insn) << 2;
+      if (op->match == MATCH_R2_SPDECI_N)
+       *imm = - (*imm);
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -358,13 +442,24 @@ static int
 nios2_match_orhi (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, int *ra, int *rb, unsigned int *uimm)
 {
 nios2_match_orhi (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, int *ra, int *rb, unsigned int *uimm)
 {
-  if (op->match == MATCH_R1_ORHI)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && op->match == MATCH_R1_ORHI)
     {
       *ra = GET_IW_I_A (insn);
       *rb = GET_IW_I_B (insn);
       *uimm = GET_IW_I_IMM16 (insn);
       return 1;
     }
     {
       *ra = GET_IW_I_A (insn);
       *rb = GET_IW_I_B (insn);
       *uimm = GET_IW_I_IMM16 (insn);
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_ORHI)
+    {
+      *ra = GET_IW_F2I16_A (insn);
+      *rb = GET_IW_F2I16_B (insn);
+      *uimm = GET_IW_F2I16_IMM16 (insn);
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -376,13 +471,52 @@ static int
 nios2_match_stw (uint32_t insn, const struct nios2_opcode *op,
                 unsigned long mach, int *ra, int *rb, int *imm)
 {
 nios2_match_stw (uint32_t insn, const struct nios2_opcode *op,
                 unsigned long mach, int *ra, int *rb, int *imm)
 {
-  if (op->match == MATCH_R1_STW || op->match == MATCH_R1_STWIO)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && (op->match == MATCH_R1_STW || op->match == MATCH_R1_STWIO))
     {
       *ra = GET_IW_I_A (insn);
       *rb = GET_IW_I_B (insn);
       *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
       return 1;
     }
     {
       *ra = GET_IW_I_A (insn);
       *rb = GET_IW_I_B (insn);
       *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_STW)
+    {
+      *ra = GET_IW_F2I16_A (insn);
+      *rb = GET_IW_F2I16_B (insn);
+      *imm = (signed) (GET_IW_F2I16_IMM16 (insn) << 16) >> 16;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_STWIO)
+    {
+      *ra = GET_IW_F2X4I12_A (insn);
+      *rb = GET_IW_F2X4I12_B (insn);
+      *imm = (signed) (GET_IW_F2X4I12_IMM12 (insn) << 20) >> 20;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_STW_N)
+    {
+      *ra = nios2_r2_reg3_mappings[GET_IW_T2I4_A3 (insn)];
+      *rb = nios2_r2_reg3_mappings[GET_IW_T2I4_B3 (insn)];
+      *imm = GET_IW_T2I4_IMM4 (insn) << 2;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_STWSP_N)
+    {
+      *ra = NIOS2_SP_REGNUM;
+      *rb = GET_IW_F1I5_B (insn);
+      *imm = GET_IW_F1I5_IMM5 (insn) << 2;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_STWZ_N)
+    {
+      *ra = nios2_r2_reg3_mappings[GET_IW_T1X1I6_A3 (insn)];
+      *rb = 0;
+      *imm = GET_IW_T1X1I6_IMM6 (insn) << 2;
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -394,13 +528,45 @@ static int
 nios2_match_ldw (uint32_t insn, const struct nios2_opcode *op,
                 unsigned long mach, int *ra, int *rb, int *imm)
 {
 nios2_match_ldw (uint32_t insn, const struct nios2_opcode *op,
                 unsigned long mach, int *ra, int *rb, int *imm)
 {
-  if (op->match == MATCH_R1_LDW || op->match == MATCH_R1_LDWIO)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && (op->match == MATCH_R1_LDW || op->match == MATCH_R1_LDWIO))
     {
       *ra = GET_IW_I_A (insn);
       *rb = GET_IW_I_B (insn);
       *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
       return 1;
     }
     {
       *ra = GET_IW_I_A (insn);
       *rb = GET_IW_I_B (insn);
       *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_LDW)
+    {
+      *ra = GET_IW_F2I16_A (insn);
+      *rb = GET_IW_F2I16_B (insn);
+      *imm = (signed) (GET_IW_F2I16_IMM16 (insn) << 16) >> 16;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_LDWIO)
+    {
+      *ra = GET_IW_F2X4I12_A (insn);
+      *rb = GET_IW_F2X4I12_B (insn);
+      *imm = (signed) (GET_IW_F2X4I12_IMM12 (insn) << 20) >> 20;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_LDW_N)
+    {
+      *ra = nios2_r2_reg3_mappings[GET_IW_T2I4_A3 (insn)];
+      *rb = nios2_r2_reg3_mappings[GET_IW_T2I4_B3 (insn)];
+      *imm = GET_IW_T2I4_IMM4 (insn) << 2;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_LDWSP_N)
+    {
+      *ra = NIOS2_SP_REGNUM;
+      *rb = GET_IW_F1I5_B (insn);
+      *imm = GET_IW_F1I5_IMM5 (insn) << 2;
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -411,15 +577,126 @@ static int
 nios2_match_rdctl (uint32_t insn, const struct nios2_opcode *op,
                   unsigned long mach, int *ra, int *rc)
 {
 nios2_match_rdctl (uint32_t insn, const struct nios2_opcode *op,
                   unsigned long mach, int *ra, int *rc)
 {
-  if (op->match == MATCH_R1_RDCTL)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && (op->match == MATCH_R1_RDCTL))
     {
       *ra = GET_IW_R_IMM5 (insn);
       *rc = GET_IW_R_C (insn);
       return 1;
     }
     {
       *ra = GET_IW_R_IMM5 (insn);
       *rc = GET_IW_R_C (insn);
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_RDCTL)
+    {
+      *ra = GET_IW_F3X6L5_IMM5 (insn);
+      *rc = GET_IW_F3X6L5_C (insn);
+      return 1;
+    }
+  return 0;
+}
+
+/* Match and disassemble a PUSH.N or STWM instruction.
+   Returns true on success, and fills in the operand pointers.  */
+
+static int
+nios2_match_stwm (uint32_t insn, const struct nios2_opcode *op,
+                 unsigned long mach, unsigned int *reglist,
+                 int *ra, int *imm, int *wb, int *id)
+{
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_PUSH_N)
+    {
+      *reglist = 1 << 31;
+      if (GET_IW_L5I4X1_FP (insn))
+       *reglist |= (1 << 28);
+      if (GET_IW_L5I4X1_CS (insn))
+       {
+         int val = GET_IW_L5I4X1_REGRANGE (insn);
+         *reglist |= nios2_r2_reg_range_mappings[val];
+       }
+      *ra = NIOS2_SP_REGNUM;
+      *imm = GET_IW_L5I4X1_IMM4 (insn) << 2;
+      *wb = 1;
+      *id = 0;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_STWM)
+    {
+      unsigned int rawmask = GET_IW_F1X4L17_REGMASK (insn);
+      if (GET_IW_F1X4L17_RS (insn))
+       {
+         *reglist = ((rawmask << 14) & 0x00ffc000);
+         if (rawmask & (1 << 10))
+           *reglist |= (1 << 28);
+         if (rawmask & (1 << 11))
+           *reglist |= (1 << 31);
+       }
+      else
+       *reglist = rawmask << 2;
+      *ra = GET_IW_F1X4L17_A (insn);
+      *imm = 0;
+      *wb = GET_IW_F1X4L17_WB (insn);
+      *id = GET_IW_F1X4L17_ID (insn);
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
+/* Match and disassemble a POP.N or LDWM instruction.
+   Returns true on success, and fills in the operand pointers.  */
+
+static int
+nios2_match_ldwm (uint32_t insn, const struct nios2_opcode *op,
+                 unsigned long mach, unsigned int *reglist,
+                 int *ra, int *imm, int *wb, int *id, int *ret)
+{
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_POP_N)
+    {
+      *reglist = 1 << 31;
+      if (GET_IW_L5I4X1_FP (insn))
+       *reglist |= (1 << 28);
+      if (GET_IW_L5I4X1_CS (insn))
+       {
+         int val = GET_IW_L5I4X1_REGRANGE (insn);
+         *reglist |= nios2_r2_reg_range_mappings[val];
+       }
+      *ra = NIOS2_SP_REGNUM;
+      *imm = GET_IW_L5I4X1_IMM4 (insn) << 2;
+      *wb = 1;
+      *id = 1;
+      *ret = 1;
+      return 1;
+    }
+  else if (op->match == MATCH_R2_LDWM)
+    {
+      unsigned int rawmask = GET_IW_F1X4L17_REGMASK (insn);
+      if (GET_IW_F1X4L17_RS (insn))
+       {
+         *reglist = ((rawmask << 14) & 0x00ffc000);
+         if (rawmask & (1 << 10))
+           *reglist |= (1 << 28);
+         if (rawmask & (1 << 11))
+           *reglist |= (1 << 31);
+       }
+      else
+       *reglist = rawmask << 2;
+      *ra = GET_IW_F1X4L17_A (insn);
+      *imm = 0;
+      *wb = GET_IW_F1X4L17_WB (insn);
+      *id = GET_IW_F1X4L17_ID (insn);
+      *ret = GET_IW_F1X4L17_PC (insn);
+      return 1;
+    }
+  return 0;
+}
 
 /* Match and disassemble a branch instruction, with (potentially)
    2 register operands and one immediate operand.
 
 /* Match and disassemble a branch instruction, with (potentially)
    2 register operands and one immediate operand.
@@ -440,36 +717,93 @@ nios2_match_branch (uint32_t insn, const struct nios2_opcode *op,
                    unsigned long mach, int *ra, int *rb, int *imm,
                    enum branch_condition *cond)
 {
                    unsigned long mach, int *ra, int *rb, int *imm,
                    enum branch_condition *cond)
 {
-  switch (op->match)
-    {
-    case MATCH_R1_BR:
-      *cond = branch_none;
-      break;
-    case MATCH_R1_BEQ:
-      *cond = branch_eq;
-      break;
-    case MATCH_R1_BNE:
-      *cond = branch_ne;
-      break;
-    case MATCH_R1_BGE:
-      *cond = branch_ge;
-      break;
-    case MATCH_R1_BGEU:
-      *cond = branch_geu;
-      break;
-    case MATCH_R1_BLT:
-      *cond = branch_lt;
-      break;
-    case MATCH_R1_BLTU:
-      *cond = branch_ltu;
-      break;
-    default:
-      return 0;
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2)
+    {
+      switch (op->match)
+       {
+       case MATCH_R1_BR:
+         *cond = branch_none;
+         break;
+       case MATCH_R1_BEQ:
+         *cond = branch_eq;
+         break;
+       case MATCH_R1_BNE:
+         *cond = branch_ne;
+         break;
+       case MATCH_R1_BGE:
+         *cond = branch_ge;
+         break;
+       case MATCH_R1_BGEU:
+         *cond = branch_geu;
+         break;
+       case MATCH_R1_BLT:
+         *cond = branch_lt;
+         break;
+       case MATCH_R1_BLTU:
+         *cond = branch_ltu;
+         break;
+       default:
+         return 0;
+       }
+      *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
+      *ra = GET_IW_I_A (insn);
+      *rb = GET_IW_I_B (insn);
+      return 1;
     }
     }
-  *imm = (signed) (GET_IW_I_IMM16 (insn) << 16) >> 16;
-  *ra = GET_IW_I_A (insn);
-  *rb = GET_IW_I_B (insn);
-  return 1;
+  else
+    {
+      switch (op->match)
+       {
+       case MATCH_R2_BR_N:
+         *cond = branch_none;
+         *ra = NIOS2_Z_REGNUM;
+         *rb = NIOS2_Z_REGNUM;
+         *imm = (signed) ((GET_IW_I10_IMM10 (insn) << 1) << 21) >> 21;
+         return 1;
+       case MATCH_R2_BEQZ_N:
+         *cond = branch_eq;
+         *ra = nios2_r2_reg3_mappings[GET_IW_T1I7_A3 (insn)];
+         *rb = NIOS2_Z_REGNUM;
+         *imm = (signed) ((GET_IW_T1I7_IMM7 (insn) << 1) << 24) >> 24;
+         return 1;
+       case MATCH_R2_BNEZ_N:
+         *cond = branch_ne;
+         *ra = nios2_r2_reg3_mappings[GET_IW_T1I7_A3 (insn)];
+         *rb = NIOS2_Z_REGNUM;
+         *imm = (signed) ((GET_IW_T1I7_IMM7 (insn) << 1) << 24) >> 24;
+         return 1;
+       case MATCH_R2_BR:
+         *cond = branch_none;
+         break;
+       case MATCH_R2_BEQ:
+         *cond = branch_eq;
+         break;
+       case MATCH_R2_BNE:
+         *cond = branch_ne;
+         break;
+       case MATCH_R2_BGE:
+         *cond = branch_ge;
+         break;
+       case MATCH_R2_BGEU:
+         *cond = branch_geu;
+         break;
+       case MATCH_R2_BLT:
+         *cond = branch_lt;
+         break;
+       case MATCH_R2_BLTU:
+         *cond = branch_ltu;
+         break;
+       default:
+         return 0;
+       }
+      *ra = GET_IW_F2I16_A (insn);
+      *rb = GET_IW_F2I16_B (insn);
+      *imm = (signed) (GET_IW_F2I16_IMM16 (insn) << 16) >> 16;
+      return 1;
+    }
+  return 0;
 }
 
 /* Match and disassemble a direct jump instruction, with an
 }
 
 /* Match and disassemble a direct jump instruction, with an
@@ -480,11 +814,20 @@ static int
 nios2_match_jmpi (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, unsigned int *uimm)
 {
 nios2_match_jmpi (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, unsigned int *uimm)
 {
-  if (op->match == MATCH_R1_JMPI)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && op->match == MATCH_R1_JMPI)
     {
       *uimm = GET_IW_J_IMM26 (insn) << 2;
       return 1;
     }
     {
       *uimm = GET_IW_J_IMM26 (insn) << 2;
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_JMPI)
+    {
+      *uimm = GET_IW_L26_IMM26 (insn) << 2;
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -496,11 +839,20 @@ static int
 nios2_match_calli (uint32_t insn, const struct nios2_opcode *op,
                   unsigned long mach, unsigned int *uimm)
 {
 nios2_match_calli (uint32_t insn, const struct nios2_opcode *op,
                   unsigned long mach, unsigned int *uimm)
 {
-  if (op->match == MATCH_R1_CALL)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && op->match == MATCH_R1_CALL)
     {
       *uimm = GET_IW_J_IMM26 (insn) << 2;
       return 1;
     }
     {
       *uimm = GET_IW_J_IMM26 (insn) << 2;
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_CALL)
+    {
+      *uimm = GET_IW_L26_IMM26 (insn) << 2;
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -512,23 +864,49 @@ static int
 nios2_match_jmpr (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, int *ra)
 {
 nios2_match_jmpr (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, int *ra)
 {
-  switch (op->match)
-    {
-    case MATCH_R1_JMP:
-      *ra = GET_IW_I_A (insn);
-      return 1;
-    case MATCH_R1_RET:
-      *ra = NIOS2_RA_REGNUM;
-      return 1;
-    case MATCH_R1_ERET:
-      *ra = NIOS2_EA_REGNUM;
-      return 1;
-    case MATCH_R1_BRET:
-      *ra = NIOS2_BA_REGNUM;
-      return 1;
-    default:
-      return 0;
-    }
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2)
+    switch (op->match)
+      {
+      case MATCH_R1_JMP:
+       *ra = GET_IW_I_A (insn);
+       return 1;
+      case MATCH_R1_RET:
+       *ra = NIOS2_RA_REGNUM;
+       return 1;
+      case MATCH_R1_ERET:
+       *ra = NIOS2_EA_REGNUM;
+       return 1;
+      case MATCH_R1_BRET:
+       *ra = NIOS2_BA_REGNUM;
+       return 1;
+      default:
+       return 0;
+      }
+  else
+    switch (op->match)
+      {
+      case MATCH_R2_JMP:
+       *ra = GET_IW_F2I16_A (insn);
+       return 1;
+      case MATCH_R2_JMPR_N:
+       *ra = GET_IW_F1X1_A (insn);
+       return 1;
+      case MATCH_R2_RET:
+      case MATCH_R2_RET_N:
+       *ra = NIOS2_RA_REGNUM;
+       return 1;
+      case MATCH_R2_ERET:
+       *ra = NIOS2_EA_REGNUM;
+       return 1;
+      case MATCH_R2_BRET:
+       *ra = NIOS2_BA_REGNUM;
+       return 1;
+      default:
+       return 0;
+      }
+  return 0;
 }
 
 /* Match and disassemble an indirect call instruction, with a register
 }
 
 /* Match and disassemble an indirect call instruction, with a register
@@ -538,11 +916,25 @@ static int
 nios2_match_callr (uint32_t insn, const struct nios2_opcode *op,
                   unsigned long mach, int *ra)
 {
 nios2_match_callr (uint32_t insn, const struct nios2_opcode *op,
                   unsigned long mach, int *ra)
 {
-  if (op->match == MATCH_R1_CALLR)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && op->match == MATCH_R1_CALLR)
     {
       *ra = GET_IW_I_A (insn);
       return 1;
     }
     {
       *ra = GET_IW_I_A (insn);
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_CALLR)
+    {
+      *ra = GET_IW_F2I16_A (insn);
+      return 1;
+    }
+  else if (op->match == MATCH_R2_CALLR_N)
+    {
+      *ra = GET_IW_F1X1_A (insn);
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -553,11 +945,25 @@ static int
 nios2_match_break (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, unsigned int *uimm)
 {
 nios2_match_break (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, unsigned int *uimm)
 {
-  if (op->match == MATCH_R1_BREAK)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && op->match == MATCH_R1_BREAK)
     {
       *uimm = GET_IW_R_IMM5 (insn);
       return 1;
     }
     {
       *uimm = GET_IW_R_IMM5 (insn);
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_BREAK)
+    {
+      *uimm = GET_IW_F3X6L5_IMM5 (insn);
+      return 1;
+    }
+  else if (op->match == MATCH_R2_BREAK_N)
+    {
+      *uimm = GET_IW_X2L5_IMM5 (insn);
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -568,11 +974,25 @@ static int
 nios2_match_trap (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, unsigned int *uimm)
 {
 nios2_match_trap (uint32_t insn, const struct nios2_opcode *op,
                  unsigned long mach, unsigned int *uimm)
 {
-  if (op->match == MATCH_R1_TRAP)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2 && op->match == MATCH_R1_TRAP)
     {
       *uimm = GET_IW_R_IMM5 (insn);
       return 1;
     }
     {
       *uimm = GET_IW_R_IMM5 (insn);
       return 1;
     }
+  else if (!is_r2)
+    return 0;
+  else if (op->match == MATCH_R2_TRAP)
+    {
+      *uimm = GET_IW_F3X6L5_IMM5 (insn);
+      return 1;
+    }
+  else if (op->match == MATCH_R2_TRAP_N)
+    {
+      *uimm = GET_IW_X2L5_IMM5 (insn);
+      return 1;
+    }
   return 0;
 }
 
   return 0;
 }
 
@@ -589,6 +1009,7 @@ nios2_in_epilogue_p (struct gdbarch *gdbarch,
                     CORE_ADDR start_pc)
 {
   unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
                     CORE_ADDR start_pc)
 {
   unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+  int is_r2 = (mach == bfd_mach_nios2r2);
   /* Maximum number of possibly-epilogue instructions to check.
      Note that this number should not be too large, else we can
      potentially end up iterating through unmapped memory.  */
   /* Maximum number of possibly-epilogue instructions to check.
      Note that this number should not be too large, else we can
      potentially end up iterating through unmapped memory.  */
@@ -597,6 +1018,7 @@ nios2_in_epilogue_p (struct gdbarch *gdbarch,
   const struct nios2_opcode *op = NULL;
   unsigned int uimm;
   int imm;
   const struct nios2_opcode *op = NULL;
   unsigned int uimm;
   int imm;
+  int wb, id, ret;
   int ra, rb, rc;
   enum branch_condition cond;
   CORE_ADDR pc;
   int ra, rb, rc;
   enum branch_condition cond;
   CORE_ADDR pc;
@@ -605,17 +1027,41 @@ nios2_in_epilogue_p (struct gdbarch *gdbarch,
   if (current_pc <= start_pc)
     return 0;
 
   if (current_pc <= start_pc)
     return 0;
 
-  /* Find the previous instruction before current_pc.
-     For the moment we will assume that all instructions are the
-     same size here.  */
-  pc = current_pc - NIOS2_OPCODE_SIZE;
+  /* Find the previous instruction before current_pc.  For R2, it might
+     be either a 16-bit or 32-bit instruction; the only way to know for
+     sure is to scan through from the beginning of the function,
+     disassembling as we go.  */
+  if (is_r2)
+    for (pc = start_pc; ; )
+      {
+       op = nios2_fetch_insn (gdbarch, pc, &insn);
+       if (op == NULL)
+         return 0;
+       if (pc + op->size < current_pc)
+         pc += op->size;
+       else
+         break;
+       /* We can skip over insns to a forward branch target.  Since
+          the branch offset is relative to the next instruction,
+          it's correct to do this after incrementing the pc above.  */
+       if (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond)
+           && imm > 0
+           && pc + imm < current_pc)
+         pc += imm;
+      }
+  /* Otherwise just go back to the previous 32-bit insn.  */
+  else
+    pc = current_pc - NIOS2_OPCODE_SIZE;
 
   /* Beginning with the previous instruction we just located, check whether
      we are in a sequence of at least one stack adjustment instruction.
      Possible instructions here include:
         ADDI sp, sp, n
         ADD sp, sp, rn
 
   /* Beginning with the previous instruction we just located, check whether
      we are in a sequence of at least one stack adjustment instruction.
      Possible instructions here include:
         ADDI sp, sp, n
         ADD sp, sp, rn
-        LDW sp, n(sp)  */
+        LDW sp, n(sp)
+        SPINCI.N n
+        LDWSP.N sp, n(sp)
+        LDWM {reglist}, (sp)++, wb */
   for (ninsns = 0; ninsns < max_insns; ninsns++)
     {
       int ok = 0;
   for (ninsns = 0; ninsns < max_insns; ninsns++)
     {
       int ok = 0;
@@ -633,6 +1079,9 @@ nios2_in_epilogue_p (struct gdbarch *gdbarch,
        ok = (rc == NIOS2_SP_REGNUM);
       else if (nios2_match_ldw (insn, op, mach, &ra, &rb, &imm))
        ok = (rb == NIOS2_SP_REGNUM);
        ok = (rc == NIOS2_SP_REGNUM);
       else if (nios2_match_ldw (insn, op, mach, &ra, &rb, &imm))
        ok = (rb == NIOS2_SP_REGNUM);
+      else if (nios2_match_ldwm (insn, op, mach, &uimm, &ra,
+                                &imm, &wb, &ret, &id))
+       ok = (ra == NIOS2_SP_REGNUM && wb && id);
       if (!ok)
        break;
     }
       if (!ok)
        break;
     }
@@ -648,9 +1097,12 @@ nios2_in_epilogue_p (struct gdbarch *gdbarch,
     return 1;
 
   /* The next instruction following the stack adjustments must be a
     return 1;
 
   /* The next instruction following the stack adjustments must be a
-     return, jump, or unconditional branch.  */
+     return, jump, or unconditional branch, or a CDX pop.n or ldwm
+     that does an implicit return.  */
   if (nios2_match_jmpr (insn, op, mach, &ra)
       || nios2_match_jmpi (insn, op, mach, &uimm)
   if (nios2_match_jmpr (insn, op, mach, &ra)
       || nios2_match_jmpi (insn, op, mach, &uimm)
+      || (nios2_match_ldwm (insn, op, mach, &uimm, &ra, &imm, &wb, &id, &ret)
+         && ret)
       || (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond)
          && cond == branch_none))
     return 1;
       || (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond)
          && cond == branch_none))
     return 1;
@@ -658,10 +1110,10 @@ nios2_in_epilogue_p (struct gdbarch *gdbarch,
   return 0;
 }
 
   return 0;
 }
 
-/* Implement the in_function_epilogue_p gdbarch method.  */
+/* Implement the stack_frame_destroyed_p gdbarch method.  */
 
 static int
 
 static int
-nios2_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
+nios2_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
 {
   CORE_ADDR func_addr;
 
 {
   CORE_ADDR func_addr;
 
@@ -684,10 +1136,12 @@ nios2_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
          mov    ra, r8
 
      2) A stack adjustment and save of R4-R7 for varargs functions.
          mov    ra, r8
 
      2) A stack adjustment and save of R4-R7 for varargs functions.
-        This is typically merged with item 3.
+        For R2 CDX this is typically handled with a STWM, otherwise
+       this is typically merged with item 3.
 
 
-     3) A stack adjustment and save of the callee-saved registers;
-       typically an explicit SP decrement and individual register
+     3) A stack adjustment and save of the callee-saved registers.
+        For R2 CDX these are typically handled with a PUSH.N or STWM,
+       otherwise as an explicit SP decrement and individual register
        saves.
 
         There may also be a stack switch here in an exception handler
        saves.
 
         There may also be a stack switch here in an exception handler
@@ -697,22 +1151,29 @@ nios2_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc)
          stw    sp, constant(rx)
          mov    sp, rx
 
          stw    sp, constant(rx)
          mov    sp, rx
 
-     5) A frame pointer save, which can be either a MOV or ADDI.
+     4) A frame pointer save, which can be either a MOV or ADDI.
 
 
-     6) A further stack pointer adjustment.  This is normally included
-        adjustment in step 4 unless the total adjustment is too large
+     5) A further stack pointer adjustment.  This is normally included
+        adjustment in step 3 unless the total adjustment is too large
        to be done in one step.
 
      7) A stack overflow check, which can take either of these forms:
          bgeu   sp, rx, +8
        to be done in one step.
 
      7) A stack overflow check, which can take either of these forms:
          bgeu   sp, rx, +8
-         break  3
+         trap  3
        or
          bltu   sp, rx, .Lstack_overflow
          ...
        .Lstack_overflow:
        or
          bltu   sp, rx, .Lstack_overflow
          ...
        .Lstack_overflow:
-         break  3
-        If present, this is inserted after the stack pointer adjustments
-       for steps 3, 4, and 6.
+         trap  3
+         
+       Older versions of GCC emitted "break 3" instead of "trap 3" here,
+       so we check for both cases.
+
+       Older GCC versions emitted stack overflow checks after the SP
+       adjustments in both steps 3 and 4.  Starting with GCC 6, there is
+       at most one overflow check, which is placed before the first
+       stack adjustment for R2 CDX and after the first stack adjustment
+       otherwise.
 
     The prologue instructions may be combined or interleaved with other
     instructions.
 
     The prologue instructions may be combined or interleaved with other
     instructions.
@@ -734,7 +1195,6 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
      Note that this number should not be too large, else we can
      potentially end up iterating through unmapped memory.  */
   int ninsns, max_insns = 50;
      Note that this number should not be too large, else we can
      potentially end up iterating through unmapped memory.  */
   int ninsns, max_insns = 50;
-  int regno;
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
 
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
 
@@ -744,8 +1204,6 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
   struct reg_value *value = cache->reg_value;
   struct reg_value temp_value[NIOS2_NUM_REGS];
 
   struct reg_value *value = cache->reg_value;
   struct reg_value temp_value[NIOS2_NUM_REGS];
 
-  int i;
-
   /* Save the starting PC so we can correct the pc after running
      through the prolog, using symbol info.  */
   CORE_ADDR pc = start_pc;
   /* Save the starting PC so we can correct the pc after running
      through the prolog, using symbol info.  */
   CORE_ADDR pc = start_pc;
@@ -782,7 +1240,7 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
       int ra, rb, rc, imm;
       unsigned int uimm;
       unsigned int reglist;
       int ra, rb, rc, imm;
       unsigned int uimm;
       unsigned int reglist;
-      int wb, ret;
+      int wb, id, ret;
       enum branch_condition cond;
 
       if (pc == current_pc)
       enum branch_condition cond;
 
       if (pc == current_pc)
@@ -805,7 +1263,12 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
       pc += op->size;
 
       if (nios2_debug)
       pc += op->size;
 
       if (nios2_debug)
-       fprintf_unfiltered (gdb_stdlog, "[%08X]", insn);
+       {
+         if (op->size == 2)
+           fprintf_unfiltered (gdb_stdlog, "[%04X]", insn & 0xffff);
+         else
+           fprintf_unfiltered (gdb_stdlog, "[%08X]", insn);
+       }
 
       /* The following instructions can appear in the prologue.  */
 
 
       /* The following instructions can appear in the prologue.  */
 
@@ -822,7 +1285,7 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
 
              /* If any registers were saved on the stack before then
                 we can't backtrace into them now.  */
 
              /* If any registers were saved on the stack before then
                 we can't backtrace into them now.  */
-             for (i = 0 ; i < NIOS2_NUM_REGS ; i++)
+             for (int i = 0 ; i < NIOS2_NUM_REGS ; i++)
                {
                  if (cache->reg_saved[i].basereg == NIOS2_SP_REGNUM)
                    cache->reg_saved[i].basereg = -1;
                {
                  if (cache->reg_saved[i].basereg == NIOS2_SP_REGNUM)
                    cache->reg_saved[i].basereg = -1;
@@ -928,9 +1391,7 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
          if (orig > 0
              && (value[rb].offset == 0
                  || (orig == NIOS2_EA_REGNUM && value[rb].offset == -4))
          if (orig > 0
              && (value[rb].offset == 0
                  || (orig == NIOS2_EA_REGNUM && value[rb].offset == -4))
-             && ((value[ra].reg == NIOS2_SP_REGNUM
-                  && cache->reg_saved[orig].basereg != NIOS2_SP_REGNUM)
-                 || cache->reg_saved[orig].basereg == -1))
+             && value[ra].reg == NIOS2_SP_REGNUM)
            {
              if (pc < current_pc)
                {
            {
              if (pc < current_pc)
                {
@@ -949,6 +1410,41 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
            break;
         }
 
            break;
         }
 
+      else if (nios2_match_stwm (insn, op, mach,
+                                &reglist, &ra, &imm, &wb, &id))
+       {
+         /* PUSH.N {reglist}, adjust
+            or
+            STWM {reglist}, --(SP)[, writeback] */
+         int off = 0;
+
+         if (ra != NIOS2_SP_REGNUM || id != 0)
+           /* This is a non-stack-push memory write and cannot be
+              part of the prologue.  */
+           break;
+
+         for (int i = 31; i >= 0; i--)
+           if (reglist & (1 << i))
+             {
+               int orig = value[i].reg;
+               
+               off += 4;
+               if (orig > 0 && value[i].offset == 0 && pc < current_pc)
+                 {
+                   cache->reg_saved[orig].basereg
+                     = value[NIOS2_SP_REGNUM].reg;
+                   cache->reg_saved[orig].addr
+                     = value[NIOS2_SP_REGNUM].offset - off;
+                 }
+             }
+
+         if (wb)
+           value[NIOS2_SP_REGNUM].offset -= off;
+         value[NIOS2_SP_REGNUM].offset -= imm;
+
+         prologue_end = pc;
+       }
+
       else if (nios2_match_rdctl (insn, op, mach, &ra, &rc))
        {
          /* RDCTL rC, ctlN
       else if (nios2_match_rdctl (insn, op, mach, &ra, &rc))
        {
          /* RDCTL rC, ctlN
@@ -972,9 +1468,9 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
                 if ra has been stored into r8 beforehand and if it's
                 before the stack adjust.
                 Note mcount corrupts r2-r3, r9-r15 & ra.  */
                 if ra has been stored into r8 beforehand and if it's
                 before the stack adjust.
                 Note mcount corrupts r2-r3, r9-r15 & ra.  */
-             for (i = 2 ; i <= 3 ; i++)
+             for (int i = 2 ; i <= 3 ; i++)
                value[i].reg = -1;
                value[i].reg = -1;
-             for (i = 9 ; i <= 15 ; i++)
+             for (int i = 9 ; i <= 15 ; i++)
                value[i].reg = -1;
              value[NIOS2_RA_REGNUM].reg = -1;
 
                value[i].reg = -1;
              value[NIOS2_RA_REGNUM].reg = -1;
 
@@ -995,14 +1491,15 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
          else if (cond == branch_geu)
            {
              /* BGEU sp, rx, +8
          else if (cond == branch_geu)
            {
              /* BGEU sp, rx, +8
-                BREAK 3
+                TRAP 3  (or BREAK 3)
                 This instruction sequence is used in stack checking;
                 we can ignore it.  */
              unsigned int next_insn;
              const struct nios2_opcode *next_op
                = nios2_fetch_insn (gdbarch, pc, &next_insn);
              if (next_op != NULL
                 This instruction sequence is used in stack checking;
                 we can ignore it.  */
              unsigned int next_insn;
              const struct nios2_opcode *next_op
                = nios2_fetch_insn (gdbarch, pc, &next_insn);
              if (next_op != NULL
-                 && nios2_match_break (next_insn, op, mach, &uimm))
+                 && (nios2_match_trap (next_insn, op, mach, &uimm)
+                     || nios2_match_break (next_insn, op, mach, &uimm)))
                pc += next_op->size;
              else
                break;
                pc += next_op->size;
              else
                break;
@@ -1010,13 +1507,14 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
          else if (cond == branch_ltu)
            {
              /* BLTU sp, rx, .Lstackoverflow
          else if (cond == branch_ltu)
            {
              /* BLTU sp, rx, .Lstackoverflow
-                If the location branched to holds a BREAK 3 instruction
-                then this is also stack overflow detection.  */
+                If the location branched to holds a TRAP or BREAK
+                instruction then this is also stack overflow detection.  */
              unsigned int next_insn;
              const struct nios2_opcode *next_op
                = nios2_fetch_insn (gdbarch, pc + imm, &next_insn);
              if (next_op != NULL
              unsigned int next_insn;
              const struct nios2_opcode *next_op
                = nios2_fetch_insn (gdbarch, pc + imm, &next_insn);
              if (next_op != NULL
-                 && nios2_match_break (next_insn, op, mach, &uimm))
+                 && (nios2_match_trap (next_insn, op, mach, &uimm)
+                     || nios2_match_break (next_insn, op, mach, &uimm)))
                ;
              else
                break;
                ;
              else
                break;
@@ -1025,11 +1523,16 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
            break;
        }
 
            break;
        }
 
-      /* All other calls or jumps (including returns) terminate 
+      /* All other calls, jumps, returns, TRAPs, or BREAKs terminate
         the prologue.  */
       else if (nios2_match_callr (insn, op, mach, &ra)
               || nios2_match_jmpr (insn, op, mach, &ra)
         the prologue.  */
       else if (nios2_match_callr (insn, op, mach, &ra)
               || nios2_match_jmpr (insn, op, mach, &ra)
-              || nios2_match_jmpi (insn, op, mach, &uimm))
+              || nios2_match_jmpi (insn, op, mach, &uimm)
+              || (nios2_match_ldwm (insn, op, mach, &reglist, &ra,
+                                    &imm, &wb, &id, &ret)
+                  && ret)
+              || nios2_match_trap (insn, op, mach, &uimm)
+              || nios2_match_break (insn, op, mach, &uimm))
        break;
     }
 
        break;
     }
 
@@ -1117,14 +1620,14 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
 
   /* Adjust all the saved registers such that they contain addresses
      instead of offsets.  */
 
   /* Adjust all the saved registers such that they contain addresses
      instead of offsets.  */
-  for (i = 0; i < NIOS2_NUM_REGS; i++)
+  for (int i = 0; i < NIOS2_NUM_REGS; i++)
     if (cache->reg_saved[i].basereg == NIOS2_SP_REGNUM)
       {
        cache->reg_saved[i].basereg = NIOS2_Z_REGNUM;
        cache->reg_saved[i].addr += frame_high;
       }
 
     if (cache->reg_saved[i].basereg == NIOS2_SP_REGNUM)
       {
        cache->reg_saved[i].basereg = NIOS2_Z_REGNUM;
        cache->reg_saved[i].addr += frame_high;
       }
 
-  for (i = 0; i < NIOS2_NUM_REGS; i++)
+  for (int i = 0; i < NIOS2_NUM_REGS; i++)
     if (cache->reg_saved[i].basereg == NIOS2_GP_REGNUM)
       {
        CORE_ADDR gp = get_frame_register_unsigned (this_frame,
     if (cache->reg_saved[i].basereg == NIOS2_GP_REGNUM)
       {
        CORE_ADDR gp = get_frame_register_unsigned (this_frame,
@@ -1181,7 +1684,7 @@ nios2_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
         = skip_prologue_using_sal (gdbarch, func_addr);
 
       if (post_prologue_pc != 0)
         = skip_prologue_using_sal (gdbarch, func_addr);
 
       if (post_prologue_pc != 0)
-        return max (start_pc, post_prologue_pc);
+        return std::max (start_pc, post_prologue_pc);
     }
 
   /* Prologue analysis does the rest....  */
     }
 
   /* Prologue analysis does the rest....  */
@@ -1189,9 +1692,34 @@ nios2_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
   return nios2_analyze_prologue (gdbarch, start_pc, start_pc, &cache, NULL);
 }
 
   return nios2_analyze_prologue (gdbarch, start_pc, start_pc, &cache, NULL);
 }
 
-/* Implement the breakpoint_from_pc gdbarch hook.
+/* Implement the breakpoint_kind_from_pc gdbarch method.  */
+
+static int
+nios2_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
+{
+  unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+
+  if (mach == bfd_mach_nios2r2)
+    {
+      unsigned int insn;
+      const struct nios2_opcode *op
+       = nios2_fetch_insn (gdbarch, *pcptr, &insn);
+
+      if (op && op->size == NIOS2_CDX_OPCODE_SIZE)
+       return NIOS2_CDX_OPCODE_SIZE;
+      else
+       return NIOS2_OPCODE_SIZE;
+    }
+  else
+    return NIOS2_OPCODE_SIZE;
+}
+
+/* Implement the sw_breakpoint_from_kind gdbarch method.  */
 
 
-   The Nios II ABI for Linux says: "Userspace programs should not use
+static const gdb_byte *
+nios2_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
+{
+/* The Nios II ABI for Linux says: "Userspace programs should not use
    the break instruction and userspace debuggers should not insert
    one." and "Userspace breakpoints are accomplished using the trap
    instruction with immediate operand 31 (all ones)."
    the break instruction and userspace debuggers should not insert
    one." and "Userspace breakpoints are accomplished using the trap
    instruction with immediate operand 31 (all ones)."
@@ -1199,37 +1727,49 @@ nios2_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
    So, we use "trap 31" consistently as the breakpoint on bare-metal
    as well as Linux targets.  */
 
    So, we use "trap 31" consistently as the breakpoint on bare-metal
    as well as Linux targets.  */
 
-static const gdb_byte*
-nios2_breakpoint_from_pc (struct gdbarch *gdbarch, CORE_ADDR *bp_addr,
-                         int *bp_size)
-{
-  enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
-  unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+  /* R2 trap encoding:
+     ((0x2d << 26) | (0x1f << 21) | (0x1d << 16) | (0x20 << 0))
+     0xb7fd0020
+     CDX trap.n encoding:
+     ((0xd << 12) | (0x1f << 6) | (0x9 << 0))
+     0xd7c9
+     Note that code is always little-endian on R2.  */
+  *size = kind;
 
 
-  /* R1 trap encoding:
-     ((0x1d << 17) | (0x2d << 11) | (0x1f << 6) | (0x3a << 0))
-     0x003b6ffa */
-  static const gdb_byte r1_breakpoint_le[] = {0xfa, 0x6f, 0x3b, 0x0};
-  static const gdb_byte r1_breakpoint_be[] = {0x0, 0x3b, 0x6f, 0xfa};
-  *bp_size = NIOS2_OPCODE_SIZE;
-  if (byte_order_for_code == BFD_ENDIAN_BIG)
-    return r1_breakpoint_be;
+  if (kind == NIOS2_CDX_OPCODE_SIZE)
+    {
+      static const gdb_byte cdx_breakpoint_le[] = {0xc9, 0xd7};
+
+      return cdx_breakpoint_le;
+    }
   else
   else
-    return r1_breakpoint_le;
-}
+    {
+      unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
 
 
-/* Implement the print_insn gdbarch method.  */
+      if (mach == bfd_mach_nios2r2)
+       {
+         static const gdb_byte r2_breakpoint_le[] = {0x20, 0x00, 0xfd, 0xb7};
 
 
-static int
-nios2_print_insn (bfd_vma memaddr, disassemble_info *info)
-{
-  if (info->endian == BFD_ENDIAN_BIG)
-    return print_insn_big_nios2 (memaddr, info);
-  else
-    return print_insn_little_nios2 (memaddr, info);
+         return r2_breakpoint_le;
+       }
+      else
+       {
+         enum bfd_endian byte_order_for_code
+           = gdbarch_byte_order_for_code (gdbarch);
+         /* R1 trap encoding:
+            ((0x1d << 17) | (0x2d << 11) | (0x1f << 6) | (0x3a << 0))
+            0x003b6ffa */
+         static const gdb_byte r1_breakpoint_le[] = {0xfa, 0x6f, 0x3b, 0x0};
+         static const gdb_byte r1_breakpoint_be[] = {0x0, 0x3b, 0x6f, 0xfa};
+
+         if (byte_order_for_code == BFD_ENDIAN_BIG)
+           return r1_breakpoint_be;
+         else
+           return r1_breakpoint_le;
+       }
+    }
 }
 
 }
 
-
 /* Implement the frame_align gdbarch method.  */
 
 static CORE_ADDR
 /* Implement the frame_align gdbarch method.  */
 
 static CORE_ADDR
@@ -1257,30 +1797,19 @@ nios2_return_value (struct gdbarch *gdbarch, struct value *function,
   return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
   return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
-/* Implement the dummy_id gdbarch method.  */
-
-static struct frame_id
-nios2_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  return frame_id_build
-    (get_frame_register_unsigned (this_frame, NIOS2_SP_REGNUM),
-     get_frame_pc (this_frame));
-}
-
 /* Implement the push_dummy_call gdbarch method.  */
 
 static CORE_ADDR
 nios2_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                        struct regcache *regcache, CORE_ADDR bp_addr,
                        int nargs, struct value **args, CORE_ADDR sp,
 /* Implement the push_dummy_call gdbarch method.  */
 
 static CORE_ADDR
 nios2_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
                        struct regcache *regcache, CORE_ADDR bp_addr,
                        int nargs, struct value **args, CORE_ADDR sp,
-                       int struct_return, CORE_ADDR struct_addr)
+                      function_call_return_method return_method,
+                      CORE_ADDR struct_addr)
 {
   int argreg;
 {
   int argreg;
-  int float_argreg;
   int argnum;
   int argnum;
-  int len = 0;
+  int arg_space = 0;
   int stack_offset = 0;
   int stack_offset = 0;
-  CORE_ADDR func_addr = find_function_addr (function, NULL);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   /* Set the return address register to point to the entry point of
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   /* Set the return address register to point to the entry point of
@@ -1289,15 +1818,15 @@ nios2_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
 
   /* Now make space on the stack for the args.  */
   for (argnum = 0; argnum < nargs; argnum++)
 
   /* Now make space on the stack for the args.  */
   for (argnum = 0; argnum < nargs; argnum++)
-    len += align_up (TYPE_LENGTH (value_type (args[argnum])), 4);
-  sp -= len;
+    arg_space += align_up (TYPE_LENGTH (value_type (args[argnum])), 4);
+  sp -= arg_space;
 
   /* Initialize the register pointer.  */
   argreg = NIOS2_FIRST_ARGREG;
 
   /* The struct_return pointer occupies the first parameter-passing
      register.  */
 
   /* Initialize the register pointer.  */
   argreg = NIOS2_FIRST_ARGREG;
 
   /* The struct_return pointer occupies the first parameter-passing
      register.  */
-  if (struct_return)
+  if (return_method == return_method_struct)
     regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
 
   /* Now load as many as possible of the first arguments into
     regcache_cooked_write_unsigned (regcache, argreg++, struct_addr);
 
   /* Now load as many as possible of the first arguments into
@@ -1306,11 +1835,9 @@ nios2_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   for (argnum = 0; argnum < nargs; argnum++)
     {
       const gdb_byte *val;
   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);
       struct value *arg = args[argnum];
       struct type *arg_type = check_typedef (value_type (arg));
       int len = TYPE_LENGTH (arg_type);
-      enum type_code typecode = TYPE_CODE (arg_type);
 
       val = value_contents (arg);
 
 
       val = value_contents (arg);
 
@@ -1361,14 +1888,6 @@ nios2_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame)
   return extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
 }
 
   return extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
 }
 
-/* Implement the unwind_sp gdbarch method.  */
-
-static CORE_ADDR
-nios2_unwind_sp (struct gdbarch *gdbarch, struct frame_info *this_frame)
-{
-  return frame_unwind_register_unsigned (this_frame, NIOS2_SP_REGNUM);
-}
-
 /* Use prologue analysis to fill in the register cache
    *THIS_PROLOGUE_CACHE for THIS_FRAME.  This function initializes
    *THIS_PROLOGUE_CACHE first.  */
 /* Use prologue analysis to fill in the register cache
    *THIS_PROLOGUE_CACHE for THIS_FRAME.  This function initializes
    *THIS_PROLOGUE_CACHE first.  */
@@ -1380,10 +1899,9 @@ nios2_frame_unwind_cache (struct frame_info *this_frame,
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR current_pc;
   struct nios2_unwind_cache *cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR current_pc;
   struct nios2_unwind_cache *cache;
-  int i;
 
   if (*this_prologue_cache)
 
   if (*this_prologue_cache)
-    return *this_prologue_cache;
+    return (struct nios2_unwind_cache *) *this_prologue_cache;
 
   cache = FRAME_OBSTACK_ZALLOC (struct nios2_unwind_cache);
   *this_prologue_cache = cache;
 
   cache = FRAME_OBSTACK_ZALLOC (struct nios2_unwind_cache);
   *this_prologue_cache = cache;
@@ -1488,10 +2006,9 @@ nios2_stub_frame_cache (struct frame_info *this_frame, void **this_cache)
   CORE_ADDR stack_addr;
   struct trad_frame_cache *this_trad_cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   CORE_ADDR stack_addr;
   struct trad_frame_cache *this_trad_cache;
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
-  int num_regs = gdbarch_num_regs (gdbarch);
 
   if (*this_cache != NULL)
 
   if (*this_cache != NULL)
-    return *this_cache;
+    return (struct trad_frame_cache *) *this_cache;
   this_trad_cache = trad_frame_cache_zalloc (this_frame);
   *this_cache = this_trad_cache;
 
   this_trad_cache = trad_frame_cache_zalloc (this_frame);
   *this_cache = this_trad_cache;
 
@@ -1546,7 +2063,6 @@ nios2_stub_frame_sniffer (const struct frame_unwind *self,
                          struct frame_info *this_frame, void **cache)
 {
   gdb_byte dummy[4];
                          struct frame_info *this_frame, void **cache)
 {
   gdb_byte dummy[4];
-  struct obj_section *s;
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
 
   /* Use the stub unwinder for unreadable code.  */
   CORE_ADDR pc = get_frame_address_in_block (this_frame);
 
   /* Use the stub unwinder for unreadable code.  */
@@ -1577,9 +2093,9 @@ static const struct frame_unwind nios2_stub_frame_unwind =
    branch prediction.  */
 
 static CORE_ADDR
    branch prediction.  */
 
 static CORE_ADDR
-nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
+nios2_get_next_pc (struct regcache *regcache, CORE_ADDR pc)
 {
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
+  struct gdbarch *gdbarch = regcache->arch ();
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
   unsigned int insn;
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
   unsigned int insn;
@@ -1588,7 +2104,7 @@ nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
   int rb;
   int imm;
   unsigned int uimm;
   int rb;
   int imm;
   unsigned int uimm;
-  int wb, ret;
+  int wb, id, ret;
   enum branch_condition cond;
 
   /* Do something stupid if we can't disassemble the insn at pc.  */
   enum branch_condition cond;
 
   /* Do something stupid if we can't disassemble the insn at pc.  */
@@ -1597,10 +2113,10 @@ nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
     
   if (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond))
     {
     
   if (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond))
     {
-      int ras = get_frame_register_signed (frame, ra);
-      int rbs = get_frame_register_signed (frame, rb);
-      unsigned int rau = get_frame_register_unsigned (frame, ra);
-      unsigned int rbu = get_frame_register_unsigned (frame, rb);
+      int ras = regcache_raw_get_signed (regcache, ra);
+      int rbs = regcache_raw_get_signed (regcache, rb);
+      unsigned int rau = regcache_raw_get_unsigned (regcache, ra);
+      unsigned int rbu = regcache_raw_get_unsigned (regcache, rb);
 
       pc += op->size;
       switch (cond)
 
       pc += op->size;
       switch (cond)
@@ -1637,18 +2153,48 @@ nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
        }
     }
 
        }
     }
 
-  else if (nios2_match_jmpi (insn, op, mach, &uimm)
-          || nios2_match_calli (insn, op, mach, &uimm))
+  else if (nios2_match_jmpi (insn, op, mach, &uimm))
     pc = (pc & 0xf0000000) | uimm;
     pc = (pc & 0xf0000000) | uimm;
+  else if (nios2_match_calli (insn, op, mach, &uimm))
+    {
+      CORE_ADDR callto = (pc & 0xf0000000) | uimm;
+      if (tdep->is_kernel_helper != NULL
+         && tdep->is_kernel_helper (callto))
+       /* Step over call to kernel helper, which we cannot debug
+          from user space.  */
+       pc += op->size;
+      else
+       pc = callto;
+    }
 
 
-  else if (nios2_match_jmpr (insn, op, mach, &ra)
-          || nios2_match_callr (insn, op, mach, &ra))
-    pc = get_frame_register_unsigned (frame, ra);
+  else if (nios2_match_jmpr (insn, op, mach, &ra))
+    pc = regcache_raw_get_unsigned (regcache, ra);
+  else if (nios2_match_callr (insn, op, mach, &ra))
+    {
+      CORE_ADDR callto = regcache_raw_get_unsigned (regcache, ra);
+      if (tdep->is_kernel_helper != NULL
+         && tdep->is_kernel_helper (callto))
+       /* Step over call to kernel helper.  */
+       pc += op->size;
+      else
+       pc = callto;
+    }
 
 
-  else if (nios2_match_trap (insn, op, mach, &uimm))
+  else if (nios2_match_ldwm (insn, op, mach, &uimm, &ra, &imm, &wb, &id, &ret)
+          && ret)
+    {
+      /* If ra is in the reglist, we have to use the value saved in the
+        stack frame rather than the current value.  */
+      if (uimm & (1 << NIOS2_RA_REGNUM))
+       pc = nios2_unwind_pc (gdbarch, get_current_frame ());
+      else
+       pc = regcache_raw_get_unsigned (regcache, NIOS2_RA_REGNUM);
+    }
+
+  else if (nios2_match_trap (insn, op, mach, &uimm) && uimm == 0)
     {
       if (tdep->syscall_next_pc != NULL)
     {
       if (tdep->syscall_next_pc != NULL)
-       return tdep->syscall_next_pc (frame);
+       return tdep->syscall_next_pc (get_current_frame (), op);
     }
 
   else
     }
 
   else
@@ -1659,16 +2205,12 @@ nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
 
 /* Implement the software_single_step gdbarch method.  */
 
 
 /* Implement the software_single_step gdbarch method.  */
 
-static int
-nios2_software_single_step (struct frame_info *frame)
+static std::vector<CORE_ADDR>
+nios2_software_single_step (struct regcache *regcache)
 {
 {
-  struct gdbarch *gdbarch = get_frame_arch (frame);
-  struct address_space *aspace = get_frame_address_space (frame);
-  CORE_ADDR next_pc = nios2_get_next_pc (frame, get_frame_pc (frame));
-
-  insert_single_step_breakpoint (gdbarch, aspace, next_pc);
+  CORE_ADDR next_pc = nios2_get_next_pc (regcache, regcache_read_pc (regcache));
 
 
-  return 1;
+  return {next_pc};
 }
 
 /* Implement the get_longjump_target gdbarch method.  */
 }
 
 /* Implement the get_longjump_target gdbarch method.  */
@@ -1689,6 +2231,42 @@ nios2_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
   return 1;
 }
 
   return 1;
 }
 
+/* Implement the type_align gdbarch function.  */
+
+static ULONGEST
+nios2_type_align (struct gdbarch *gdbarch, struct type *type)
+{
+  switch (TYPE_CODE (type))
+    {
+    case TYPE_CODE_PTR:
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_FLAGS:
+    case TYPE_CODE_INT:
+    case TYPE_CODE_RANGE:
+    case TYPE_CODE_FLT:
+    case TYPE_CODE_ENUM:
+    case TYPE_CODE_REF:
+    case TYPE_CODE_RVALUE_REF:
+    case TYPE_CODE_CHAR:
+    case TYPE_CODE_BOOL:
+    case TYPE_CODE_DECFLOAT:
+    case TYPE_CODE_METHODPTR:
+    case TYPE_CODE_MEMBERPTR:
+      type = check_typedef (type);
+      return std::min<ULONGEST> (4, TYPE_LENGTH (type));
+    default:
+      return 0;
+    }
+}
+
+/* Implement the gcc_target_options gdbarch method.  */
+static std::string
+nios2_gcc_target_options (struct gdbarch *gdbarch)
+{
+  /* GCC doesn't know "-m32".  */
+  return {};
+}
+
 /* Initialize the Nios II gdbarch.  */
 
 static struct gdbarch *
 /* Initialize the Nios II gdbarch.  */
 
 static struct gdbarch *
@@ -1696,7 +2274,7 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 {
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
 {
   struct gdbarch *gdbarch;
   struct gdbarch_tdep *tdep;
-  int register_bytes, i;
+  int i;
   struct tdesc_arch_data *tdesc_data = NULL;
   const struct target_desc *tdesc = info.target_desc;
 
   struct tdesc_arch_data *tdesc_data = NULL;
   const struct target_desc *tdesc = info.target_desc;
 
@@ -1736,7 +2314,7 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* None found, create a new architecture from the information
      provided.  */
 
   /* None found, create a new architecture from the information
      provided.  */
-  tdep = xcalloc (1, sizeof (struct gdbarch_tdep));
+  tdep = XCNEW (struct gdbarch_tdep);
   gdbarch = gdbarch_alloc (&info, tdep);
 
   /* longjmp support not enabled by default.  */
   gdbarch = gdbarch_alloc (&info, tdep);
 
   /* longjmp support not enabled by default.  */
@@ -1752,6 +2330,8 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_float_bit (gdbarch, 32);
   set_gdbarch_double_bit (gdbarch, 64);
 
   set_gdbarch_float_bit (gdbarch, 32);
   set_gdbarch_double_bit (gdbarch, 64);
 
+  set_gdbarch_type_align (gdbarch, nios2_type_align);
+
   set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
   set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
 
   set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
   set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
 
@@ -1775,12 +2355,11 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_return_value (gdbarch, nios2_return_value);
 
   set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
   set_gdbarch_return_value (gdbarch, nios2_return_value);
 
   set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
-  set_gdbarch_in_function_epilogue_p (gdbarch, nios2_in_function_epilogue_p);
-  set_gdbarch_breakpoint_from_pc (gdbarch, nios2_breakpoint_from_pc);
+  set_gdbarch_stack_frame_destroyed_p (gdbarch, nios2_stack_frame_destroyed_p);
+  set_gdbarch_breakpoint_kind_from_pc (gdbarch, nios2_breakpoint_kind_from_pc);
+  set_gdbarch_sw_breakpoint_from_kind (gdbarch, nios2_sw_breakpoint_from_kind);
 
 
-  set_gdbarch_dummy_id (gdbarch, nios2_dummy_id);
   set_gdbarch_unwind_pc (gdbarch, nios2_unwind_pc);
   set_gdbarch_unwind_pc (gdbarch, nios2_unwind_pc);
-  set_gdbarch_unwind_sp (gdbarch, nios2_unwind_sp);
 
   /* The dwarf2 unwinder will normally produce the best results if
      the debug information is available, so register it first.  */
 
   /* The dwarf2 unwinder will normally produce the best results if
      the debug information is available, so register it first.  */
@@ -1791,6 +2370,9 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Single stepping.  */
   set_gdbarch_software_single_step (gdbarch, nios2_software_single_step);
 
   /* Single stepping.  */
   set_gdbarch_software_single_step (gdbarch, nios2_software_single_step);
 
+  /* Target options for compile.  */
+  set_gdbarch_gcc_target_options (gdbarch, nios2_gcc_target_options);
+
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
@@ -1799,8 +2381,6 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   frame_base_set_default (gdbarch, &nios2_frame_base);
 
 
   frame_base_set_default (gdbarch, &nios2_frame_base);
 
-  set_gdbarch_print_insn (gdbarch, nios2_print_insn);
-
   /* Enable inferior call support.  */
   set_gdbarch_push_dummy_call (gdbarch, nios2_push_dummy_call);
 
   /* Enable inferior call support.  */
   set_gdbarch_push_dummy_call (gdbarch, nios2_push_dummy_call);
 
@@ -1810,8 +2390,6 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   return gdbarch;
 }
 
   return gdbarch;
 }
 
-extern initialize_file_ftype _initialize_nios2_tdep; /* -Wmissing-prototypes */
-
 void
 _initialize_nios2_tdep (void)
 {
 void
 _initialize_nios2_tdep (void)
 {
This page took 0.041813 seconds and 4 git commands to generate.