xtensa_pseudo_register_read/write - Use regcache_raw_read_unsigned
[deliverable/binutils-gdb.git] / gdb / nios2-tdep.c
index 12056b51a54cdfd0d4f0b785e13567c9109f54e7..3d39451804d9cd3af0ac8b47432ac57580896749 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-2017 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.
@@ -44,9 +44,7 @@
 
 /* To get entry_point_address.  */
 #include "objfiles.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"
@@ -141,17 +139,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];
 }
@@ -287,8 +283,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 +309,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 +351,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 +387,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 +441,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 +470,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 +527,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 +576,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 +716,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)
+  int is_r2 = (mach == bfd_mach_nios2r2);
+
+  if (!is_r2)
     {
     {
-    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;
+      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 +813,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 +838,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 +863,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 +915,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 +944,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 +973,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 +1008,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 +1017,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 +1026,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 +1078,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 +1096,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;
@@ -684,10 +1135,12 @@ nios2_stack_frame_destroyed_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
@@ -741,7 +1194,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;
 
@@ -789,7 +1241,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)
@@ -812,7 +1264,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.  */
 
@@ -954,6 +1411,42 @@ 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 i;
+         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 (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
@@ -1037,6 +1530,9 @@ nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
       else if (nios2_match_callr (insn, op, mach, &ra)
               || nios2_match_jmpr (insn, op, mach, &ra)
               || nios2_match_jmpi (insn, op, mach, &uimm)
       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_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;
               || nios2_match_trap (insn, op, mach, &uimm)
               || nios2_match_break (insn, op, mach, &uimm))
        break;
@@ -1190,7 +1686,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....  */
@@ -1198,9 +1694,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;
 
 
-   The Nios II ABI for Linux says: "Userspace programs should not use
+  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.  */
+
+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)."
@@ -1208,23 +1729,47 @@ 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;
+
+  if (kind == NIOS2_CDX_OPCODE_SIZE)
+    {
+      static const gdb_byte cdx_breakpoint_le[] = {0xc9, 0xd7};
 
 
-  /* 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;
+      return cdx_breakpoint_le;
+    }
   else
   else
-    return r1_breakpoint_le;
+    {
+      unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
+
+      if (mach == bfd_mach_nios2r2)
+       {
+         static const gdb_byte r2_breakpoint_le[] = {0x20, 0x00, 0xfd, 0xb7};
+
+         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 print_insn gdbarch method.  */
 }
 
 /* Implement the print_insn gdbarch method.  */
@@ -1315,11 +1860,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);
 
@@ -1389,10 +1932,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;
@@ -1497,10 +2039,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;
 
@@ -1555,7 +2096,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.  */
@@ -1586,9 +2126,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 = get_regcache_arch (regcache);
   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;
@@ -1597,7 +2137,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.  */
@@ -1606,10 +2146,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)
@@ -1652,12 +2192,23 @@ nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
 
   else if (nios2_match_jmpr (insn, op, mach, &ra)
           || nios2_match_callr (insn, op, mach, &ra))
 
   else if (nios2_match_jmpr (insn, op, mach, &ra)
           || nios2_match_callr (insn, op, mach, &ra))
-    pc = get_frame_register_unsigned (frame, ra);
+    pc = regcache_raw_get_unsigned (regcache, ra);
 
 
-  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
@@ -1668,16 +2219,16 @@ 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 VEC (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));
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  CORE_ADDR next_pc = nios2_get_next_pc (regcache, regcache_read_pc (regcache));
+  VEC (CORE_ADDR) *next_pcs = NULL;
 
 
-  insert_single_step_breakpoint (gdbarch, aspace, next_pc);
+  VEC_safe_push (CORE_ADDR, next_pcs, next_pc);
 
 
-  return 1;
+  return next_pcs;
 }
 
 /* Implement the get_longjump_target gdbarch method.  */
 }
 
 /* Implement the get_longjump_target gdbarch method.  */
@@ -1705,7 +2256,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;
 
@@ -1745,7 +2296,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.  */
@@ -1785,7 +2336,8 @@ nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
   set_gdbarch_stack_frame_destroyed_p (gdbarch, nios2_stack_frame_destroyed_p);
 
   set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
   set_gdbarch_stack_frame_destroyed_p (gdbarch, nios2_stack_frame_destroyed_p);
-  set_gdbarch_breakpoint_from_pc (gdbarch, nios2_breakpoint_from_pc);
+  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_dummy_id (gdbarch, nios2_dummy_id);
   set_gdbarch_unwind_pc (gdbarch, nios2_unwind_pc);
This page took 0.037544 seconds and 4 git commands to generate.