/* Target-machine dependent code for Nios II, for GDB.
   Copyright (C) 2012-2021 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 >= 0 && 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 = TYPE_LENGTH (valtype);

  /* 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 = TYPE_LENGTH (valtype);

  /* 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,
			struct frame_info *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)
    fprintf_unfiltered (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)
	    fprintf_unfiltered (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)
	    fprintf_unfiltered (gdb_stdlog, "[%04X]", insn & 0xffff);
	  else
	    fprintf_unfiltered (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)
    fprintf_unfiltered (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)
	fprintf_unfiltered (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)
		fprintf_unfiltered
		  (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)
    fprintf_unfiltered (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 (type) > 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 (TYPE_LENGTH (value_type (args[argnum])), 4);
  sp -= arg_space;

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

  /* The struct_return pointer occupies the first parameter-passing
     register.  */
  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 (value_type (arg));
      int len = TYPE_LENGTH (arg_type);

      val = value_contents (arg).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, struct frame_info *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 (struct frame_info *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 (struct frame_info *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 (struct frame_info *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 (struct frame_info *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 (struct frame_info *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 (struct frame_info *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 (struct frame_info *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,
			  struct frame_info *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 ();
  struct gdbarch_tdep *tdep = 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 (struct frame_info *frame, CORE_ADDR *pc)
{
  struct gdbarch *gdbarch = get_frame_arch (frame);
  struct gdbarch_tdep *tdep = 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 (type));
    default:
      return 0;
    }
}

/* Implement the gcc_target_options gdbarch method.  */
static std::string
nios2_gcc_target_options (struct gdbarch *gdbarch)
{
  /* GCC doesn't know "-m32".  */
  return {};
}

/* Initialize the Nios II gdbarch.  */

static struct gdbarch *
nios2_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  struct gdbarch_tdep *tdep;
  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.  */
  tdep = XCNEW (struct gdbarch_tdep);
  gdbarch = gdbarch_alloc (&info, tdep);

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