/* Target-machine dependent code for Nios II, for GDB.
   Copyright (C) 2012-2023 Free Software Foundation, Inc.
   Contributed by Peter Brookes (pbrookes@altera.com)
   and Andrew Draper (adraper@altera.com).
   Contributed by Mentor Graphics, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "frame.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
#include "dwarf2/frame.h"
#include "symtab.h"
#include "inferior.h"
#include "gdbtypes.h"
#include "gdbcore.h"
#include "gdbcmd.h"
#include "osabi.h"
#include "target.h"
#include "dis-asm.h"
#include "regcache.h"
#include "value.h"
#include "symfile.h"
#include "arch-utils.h"
#include "infcall.h"
#include "regset.h"
#include "target-descriptions.h"

/* To get entry_point_address.  */
#include "objfiles.h"
#include <algorithm>

/* Nios II specific header.  */
#include "nios2-tdep.h"

#include "features/nios2.c"

/* Control debugging information emitted in this file.  */

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.  */

/* 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;
  int offset;
};

/* struct reg_saved is used to record that a register value has been saved at
   basereg + addr, for basereg >= 0.  If basereg < 0, that indicates
   that the register is not known to have been saved.  Note that when
   basereg == NIOS2_Z_REGNUM (that is, r0, which holds value 0),
   addr is an absolute address.  */

struct reg_saved
{
  int basereg;
  CORE_ADDR addr;
};

struct nios2_unwind_cache
{
  /* The frame's base, optionally used by the high-level debug info.  */
  CORE_ADDR base;

  /* The previous frame's inner most stack address.  Used as this
     frame ID's stack_addr.  */
  CORE_ADDR cfa;

  /* The address of the first instruction in this function.  */
  CORE_ADDR pc;

  /* Which register holds the return address for the frame.  */
  int return_regnum;

  /* Table indicating what changes have been made to each register.  */
  struct reg_value reg_value[NIOS2_NUM_REGS];

  /* Table indicating where each register has been saved.  */
  struct reg_saved reg_saved[NIOS2_NUM_REGS];
};


/* This array is a mapping from Dwarf-2 register numbering to GDB's.  */

static int nios2_dwarf2gdb_regno_map[] =
{
  0, 1, 2, 3,
  4, 5, 6, 7,
  8, 9, 10, 11,
  12, 13, 14, 15,
  16, 17, 18, 19,
  20, 21, 22, 23,
  24, 25,
  NIOS2_GP_REGNUM,        /* 26 */
  NIOS2_SP_REGNUM,        /* 27 */
  NIOS2_FP_REGNUM,        /* 28 */
  NIOS2_EA_REGNUM,        /* 29 */
  NIOS2_BA_REGNUM,        /* 30 */
  NIOS2_RA_REGNUM,        /* 31 */
  NIOS2_PC_REGNUM,        /* 32 */
  NIOS2_STATUS_REGNUM,    /* 33 */
  NIOS2_ESTATUS_REGNUM,   /* 34 */
  NIOS2_BSTATUS_REGNUM,   /* 35 */
  NIOS2_IENABLE_REGNUM,   /* 36 */
  NIOS2_IPENDING_REGNUM,  /* 37 */
  NIOS2_CPUID_REGNUM,     /* 38 */
  39, /* CTL6 */          /* 39 */
  NIOS2_EXCEPTION_REGNUM, /* 40 */
  NIOS2_PTEADDR_REGNUM,   /* 41 */
  NIOS2_TLBACC_REGNUM,    /* 42 */
  NIOS2_TLBMISC_REGNUM,   /* 43 */
  NIOS2_ECCINJ_REGNUM,    /* 44 */
  NIOS2_BADADDR_REGNUM,   /* 45 */
  NIOS2_CONFIG_REGNUM,    /* 46 */
  NIOS2_MPUBASE_REGNUM,   /* 47 */
  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)
{
  if (dw_reg < 0 || dw_reg >= NIOS2_NUM_REGS)
    return -1;

  return nios2_dwarf2gdb_regno_map[dw_reg];
}

/* Canonical names for the 49 registers.  */

static const char *const nios2_reg_names[NIOS2_NUM_REGS] =
{
  "zero", "at", "r2", "r3", "r4", "r5", "r6", "r7",
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
  "et", "bt", "gp", "sp", "fp", "ea", "sstatus", "ra",
  "pc",
  "status", "estatus", "bstatus", "ienable",
  "ipending", "cpuid", "ctl6", "exception",
  "pteaddr", "tlbacc", "tlbmisc", "eccinj",
  "badaddr", "config", "mpubase", "mpuacc"
};

/* Implement the register_name gdbarch method.  */

static const char *
nios2_register_name (struct gdbarch *gdbarch, int regno)
{
  /* Use mnemonic aliases for GPRs.  */
  if (regno < NIOS2_NUM_REGS)
    return nios2_reg_names[regno];
  else
    return tdesc_register_name (gdbarch, regno);
}

/* Implement the register_type gdbarch method.  */

static struct type *
nios2_register_type (struct gdbarch *gdbarch, int regno)
{
  /* If the XML description has register information, use that to
     determine the register type.  */
  if (tdesc_has_registers (gdbarch_target_desc (gdbarch)))
    return tdesc_register_type (gdbarch, regno);

  if (regno == NIOS2_PC_REGNUM)
    return builtin_type (gdbarch)->builtin_func_ptr;
  else if (regno == NIOS2_SP_REGNUM)
    return builtin_type (gdbarch)->builtin_data_ptr;
  else
    return builtin_type (gdbarch)->builtin_uint32;
}

/* Given a return value in REGCACHE with a type VALTYPE,
   extract and copy its value into VALBUF.  */

static void
nios2_extract_return_value (struct gdbarch *gdbarch, struct type *valtype,
			    struct regcache *regcache, gdb_byte *valbuf)
{
  int len = valtype->length ();

  /* Return values of up to 8 bytes are returned in $r2 $r3.  */
  if (len <= register_size (gdbarch, NIOS2_R2_REGNUM))
    regcache->cooked_read (NIOS2_R2_REGNUM, valbuf);
  else
    {
      gdb_assert (len <= (register_size (gdbarch, NIOS2_R2_REGNUM)
			  + register_size (gdbarch, NIOS2_R3_REGNUM)));
      regcache->cooked_read (NIOS2_R2_REGNUM, valbuf);
      regcache->cooked_read (NIOS2_R3_REGNUM, valbuf + 4);
    }
}

/* Write into appropriate registers a function return value
   of type TYPE, given in virtual format.  */

static void
nios2_store_return_value (struct gdbarch *gdbarch, struct type *valtype,
			  struct regcache *regcache, const gdb_byte *valbuf)
{
  int len = valtype->length ();

  /* Return values of up to 8 bytes are returned in $r2 $r3.  */
  if (len <= register_size (gdbarch, NIOS2_R2_REGNUM))
    regcache->cooked_write (NIOS2_R2_REGNUM, valbuf);
  else
    {
      gdb_assert (len <= (register_size (gdbarch, NIOS2_R2_REGNUM)
			  + register_size (gdbarch, NIOS2_R3_REGNUM)));
      regcache->cooked_write (NIOS2_R2_REGNUM, valbuf);
      regcache->cooked_write (NIOS2_R3_REGNUM, valbuf + 4);
    }
}


/* Set up the default values of the registers.  */

static void
nios2_setup_default (struct nios2_unwind_cache *cache)
{
  int i;

  for (i = 0; i < NIOS2_NUM_REGS; i++)
    {
      /* All registers start off holding their previous values.  */
      cache->reg_value[i].reg    = i;
      cache->reg_value[i].offset = 0;

      /* All registers start off not saved.  */
      cache->reg_saved[i].basereg = -1;
      cache->reg_saved[i].addr    = 0;
    }
}

/* Initialize the unwind cache.  */

static void
nios2_init_cache (struct nios2_unwind_cache *cache, CORE_ADDR pc)
{
  cache->base = 0;
  cache->cfa = 0;
  cache->pc = pc;
  cache->return_regnum = NIOS2_RA_REGNUM;
  nios2_setup_default (cache);
}

/* Read and identify an instruction at PC.  If INSNP is non-null,
   store the instruction word into that location.  Return the opcode
   pointer or NULL if the memory couldn't be read or disassembled.  */

static const struct nios2_opcode *
nios2_fetch_insn (struct gdbarch *gdbarch, CORE_ADDR pc,
		  unsigned int *insnp)
{
  LONGEST memword;
  unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
  unsigned int insn;

  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;
  if (insnp)
    *insnp = insn;
  return nios2_find_opcode_hash (insn, mach);
}


/* Match and disassemble an ADD-type instruction, with 3 register operands.
   Returns true on success, and fills in the operand pointers.  */

static int
nios2_match_add (uint32_t insn, const struct nios2_opcode *op,
		 unsigned long mach, int *ra, int *rb, int *rc)
{
  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;
    }
  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;
}

/* Match and disassemble a SUB-type instruction, with 3 register operands.
   Returns true on success, and fills in the operand pointers.  */

static int
nios2_match_sub (uint32_t insn, const struct nios2_opcode *op,
		 unsigned long mach, int *ra, int *rb, int *rc)
{
  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;
    }
  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;
}

/* Match and disassemble an ADDI-type instruction, with 2 register operands
   and one immediate operand.
   Returns true on success, and fills in the operand pointers.  */

static int
nios2_match_addi (uint32_t insn, const struct nios2_opcode *op,
		  unsigned long mach, int *ra, int *rb, int *imm)
{
  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;
    }
  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;
}

/* Match and disassemble an ORHI-type instruction, with 2 register operands
   and one unsigned immediate operand.
   Returns true on success, and fills in the operand pointers.  */

static int
nios2_match_orhi (uint32_t insn, const struct nios2_opcode *op,
		  unsigned long mach, int *ra, int *rb, unsigned int *uimm)
{
  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;
    }
  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;
}

/* Match and disassemble a STW-type instruction, with 2 register operands
   and one immediate operand.
   Returns true on success, and fills in the operand pointers.  */

static int
nios2_match_stw (uint32_t insn, const struct nios2_opcode *op,
		 unsigned long mach, int *ra, int *rb, int *imm)
{
  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;
    }
  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;
}

/* Match and disassemble a LDW-type instruction, with 2 register operands
   and one immediate operand.
   Returns true on success, and fills in the operand pointers.  */

static int
nios2_match_ldw (uint32_t insn, const struct nios2_opcode *op,
		 unsigned long mach, int *ra, int *rb, int *imm)
{
  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;
    }
  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;
}

/* Match and disassemble a RDCTL instruction, with 2 register operands.
   Returns true on success, and fills in the operand pointers.  */

static int
nios2_match_rdctl (uint32_t insn, const struct nios2_opcode *op,
		   unsigned long mach, int *ra, int *rc)
{
  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;
    }
  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;
}

/* 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.
   Returns true on success, and fills in the operand pointers.  */

enum branch_condition {
  branch_none,
  branch_eq,
  branch_ne,
  branch_ge,
  branch_geu,
  branch_lt,
  branch_ltu
};
  
static int
nios2_match_branch (uint32_t insn, const struct nios2_opcode *op,
		    unsigned long mach, int *ra, int *rb, int *imm,
		    enum branch_condition *cond)
{
  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;
    }
  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
   unsigned operand.  Returns true on success, and fills in the operand
   pointer.  */

static int
nios2_match_jmpi (uint32_t insn, const struct nios2_opcode *op,
		  unsigned long mach, unsigned int *uimm)
{
  int is_r2 = (mach == bfd_mach_nios2r2);

  if (!is_r2 && op->match == MATCH_R1_JMPI)
    {
      *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;
}

/* Match and disassemble a direct call instruction, with an
   unsigned operand.  Returns true on success, and fills in the operand
   pointer.  */

static int
nios2_match_calli (uint32_t insn, const struct nios2_opcode *op,
		   unsigned long mach, unsigned int *uimm)
{
  int is_r2 = (mach == bfd_mach_nios2r2);

  if (!is_r2 && op->match == MATCH_R1_CALL)
    {
      *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;
}

/* Match and disassemble an indirect jump instruction, with a
   (possibly implicit) register operand.  Returns true on success, and fills
   in the operand pointer.  */

static int
nios2_match_jmpr (uint32_t insn, const struct nios2_opcode *op,
		  unsigned long mach, int *ra)
{
  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
   operand.  Returns true on success, and fills in the operand pointer.  */

static int
nios2_match_callr (uint32_t insn, const struct nios2_opcode *op,
		   unsigned long mach, int *ra)
{
  int is_r2 = (mach == bfd_mach_nios2r2);

  if (!is_r2 && op->match == MATCH_R1_CALLR)
    {
      *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;
}

/* Match and disassemble a break instruction, with an unsigned operand.
   Returns true on success, and fills in the operand pointer.  */

static int
nios2_match_break (uint32_t insn, const struct nios2_opcode *op,
		  unsigned long mach, unsigned int *uimm)
{
  int is_r2 = (mach == bfd_mach_nios2r2);

  if (!is_r2 && op->match == MATCH_R1_BREAK)
    {
      *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;
}

/* Match and disassemble a trap instruction, with an unsigned operand.
   Returns true on success, and fills in the operand pointer.  */

static int
nios2_match_trap (uint32_t insn, const struct nios2_opcode *op,
		  unsigned long mach, unsigned int *uimm)
{
  int is_r2 = (mach == bfd_mach_nios2r2);

  if (!is_r2 && op->match == MATCH_R1_TRAP)
    {
      *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;
}

/* Helper function to identify when we're in a function epilogue;
   that is, the part of the function from the point at which the
   stack adjustments are made, to the return or sibcall.
   Note that we may have several stack adjustment instructions, and
   this function needs to test whether the stack teardown has already
   started before current_pc, not whether it has completed.  */

static int
nios2_in_epilogue_p (struct gdbarch *gdbarch,
		     CORE_ADDR current_pc,
		     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.  */
  int ninsns, max_insns = 5;
  unsigned int insn;
  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;

  /* There has to be a previous instruction in the function.  */
  if (current_pc <= start_pc)
    return 0;

  /* 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
	 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;

      /* Fetch the insn at pc.  */
      op = nios2_fetch_insn (gdbarch, pc, &insn);
      if (op == NULL)
	return 0;
      pc += op->size;

      /* Was it a stack adjustment?  */
      if (nios2_match_addi (insn, op, mach, &ra, &rb, &imm))
	ok = (rb == NIOS2_SP_REGNUM);
      else if (nios2_match_add (insn, op, mach, &ra, &rb, &rc))
	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;
    }

  /* No stack adjustments found.  */
  if (ninsns == 0)
    return 0;

  /* We found more stack adjustments than we expect GCC to be generating.
     Since it looks like a stack unwind might be in progress tell GDB to
     treat it as such.  */
  if (ninsns == max_insns)
    return 1;

  /* The next instruction following the stack adjustments must be a
     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)
      || (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;

  return 0;
}

/* Implement the stack_frame_destroyed_p gdbarch method.  */

static int
nios2_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  CORE_ADDR func_addr;

  if (find_pc_partial_function (pc, NULL, &func_addr, NULL))
    return nios2_in_epilogue_p (gdbarch, pc, func_addr);

  return 0;
}

/* Do prologue analysis, returning the PC of the first instruction
   after the function prologue.  Assumes CACHE has already been
   initialized.  THIS_FRAME can be null, in which case we are only
   interested in skipping the prologue.  Otherwise CACHE is filled in
   from the frame information.

   The prologue may consist of the following parts:
     1) Profiling instrumentation.  For non-PIC code it looks like:
	  mov	 r8, ra
	  call	 mcount
	  mov	 ra, r8

     2) A stack adjustment and save of R4-R7 for varargs functions.
	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.
	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
	in place of a stack adjustment.  It looks like:
	  movhi  rx, %hiadj(newstack)
	  addhi  rx, rx, %lo(newstack)
	  stw    sp, constant(rx)
	  mov    sp, rx

     4) A frame pointer save, which can be either a MOV or ADDI.

     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
	  trap  3
	or
	  bltu   sp, rx, .Lstack_overflow
	  ...
	.Lstack_overflow:
	  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.

    To cope with all this variability we decode all the instructions
    from the start of the prologue until we hit an instruction that
    cannot possibly be a prologue instruction, such as a branch, call,
    return, or epilogue instruction.  The prologue is considered to end
    at the last instruction that can definitely be considered a
    prologue instruction.  */

static CORE_ADDR
nios2_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR start_pc,
			const CORE_ADDR current_pc,
			struct nios2_unwind_cache *cache,
			frame_info_ptr this_frame)
{
  /* Maximum number of possibly-prologue instructions to check.
     Note that this number should not be too large, else we can
     potentially end up iterating through unmapped memory.  */
  int ninsns, max_insns = 50;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;

  /* Does the frame set up the FP register?  */
  int base_reg = 0;

  struct reg_value *value = cache->reg_value;
  struct reg_value temp_value[NIOS2_NUM_REGS];

  /* Save the starting PC so we can correct the pc after running
     through the prolog, using symbol info.  */
  CORE_ADDR pc = start_pc;

  /* Is this an exception handler?  */
  int exception_handler = 0;

  /* What was the original value of SP (or fake original value for
     functions which switch stacks?  */
  CORE_ADDR frame_high;

  /* The last definitely-prologue instruction seen.  */
  CORE_ADDR prologue_end;

  /* Is this the innermost function?  */
  int innermost = (this_frame ? (frame_relative_level (this_frame) == 0) : 1);

  if (nios2_debug)
    gdb_printf (gdb_stdlog,
		"{ nios2_analyze_prologue start=%s, current=%s ",
		paddress (gdbarch, start_pc),
		paddress (gdbarch, current_pc));

  /* Set up the default values of the registers.  */
  nios2_setup_default (cache);

  /* Find the prologue instructions.  */
  prologue_end = start_pc;
  for (ninsns = 0; ninsns < max_insns; ninsns++)
    {
      /* Present instruction.  */
      uint32_t insn;
      const struct nios2_opcode *op;
      int ra, rb, rc, imm;
      unsigned int uimm;
      unsigned int reglist;
      int wb, id, ret;
      enum branch_condition cond;

      if (pc == current_pc)
	{
	  /* When we reach the current PC we must save the current
	     register state (for the backtrace) but keep analysing
	     because there might be more to find out (eg. is this an
	     exception handler).  */
	  memcpy (temp_value, value, sizeof (temp_value));
	  value = temp_value;
	  if (nios2_debug)
	    gdb_printf (gdb_stdlog, "*");
	}

      op = nios2_fetch_insn (gdbarch, pc, &insn);

      /* Unknown opcode?  Stop scanning.  */
      if (op == NULL)
	break;
      pc += op->size;

      if (nios2_debug)
	{
	  if (op->size == 2)
	    gdb_printf (gdb_stdlog, "[%04X]", insn & 0xffff);
	  else
	    gdb_printf (gdb_stdlog, "[%08X]", insn);
	}

      /* The following instructions can appear in the prologue.  */

      if (nios2_match_add (insn, op, mach, &ra, &rb, &rc))
	{
	  /* ADD   rc, ra, rb  (also used for MOV) */
	  if (rc == NIOS2_SP_REGNUM
	      && rb == 0
	      && value[ra].reg == cache->reg_saved[NIOS2_SP_REGNUM].basereg)
	    {
	      /* If the previous value of SP is available somewhere
		 near the new stack pointer value then this is a
		 stack switch.  */

	      /* If any registers were saved on the stack before then
		 we can't backtrace into them now.  */
	      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 (value[i].reg == NIOS2_SP_REGNUM)
		    value[i].reg = -1;
		}

	      /* Create a fake "high water mark" 4 bytes above where SP
		 was stored and fake up the registers to be consistent
		 with that.  */
	      value[NIOS2_SP_REGNUM].reg = NIOS2_SP_REGNUM;
	      value[NIOS2_SP_REGNUM].offset
		= (value[ra].offset
		   - cache->reg_saved[NIOS2_SP_REGNUM].addr
		   - 4);
	      cache->reg_saved[NIOS2_SP_REGNUM].basereg = NIOS2_SP_REGNUM;
	      cache->reg_saved[NIOS2_SP_REGNUM].addr = -4;
	    }

	  else if (rc == NIOS2_SP_REGNUM && ra == NIOS2_FP_REGNUM)
	    /* This is setting SP from FP.  This only happens in the
	       function epilogue.  */
	    break;

	  else if (rc != 0)
	    {
	      if (value[rb].reg == 0)
		value[rc].reg = value[ra].reg;
	      else if (value[ra].reg == 0)
		value[rc].reg = value[rb].reg;
	      else
		value[rc].reg = -1;
	      value[rc].offset = value[ra].offset + value[rb].offset;
	    }

	  /* The add/move is only considered a prologue instruction
	     if the destination is SP or FP.  */
	  if (rc == NIOS2_SP_REGNUM || rc == NIOS2_FP_REGNUM)
	    prologue_end = pc;
	}
      
      else if (nios2_match_sub (insn, op, mach, &ra, &rb, &rc))
	{
	  /* SUB   rc, ra, rb */
	  if (rc == NIOS2_SP_REGNUM && rb == NIOS2_SP_REGNUM
	      && value[rc].reg != 0)
	    /* If we are decrementing the SP by a non-constant amount,
	       this is alloca, not part of the prologue.  */
	    break;
	  else if (rc != 0)
	    {
	      if (value[rb].reg == 0)
		value[rc].reg = value[ra].reg;
	      else
		value[rc].reg = -1;
	      value[rc].offset = value[ra].offset - value[rb].offset;
	    }
	}

      else if (nios2_match_addi (insn, op, mach, &ra, &rb, &imm))
	{
	  /* ADDI    rb, ra, imm */

	  /* A positive stack adjustment has to be part of the epilogue.  */
	  if (rb == NIOS2_SP_REGNUM
	      && (imm > 0 || value[ra].reg != NIOS2_SP_REGNUM))
	    break;

	  /* Likewise restoring SP from FP.  */
	  else if (rb == NIOS2_SP_REGNUM && ra == NIOS2_FP_REGNUM)
	    break;

	  if (rb != 0)
	    {
	      value[rb].reg    = value[ra].reg;
	      value[rb].offset = value[ra].offset + imm;
	    }

	  /* The add is only considered a prologue instruction
	     if the destination is SP or FP.  */
	  if (rb == NIOS2_SP_REGNUM || rb == NIOS2_FP_REGNUM)
	    prologue_end = pc;
	}

      else if (nios2_match_orhi (insn, op, mach, &ra, &rb, &uimm))
	{
	  /* ORHI  rb, ra, uimm   (also used for MOVHI) */
	  if (rb != 0)
	    {
	      value[rb].reg    = (value[ra].reg == 0) ? 0 : -1;
	      value[rb].offset = value[ra].offset | (uimm << 16);
	    }
	}

      else if (nios2_match_stw (insn, op, mach, &ra, &rb, &imm))
	{
	  /* STW rb, imm(ra) */

	  /* Are we storing the original value of a register to the stack?
	     For exception handlers the value of EA-4 (return
	     address from interrupts etc) is sometimes stored.  */
	  int orig = value[rb].reg;
	  if (orig > 0
	      && (value[rb].offset == 0
		  || (orig == NIOS2_EA_REGNUM && value[rb].offset == -4))
	      && value[ra].reg == NIOS2_SP_REGNUM)
	    {
	      if (pc < current_pc)
		{
		  /* Save off callee saved registers.  */
		  cache->reg_saved[orig].basereg = value[ra].reg;
		  cache->reg_saved[orig].addr = value[ra].offset + imm;
		}
	      
	      prologue_end = pc;
	      
	      if (orig == NIOS2_EA_REGNUM || orig == NIOS2_ESTATUS_REGNUM)
		exception_handler = 1;
	    }
	  else
	    /* Non-stack memory writes cannot appear in the prologue.  */
	    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
	     This can appear in exception handlers in combination with
	     a subsequent save to the stack frame.  */
	  if (rc != 0)
	    {
	      value[rc].reg    = NIOS2_STATUS_REGNUM + ra;
	      value[rc].offset = 0;
	    }
	}

      else if (nios2_match_calli (insn, op, mach, &uimm))
	{
	  if (value[8].reg == NIOS2_RA_REGNUM
	      && value[8].offset == 0
	      && value[NIOS2_SP_REGNUM].reg == NIOS2_SP_REGNUM
	      && value[NIOS2_SP_REGNUM].offset == 0)
	    {
	      /* A CALL instruction.  This is treated as a call to mcount
		 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 (int i = 2 ; i <= 3 ; i++)
		value[i].reg = -1;
	      for (int i = 9 ; i <= 15 ; i++)
		value[i].reg = -1;
	      value[NIOS2_RA_REGNUM].reg = -1;

	      prologue_end = pc;
	    }

	  /* Other calls are not part of the prologue.  */
	  else
	    break;
	}

      else if (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond))
	{
	  /* Branches not involving a stack overflow check aren't part of
	     the prologue.  */
	  if (ra != NIOS2_SP_REGNUM)
	    break;
	  else if (cond == branch_geu)
	    {
	      /* BGEU sp, rx, +8
		 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
		  && (nios2_match_trap (next_insn, op, mach, &uimm)
		      || nios2_match_break (next_insn, op, mach, &uimm)))
		pc += next_op->size;
	      else
		break;
	    }
	  else if (cond == branch_ltu)
	    {
	      /* BLTU sp, rx, .Lstackoverflow
		 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
		  && (nios2_match_trap (next_insn, op, mach, &uimm)
		      || nios2_match_break (next_insn, op, mach, &uimm)))
		;
	      else
		break;
	    }
	  else
	    break;
	}

      /* 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)
	       || 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;
    }

  /* If THIS_FRAME is NULL, we are being called from skip_prologue
     and are only interested in the PROLOGUE_END value, so just
     return that now and skip over the cache updates, which depend
     on having frame information.  */
  if (this_frame == NULL)
    return prologue_end;

  /* If we are in the function epilogue and have already popped
     registers off the stack in preparation for returning, then we
     want to go back to the original register values.  */
  if (innermost && nios2_in_epilogue_p (gdbarch, current_pc, start_pc))
    nios2_setup_default (cache);

  /* Exception handlers use a different return address register.  */
  if (exception_handler)
    cache->return_regnum = NIOS2_EA_REGNUM;

  if (nios2_debug)
    gdb_printf (gdb_stdlog, "\n-> retreg=%d, ", cache->return_regnum);

  if (cache->reg_value[NIOS2_FP_REGNUM].reg == NIOS2_SP_REGNUM)
    /* If the FP now holds an offset from the CFA then this is a
       normal frame which uses the frame pointer.  */
    base_reg = NIOS2_FP_REGNUM;
  else if (cache->reg_value[NIOS2_SP_REGNUM].reg == NIOS2_SP_REGNUM)
    /* FP doesn't hold an offset from the CFA.  If SP still holds an
       offset from the CFA then we might be in a function which omits
       the frame pointer, or we might be partway through the prologue.
       In both cases we can find the CFA using SP.  */
    base_reg = NIOS2_SP_REGNUM;
  else
    {
      /* Somehow the stack pointer has been corrupted.
	 We can't return.  */
      if (nios2_debug)
	gdb_printf (gdb_stdlog, "<can't reach cfa> }\n");
      return 0;
    }

  if (cache->reg_value[base_reg].offset == 0
      || cache->reg_saved[NIOS2_RA_REGNUM].basereg != NIOS2_SP_REGNUM
      || cache->reg_saved[cache->return_regnum].basereg != NIOS2_SP_REGNUM)
    {
      /* If the frame didn't adjust the stack, didn't save RA or
	 didn't save EA in an exception handler then it must either
	 be a leaf function (doesn't call any other functions) or it
	 can't return.  If it has called another function then it
	 can't be a leaf, so set base == 0 to indicate that we can't
	 backtrace past it.  */

      if (!innermost)
	{
	  /* If it isn't the innermost function then it can't be a
	     leaf, unless it was interrupted.  Check whether RA for
	     this frame is the same as PC.  If so then it probably
	     wasn't interrupted.  */
	  CORE_ADDR ra
	    = get_frame_register_unsigned (this_frame, NIOS2_RA_REGNUM);

	  if (ra == current_pc)
	    {
	      if (nios2_debug)
		gdb_printf
		  (gdb_stdlog,
		   "<noreturn ADJUST %s, r31@r%d+?>, r%d@r%d+?> }\n",
		   paddress (gdbarch, cache->reg_value[base_reg].offset),
		   cache->reg_saved[NIOS2_RA_REGNUM].basereg,
		   cache->return_regnum,
		   cache->reg_saved[cache->return_regnum].basereg);
	      return 0;
	    }
	}
    }

  /* Get the value of whichever register we are using for the
     base.  */
  cache->base = get_frame_register_unsigned (this_frame, base_reg);

  /* What was the value of SP at the start of this function (or just
     after the stack switch).  */
  frame_high = cache->base - cache->reg_value[base_reg].offset;

  /* Adjust all the saved registers such that they contain addresses
     instead of offsets.  */
  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;
      }

  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,
						    NIOS2_GP_REGNUM);

	for ( ; i < NIOS2_NUM_REGS; i++)
	  if (cache->reg_saved[i].basereg == NIOS2_GP_REGNUM)
	    {
	      cache->reg_saved[i].basereg = NIOS2_Z_REGNUM;
	      cache->reg_saved[i].addr += gp;
	    }
      }

  /* Work out what the value of SP was on the first instruction of
     this function.  If we didn't switch stacks then this can be
     trivially computed from the base address.  */
  if (cache->reg_saved[NIOS2_SP_REGNUM].basereg == NIOS2_Z_REGNUM)
    cache->cfa
      = read_memory_unsigned_integer (cache->reg_saved[NIOS2_SP_REGNUM].addr,
				      4, byte_order);
  else
    cache->cfa = frame_high;

  /* Exception handlers restore ESTATUS into STATUS.  */
  if (exception_handler)
    {
      cache->reg_saved[NIOS2_STATUS_REGNUM]
	= cache->reg_saved[NIOS2_ESTATUS_REGNUM];
      cache->reg_saved[NIOS2_ESTATUS_REGNUM].basereg = -1;
    }

  if (nios2_debug)
    gdb_printf (gdb_stdlog, "cfa=%s }\n",
		paddress (gdbarch, cache->cfa));

  return prologue_end;
}

/* Implement the skip_prologue gdbarch hook.  */

static CORE_ADDR
nios2_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
{
  CORE_ADDR func_addr;

  struct nios2_unwind_cache cache;

  /* See if we can determine the end of the prologue via the symbol
     table.  If so, then return either PC, or the PC after the
     prologue, whichever is greater.  */
  if (find_pc_partial_function (start_pc, NULL, &func_addr, NULL))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);

      if (post_prologue_pc != 0)
	return std::max (start_pc, post_prologue_pc);
    }

  /* Prologue analysis does the rest....  */
  nios2_init_cache (&cache, start_pc);
  return nios2_analyze_prologue (gdbarch, start_pc, start_pc, &cache, NULL);
}

/* 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.  */

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)."

   So, we use "trap 31" consistently as the breakpoint on bare-metal
   as well as Linux targets.  */

  /* 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};

      return cdx_breakpoint_le;
    }
  else
    {
      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 frame_align gdbarch method.  */

static CORE_ADDR
nios2_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return align_down (addr, 4);
}


/* Implement the return_value gdbarch method.  */

static enum return_value_convention
nios2_return_value (struct gdbarch *gdbarch, struct value *function,
		    struct type *type, struct regcache *regcache,
		    gdb_byte *readbuf, const gdb_byte *writebuf)
{
  if (type->length () > 8)
    return RETURN_VALUE_STRUCT_CONVENTION;

  if (readbuf)
    nios2_extract_return_value (gdbarch, type, regcache, readbuf);
  if (writebuf)
    nios2_store_return_value (gdbarch, type, regcache, writebuf);

  return RETURN_VALUE_REGISTER_CONVENTION;
}

/* 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,
		       function_call_return_method return_method,
		       CORE_ADDR struct_addr)
{
  int argreg;
  int argnum;
  int arg_space = 0;
  int stack_offset = 0;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  /* Set the return address register to point to the entry point of
     the program, where a breakpoint lies in wait.  */
  regcache_cooked_write_signed (regcache, NIOS2_RA_REGNUM, bp_addr);

  /* Now make space on the stack for the args.  */
  for (argnum = 0; argnum < nargs; argnum++)
    arg_space += align_up (args[argnum]->type ()->length (), 4);
  sp -= arg_space;

  /* Initialize the register pointer.  */
  argreg = NIOS2_FIRST_ARGREG;

  /* The struct_return pointer occupies the first parameter-passing
     register.  */
  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
     registers, and push the rest onto the stack.  Loop through args
     from first to last.  */
  for (argnum = 0; argnum < nargs; argnum++)
    {
      const gdb_byte *val;
      struct value *arg = args[argnum];
      struct type *arg_type = check_typedef (arg->type ());
      int len = arg_type->length ();

      val = arg->contents ().data ();

      /* Copy the argument to general registers or the stack in
	 register-sized pieces.  Large arguments are split between
	 registers and stack.  */
      while (len > 0)
	{
	  int partial_len = (len < 4 ? len : 4);

	  if (argreg <= NIOS2_LAST_ARGREG)
	    {
	      /* The argument is being passed in a register.  */
	      CORE_ADDR regval = extract_unsigned_integer (val, partial_len,
							   byte_order);

	      regcache_cooked_write_unsigned (regcache, argreg, regval);
	      argreg++;
	    }
	  else
	    {
	      /* The argument is being passed on the stack.  */
	      CORE_ADDR addr = sp + stack_offset;

	      write_memory (addr, val, partial_len);
	      stack_offset += align_up (partial_len, 4);
	    }

	  len -= partial_len;
	  val += partial_len;
	}
    }

  regcache_cooked_write_signed (regcache, NIOS2_SP_REGNUM, sp);

  /* Return adjusted stack pointer.  */
  return sp;
}

/* Implement the unwind_pc gdbarch method.  */

static CORE_ADDR
nios2_unwind_pc (struct gdbarch *gdbarch, frame_info_ptr next_frame)
{
  gdb_byte buf[4];

  frame_unwind_register (next_frame, NIOS2_PC_REGNUM, buf);
  return extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);
}

/* Use prologue analysis to fill in the register cache
   *THIS_PROLOGUE_CACHE for THIS_FRAME.  This function initializes
   *THIS_PROLOGUE_CACHE first.  */

static struct nios2_unwind_cache *
nios2_frame_unwind_cache (frame_info_ptr this_frame,
			  void **this_prologue_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR current_pc;
  struct nios2_unwind_cache *cache;

  if (*this_prologue_cache)
    return (struct nios2_unwind_cache *) *this_prologue_cache;

  cache = FRAME_OBSTACK_ZALLOC (struct nios2_unwind_cache);
  *this_prologue_cache = cache;

  /* Zero all fields.  */
  nios2_init_cache (cache, get_frame_func (this_frame));

  /* Prologue analysis does the rest...  */
  current_pc = get_frame_pc (this_frame);
  if (cache->pc != 0)
    nios2_analyze_prologue (gdbarch, cache->pc, current_pc, cache, this_frame);

  return cache;
}

/* Implement the this_id function for the normal unwinder.  */

static void
nios2_frame_this_id (frame_info_ptr this_frame, void **this_cache,
		     struct frame_id *this_id)
{
  struct nios2_unwind_cache *cache =
    nios2_frame_unwind_cache (this_frame, this_cache);

  /* This marks the outermost frame.  */
  if (cache->base == 0)
    return;

  *this_id = frame_id_build (cache->cfa, cache->pc);
}

/* Implement the prev_register function for the normal unwinder.  */

static struct value *
nios2_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
			   int regnum)
{
  struct nios2_unwind_cache *cache =
    nios2_frame_unwind_cache (this_frame, this_cache);

  gdb_assert (regnum >= 0 && regnum < NIOS2_NUM_REGS);

  /* The PC of the previous frame is stored in the RA register of
     the current frame.  Frob regnum so that we pull the value from
     the correct place.  */
  if (regnum == NIOS2_PC_REGNUM)
    regnum = cache->return_regnum;

  if (regnum == NIOS2_SP_REGNUM && cache->cfa)
    return frame_unwind_got_constant (this_frame, regnum, cache->cfa);

  /* If we've worked out where a register is stored then load it from
     there.  */
  if (cache->reg_saved[regnum].basereg == NIOS2_Z_REGNUM)
    return frame_unwind_got_memory (this_frame, regnum,
				    cache->reg_saved[regnum].addr);

  return frame_unwind_got_register (this_frame, regnum, regnum);
}

/* Implement the this_base, this_locals, and this_args hooks
   for the normal unwinder.  */

static CORE_ADDR
nios2_frame_base_address (frame_info_ptr this_frame, void **this_cache)
{
  struct nios2_unwind_cache *info
    = nios2_frame_unwind_cache (this_frame, this_cache);

  return info->base;
}

/* Data structures for the normal prologue-analysis-based
   unwinder.  */

static const struct frame_unwind nios2_frame_unwind =
{
  "nios2 prologue",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  nios2_frame_this_id,
  nios2_frame_prev_register,
  NULL,
  default_frame_sniffer
};

static const struct frame_base nios2_frame_base =
{
  &nios2_frame_unwind,
  nios2_frame_base_address,
  nios2_frame_base_address,
  nios2_frame_base_address
};

/* Fill in the register cache *THIS_CACHE for THIS_FRAME for use
   in the stub unwinder.  */

static struct trad_frame_cache *
nios2_stub_frame_cache (frame_info_ptr this_frame, void **this_cache)
{
  CORE_ADDR pc;
  CORE_ADDR start_addr;
  CORE_ADDR stack_addr;
  struct trad_frame_cache *this_trad_cache;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);

  if (*this_cache != NULL)
    return (struct trad_frame_cache *) *this_cache;
  this_trad_cache = trad_frame_cache_zalloc (this_frame);
  *this_cache = this_trad_cache;

  /* The return address is in the link register.  */
  trad_frame_set_reg_realreg (this_trad_cache,
			      gdbarch_pc_regnum (gdbarch),
			      NIOS2_RA_REGNUM);

  /* Frame ID, since it's a frameless / stackless function, no stack
     space is allocated and SP on entry is the current SP.  */
  pc = get_frame_pc (this_frame);
  find_pc_partial_function (pc, NULL, &start_addr, NULL);
  stack_addr = get_frame_register_unsigned (this_frame, NIOS2_SP_REGNUM);
  trad_frame_set_id (this_trad_cache, frame_id_build (start_addr, stack_addr));
  /* Assume that the frame's base is the same as the stack pointer.  */
  trad_frame_set_this_base (this_trad_cache, stack_addr);

  return this_trad_cache;
}

/* Implement the this_id function for the stub unwinder.  */

static void
nios2_stub_frame_this_id (frame_info_ptr this_frame, void **this_cache,
			  struct frame_id *this_id)
{
  struct trad_frame_cache *this_trad_cache
    = nios2_stub_frame_cache (this_frame, this_cache);

  trad_frame_get_id (this_trad_cache, this_id);
}

/* Implement the prev_register function for the stub unwinder.  */

static struct value *
nios2_stub_frame_prev_register (frame_info_ptr this_frame,
				void **this_cache, int regnum)
{
  struct trad_frame_cache *this_trad_cache
    = nios2_stub_frame_cache (this_frame, this_cache);

  return trad_frame_get_register (this_trad_cache, this_frame, regnum);
}

/* Implement the sniffer function for the stub unwinder.
   This unwinder is used for cases where the normal
   prologue-analysis-based unwinder can't work,
   such as PLT stubs.  */

static int
nios2_stub_frame_sniffer (const struct frame_unwind *self,
			  frame_info_ptr this_frame, void **cache)
{
  gdb_byte dummy[4];
  CORE_ADDR pc = get_frame_address_in_block (this_frame);

  /* Use the stub unwinder for unreadable code.  */
  if (target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0)
    return 1;

  if (in_plt_section (pc))
    return 1;

  return 0;
}

/* Define the data structures for the stub unwinder.  */

static const struct frame_unwind nios2_stub_frame_unwind =
{
  "nios2 stub",
  NORMAL_FRAME,
  default_frame_unwind_stop_reason,
  nios2_stub_frame_this_id,
  nios2_stub_frame_prev_register,
  NULL,
  nios2_stub_frame_sniffer
};



/* Determine where to set a single step breakpoint while considering
   branch prediction.  */

static CORE_ADDR
nios2_get_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = regcache->arch ();
  nios2_gdbarch_tdep *tdep = gdbarch_tdep<nios2_gdbarch_tdep> (gdbarch);
  unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach;
  unsigned int insn;
  const struct nios2_opcode *op = nios2_fetch_insn (gdbarch, pc, &insn);
  int ra;
  int rb;
  int imm;
  unsigned int uimm;
  int wb, id, ret;
  enum branch_condition cond;

  /* Do something stupid if we can't disassemble the insn at pc.  */
  if (op == NULL)
    return pc + NIOS2_OPCODE_SIZE;
    
  if (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond))
    {
      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)
	{
	case branch_none:
	  pc += imm;
	  break;
	case branch_eq:
	  if (ras == rbs)
	    pc += imm;
	  break;
	case branch_ne:
	  if (ras != rbs)
	    pc += imm;
	  break;
	case branch_ge:
	  if (ras >= rbs)
	    pc += imm;
	  break;
	case branch_geu:
	  if (rau >= rbu)
	    pc += imm;
	  break;
	case branch_lt:
	  if (ras < rbs)
	    pc += imm;
	  break;
	case branch_ltu:
	  if (rau < rbu)
	    pc += imm;
	  break;
	default:
	  break;
	}
    }

  else if (nios2_match_jmpi (insn, op, mach, &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))
    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_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)
	return tdep->syscall_next_pc (get_current_frame (), op);
    }

  else
    pc += op->size;

  return pc;
}

/* Implement the software_single_step gdbarch method.  */

static std::vector<CORE_ADDR>
nios2_software_single_step (struct regcache *regcache)
{
  CORE_ADDR next_pc = nios2_get_next_pc (regcache, regcache_read_pc (regcache));

  return {next_pc};
}

/* Implement the get_longjump_target gdbarch method.  */

static int
nios2_get_longjmp_target (frame_info_ptr frame, CORE_ADDR *pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  nios2_gdbarch_tdep *tdep = gdbarch_tdep<nios2_gdbarch_tdep> (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  CORE_ADDR jb_addr = get_frame_register_unsigned (frame, NIOS2_R4_REGNUM);
  gdb_byte buf[4];

  if (target_read_memory (jb_addr + (tdep->jb_pc * 4), buf, 4))
    return 0;

  *pc = extract_unsigned_integer (buf, 4, byte_order);
  return 1;
}

/* Implement the type_align gdbarch function.  */

static ULONGEST
nios2_type_align (struct gdbarch *gdbarch, struct type *type)
{
  switch (type->code ())
    {
    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 ());
    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 *
nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  int i;
  tdesc_arch_data_up tdesc_data;
  const struct target_desc *tdesc = info.target_desc;

  if (!tdesc_has_registers (tdesc))
    /* Pick a default target description.  */
    tdesc = tdesc_nios2;

  /* Check any target description for validity.  */
  if (tdesc_has_registers (tdesc))
    {
      const struct tdesc_feature *feature;
      int valid_p;

      feature = tdesc_find_feature (tdesc, "org.gnu.gdb.nios2.cpu");
      if (feature == NULL)
	return NULL;

      tdesc_data = tdesc_data_alloc ();

      valid_p = 1;
      
      for (i = 0; i < NIOS2_NUM_REGS; i++)
	valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), i,
					    nios2_reg_names[i]);

      if (!valid_p)
	return NULL;
    }

  /* Find a candidate among the list of pre-declared architectures.  */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != NULL)
    return arches->gdbarch;

  /* None found, create a new architecture from the information
     provided.  */
  gdbarch *gdbarch
    = gdbarch_alloc (&info, gdbarch_tdep_up (new nios2_gdbarch_tdep));
  nios2_gdbarch_tdep *tdep = gdbarch_tdep<nios2_gdbarch_tdep> (gdbarch);

  /* longjmp support not enabled by default.  */
  tdep->jb_pc = -1;

  /* Data type sizes.  */
  set_gdbarch_ptr_bit (gdbarch, 32);
  set_gdbarch_addr_bit (gdbarch, 32);
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 32);
  set_gdbarch_long_bit (gdbarch, 32);
  set_gdbarch_long_long_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);

  /* The register set.  */
  set_gdbarch_num_regs (gdbarch, NIOS2_NUM_REGS);
  set_gdbarch_sp_regnum (gdbarch, NIOS2_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, NIOS2_PC_REGNUM);	/* Pseudo register PC */

  set_gdbarch_register_name (gdbarch, nios2_register_name);
  set_gdbarch_register_type (gdbarch, nios2_register_type);

  /* Provide register mappings for stabs and dwarf2.  */
  set_gdbarch_stab_reg_to_regnum (gdbarch, nios2_dwarf_reg_to_regnum);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, nios2_dwarf_reg_to_regnum);

  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);

  /* Call dummy code.  */
  set_gdbarch_frame_align (gdbarch, nios2_frame_align);

  set_gdbarch_return_value (gdbarch, nios2_return_value);

  set_gdbarch_skip_prologue (gdbarch, nios2_skip_prologue);
  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_unwind_pc (gdbarch, nios2_unwind_pc);

  /* The dwarf2 unwinder will normally produce the best results if
     the debug information is available, so register it first.  */
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &nios2_stub_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &nios2_frame_unwind);

  /* 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);

  if (tdep->jb_pc >= 0)
    set_gdbarch_get_longjmp_target (gdbarch, nios2_get_longjmp_target);

  frame_base_set_default (gdbarch, &nios2_frame_base);

  /* Enable inferior call support.  */
  set_gdbarch_push_dummy_call (gdbarch, nios2_push_dummy_call);

  if (tdesc_data != nullptr)
    tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data));

  return gdbarch;
}

void _initialize_nios2_tdep ();
void
_initialize_nios2_tdep ()
{
  gdbarch_register (bfd_arch_nios2, nios2_gdbarch_init, NULL);
  initialize_tdesc_nios2 ();

  /* Allow debugging this file's internals.  */
  add_setshow_boolean_cmd ("nios2", class_maintenance, &nios2_debug,
			   _("Set Nios II debugging."),
			   _("Show Nios II debugging."),
			   _("When on, Nios II specific debugging is enabled."),
			   NULL,
			   NULL,
			   &setdebuglist, &showdebuglist);
}
