/* Target-dependent code for the RISC-V architecture, for GDB.

   Copyright (C) 2018-2023 Free Software Foundation, 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 "inferior.h"
#include "symtab.h"
#include "value.h"
#include "gdbcmd.h"
#include "language.h"
#include "gdbcore.h"
#include "symfile.h"
#include "objfiles.h"
#include "gdbtypes.h"
#include "target.h"
#include "arch-utils.h"
#include "regcache.h"
#include "osabi.h"
#include "riscv-tdep.h"
#include "block.h"
#include "reggroups.h"
#include "opcode/riscv.h"
#include "elf/riscv.h"
#include "elf-bfd.h"
#include "symcat.h"
#include "dis-asm.h"
#include "frame-unwind.h"
#include "frame-base.h"
#include "trad-frame.h"
#include "infcall.h"
#include "floatformat.h"
#include "remote.h"
#include "target-descriptions.h"
#include "dwarf2/frame.h"
#include "user-regs.h"
#include "valprint.h"
#include "gdbsupport/common-defs.h"
#include "opcode/riscv-opc.h"
#include "cli/cli-decode.h"
#include "observable.h"
#include "prologue-value.h"
#include "arch/riscv.h"
#include "riscv-ravenscar-thread.h"

/* The stack must be 16-byte aligned.  */
#define SP_ALIGNMENT 16

/* The biggest alignment that the target supports.  */
#define BIGGEST_ALIGNMENT 16

/* Define a series of is_XXX_insn functions to check if the value INSN
   is an instance of instruction XXX.  */
#define DECLARE_INSN(INSN_NAME, INSN_MATCH, INSN_MASK) \
static inline bool is_ ## INSN_NAME ## _insn (long insn) \
{ \
  return (insn & INSN_MASK) == INSN_MATCH; \
}
#include "opcode/riscv-opc.h"
#undef DECLARE_INSN

/* When this is set to non-zero debugging information about breakpoint
   kinds will be printed.  */

static unsigned int riscv_debug_breakpoints = 0;

/* When this is set to non-zero debugging information about inferior calls
   will be printed.  */

static unsigned int riscv_debug_infcall = 0;

/* When this is set to non-zero debugging information about stack unwinding
   will be printed.  */

static unsigned int riscv_debug_unwinder = 0;

/* When this is set to non-zero debugging information about gdbarch
   initialisation will be printed.  */

static unsigned int riscv_debug_gdbarch = 0;

/* The names of the RISC-V target description features.  */
const char *riscv_feature_name_csr = "org.gnu.gdb.riscv.csr";
static const char *riscv_feature_name_cpu = "org.gnu.gdb.riscv.cpu";
static const char *riscv_feature_name_fpu = "org.gnu.gdb.riscv.fpu";
static const char *riscv_feature_name_virtual = "org.gnu.gdb.riscv.virtual";
static const char *riscv_feature_name_vector = "org.gnu.gdb.riscv.vector";

/* The current set of options to be passed to the disassembler.  */
static char *riscv_disassembler_options;

/* Cached information about a frame.  */

struct riscv_unwind_cache
{
  /* The register from which we can calculate the frame base.  This is
     usually $sp or $fp.  */
  int frame_base_reg;

  /* The offset from the current value in register FRAME_BASE_REG to the
     actual frame base address.  */
  int frame_base_offset;

  /* Information about previous register values.  */
  trad_frame_saved_reg *regs;

  /* The id for this frame.  */
  struct frame_id this_id;

  /* The base (stack) address for this frame.  This is the stack pointer
     value on entry to this frame before any adjustments are made.  */
  CORE_ADDR frame_base;
};

/* RISC-V specific register group for CSRs.  */

static const reggroup *csr_reggroup = nullptr;

/* Callback function for user_reg_add.  */

static struct value *
value_of_riscv_user_reg (frame_info_ptr frame, const void *baton)
{
  const int *reg_p = (const int *) baton;
  return value_of_register (*reg_p, frame);
}

/* Information about a register alias that needs to be set up for this
   target.  These are collected when the target's XML description is
   analysed, and then processed later, once the gdbarch has been created.  */

class riscv_pending_register_alias
{
public:
  /* Constructor.  */

  riscv_pending_register_alias (const char *name, const void *baton)
    : m_name (name),
      m_baton (baton)
  { /* Nothing.  */ }

  /* Convert this into a user register for GDBARCH.  */

  void create (struct gdbarch *gdbarch) const
  {
    user_reg_add (gdbarch, m_name, value_of_riscv_user_reg, m_baton);
  }

private:
  /* The name for this alias.  */
  const char *m_name;

  /* The baton value for passing to user_reg_add.  This must point to some
     data that will live for at least as long as the gdbarch object to
     which the user register is attached.  */
  const void *m_baton;
};

/* A set of registers that we expect to find in a tdesc_feature.  These
   are use in RISCV_GDBARCH_INIT when processing the target description.  */

struct riscv_register_feature
{
  explicit riscv_register_feature (const char *feature_name)
    : m_feature_name (feature_name)
  { /* Delete.  */ }

  riscv_register_feature () = delete;
  DISABLE_COPY_AND_ASSIGN (riscv_register_feature);

  /* Information for a single register.  */
  struct register_info
  {
    /* The GDB register number for this register.  */
    int regnum;

    /* List of names for this register.  The first name in this list is the
       preferred name, the name GDB should use when describing this
       register.  */
    std::vector<const char *> names;

    /* Look in FEATURE for a register with a name from this classes names
       list.  If the register is found then register its number with
       TDESC_DATA and add all its aliases to the ALIASES list.
       PREFER_FIRST_NAME_P is used when deciding which aliases to create.  */
    bool check (struct tdesc_arch_data *tdesc_data,
		const struct tdesc_feature *feature,
		bool prefer_first_name_p,
		std::vector<riscv_pending_register_alias> *aliases) const;
  };

  /* Return the name of this feature.  */
  const char *name () const
  { return m_feature_name; }

protected:

  /* Return a target description feature extracted from TDESC for this
     register feature.  Will return nullptr if there is no feature in TDESC
     with the name M_FEATURE_NAME.  */
  const struct tdesc_feature *tdesc_feature (const struct target_desc *tdesc) const
  {
    return tdesc_find_feature (tdesc, name ());
  }

  /* List of all the registers that we expect that we might find in this
     register set.  */
  std::vector<struct register_info> m_registers;

private:

  /* The name for this feature.  This is the name used to find this feature
     within the target description.  */
  const char *m_feature_name;
};

/* See description in the class declaration above.  */

bool
riscv_register_feature::register_info::check
	(struct tdesc_arch_data *tdesc_data,
	 const struct tdesc_feature *feature,
	 bool prefer_first_name_p,
	 std::vector<riscv_pending_register_alias> *aliases) const
{
  for (const char *name : this->names)
    {
      bool found = tdesc_numbered_register (feature, tdesc_data,
					    this->regnum, name);
      if (found)
	{
	  /* We know that the target description mentions this
	     register.  In RISCV_REGISTER_NAME we ensure that GDB
	     always uses the first name for each register, so here we
	     add aliases for all of the remaining names.  */
	  int start_index = prefer_first_name_p ? 1 : 0;
	  for (int i = start_index; i < this->names.size (); ++i)
	    {
	      const char *alias = this->names[i];
	      if (alias == name && !prefer_first_name_p)
		continue;
	      aliases->emplace_back (alias, (void *) &this->regnum);
	    }
	  return true;
	}
    }
  return false;
}

/* Class representing the x-registers feature set.  */

struct riscv_xreg_feature : public riscv_register_feature
{
  riscv_xreg_feature ()
    : riscv_register_feature (riscv_feature_name_cpu)
  {
    m_registers =  {
      { RISCV_ZERO_REGNUM + 0, { "zero", "x0" } },
      { RISCV_ZERO_REGNUM + 1, { "ra", "x1" } },
      { RISCV_ZERO_REGNUM + 2, { "sp", "x2" } },
      { RISCV_ZERO_REGNUM + 3, { "gp", "x3" } },
      { RISCV_ZERO_REGNUM + 4, { "tp", "x4" } },
      { RISCV_ZERO_REGNUM + 5, { "t0", "x5" } },
      { RISCV_ZERO_REGNUM + 6, { "t1", "x6" } },
      { RISCV_ZERO_REGNUM + 7, { "t2", "x7" } },
      { RISCV_ZERO_REGNUM + 8, { "fp", "x8", "s0" } },
      { RISCV_ZERO_REGNUM + 9, { "s1", "x9" } },
      { RISCV_ZERO_REGNUM + 10, { "a0", "x10" } },
      { RISCV_ZERO_REGNUM + 11, { "a1", "x11" } },
      { RISCV_ZERO_REGNUM + 12, { "a2", "x12" } },
      { RISCV_ZERO_REGNUM + 13, { "a3", "x13" } },
      { RISCV_ZERO_REGNUM + 14, { "a4", "x14" } },
      { RISCV_ZERO_REGNUM + 15, { "a5", "x15" } },
      { RISCV_ZERO_REGNUM + 16, { "a6", "x16" } },
      { RISCV_ZERO_REGNUM + 17, { "a7", "x17" } },
      { RISCV_ZERO_REGNUM + 18, { "s2", "x18" } },
      { RISCV_ZERO_REGNUM + 19, { "s3", "x19" } },
      { RISCV_ZERO_REGNUM + 20, { "s4", "x20" } },
      { RISCV_ZERO_REGNUM + 21, { "s5", "x21" } },
      { RISCV_ZERO_REGNUM + 22, { "s6", "x22" } },
      { RISCV_ZERO_REGNUM + 23, { "s7", "x23" } },
      { RISCV_ZERO_REGNUM + 24, { "s8", "x24" } },
      { RISCV_ZERO_REGNUM + 25, { "s9", "x25" } },
      { RISCV_ZERO_REGNUM + 26, { "s10", "x26" } },
      { RISCV_ZERO_REGNUM + 27, { "s11", "x27" } },
      { RISCV_ZERO_REGNUM + 28, { "t3", "x28" } },
      { RISCV_ZERO_REGNUM + 29, { "t4", "x29" } },
      { RISCV_ZERO_REGNUM + 30, { "t5", "x30" } },
      { RISCV_ZERO_REGNUM + 31, { "t6", "x31" } },
      { RISCV_ZERO_REGNUM + 32, { "pc" } }
    };
  }

  /* Return the preferred name for the register with gdb register number
     REGNUM, which must be in the inclusive range RISCV_ZERO_REGNUM to
     RISCV_PC_REGNUM.  */
  const char *register_name (int regnum) const
  {
    gdb_assert (regnum >= RISCV_ZERO_REGNUM && regnum <= m_registers.size ());
    return m_registers[regnum].names[0];
  }

  /* Check this feature within TDESC, record the registers from this
     feature into TDESC_DATA and update ALIASES and FEATURES.  */
  bool check (const struct target_desc *tdesc,
	      struct tdesc_arch_data *tdesc_data,
	      std::vector<riscv_pending_register_alias> *aliases,
	      struct riscv_gdbarch_features *features) const
  {
    const struct tdesc_feature *feature_cpu = tdesc_feature (tdesc);

    if (feature_cpu == nullptr)
      return false;

    bool seen_an_optional_reg_p = false;
    for (const auto &reg : m_registers)
      {
	bool found = reg.check (tdesc_data, feature_cpu, true, aliases);

	bool is_optional_reg_p = (reg.regnum >= RISCV_ZERO_REGNUM + 16
				  && reg.regnum < RISCV_ZERO_REGNUM + 32);

	if (!found && (!is_optional_reg_p || seen_an_optional_reg_p))
	  return false;
	else if (found && is_optional_reg_p)
	  seen_an_optional_reg_p = true;
      }

    /* Check that all of the core cpu registers have the same bitsize.  */
    int xlen_bitsize = tdesc_register_bitsize (feature_cpu, "pc");

    bool valid_p = true;
    for (auto &tdesc_reg : feature_cpu->registers)
      valid_p &= (tdesc_reg->bitsize == xlen_bitsize);

    features->xlen = (xlen_bitsize / 8);
    features->embedded = !seen_an_optional_reg_p;

    return valid_p;
  }
};

/* An instance of the x-register feature set.  */

static const struct riscv_xreg_feature riscv_xreg_feature;

/* Class representing the f-registers feature set.  */

struct riscv_freg_feature : public riscv_register_feature
{
  riscv_freg_feature ()
    : riscv_register_feature (riscv_feature_name_fpu)
  {
    m_registers =  {
      { RISCV_FIRST_FP_REGNUM + 0, { "ft0", "f0" } },
      { RISCV_FIRST_FP_REGNUM + 1, { "ft1", "f1" } },
      { RISCV_FIRST_FP_REGNUM + 2, { "ft2", "f2" } },
      { RISCV_FIRST_FP_REGNUM + 3, { "ft3", "f3" } },
      { RISCV_FIRST_FP_REGNUM + 4, { "ft4", "f4" } },
      { RISCV_FIRST_FP_REGNUM + 5, { "ft5", "f5" } },
      { RISCV_FIRST_FP_REGNUM + 6, { "ft6", "f6" } },
      { RISCV_FIRST_FP_REGNUM + 7, { "ft7", "f7" } },
      { RISCV_FIRST_FP_REGNUM + 8, { "fs0", "f8" } },
      { RISCV_FIRST_FP_REGNUM + 9, { "fs1", "f9" } },
      { RISCV_FIRST_FP_REGNUM + 10, { "fa0", "f10" } },
      { RISCV_FIRST_FP_REGNUM + 11, { "fa1", "f11" } },
      { RISCV_FIRST_FP_REGNUM + 12, { "fa2", "f12" } },
      { RISCV_FIRST_FP_REGNUM + 13, { "fa3", "f13" } },
      { RISCV_FIRST_FP_REGNUM + 14, { "fa4", "f14" } },
      { RISCV_FIRST_FP_REGNUM + 15, { "fa5", "f15" } },
      { RISCV_FIRST_FP_REGNUM + 16, { "fa6", "f16" } },
      { RISCV_FIRST_FP_REGNUM + 17, { "fa7", "f17" } },
      { RISCV_FIRST_FP_REGNUM + 18, { "fs2", "f18" } },
      { RISCV_FIRST_FP_REGNUM + 19, { "fs3", "f19" } },
      { RISCV_FIRST_FP_REGNUM + 20, { "fs4", "f20" } },
      { RISCV_FIRST_FP_REGNUM + 21, { "fs5", "f21" } },
      { RISCV_FIRST_FP_REGNUM + 22, { "fs6", "f22" } },
      { RISCV_FIRST_FP_REGNUM + 23, { "fs7", "f23" } },
      { RISCV_FIRST_FP_REGNUM + 24, { "fs8", "f24" } },
      { RISCV_FIRST_FP_REGNUM + 25, { "fs9", "f25" } },
      { RISCV_FIRST_FP_REGNUM + 26, { "fs10", "f26" } },
      { RISCV_FIRST_FP_REGNUM + 27, { "fs11", "f27" } },
      { RISCV_FIRST_FP_REGNUM + 28, { "ft8", "f28" } },
      { RISCV_FIRST_FP_REGNUM + 29, { "ft9", "f29" } },
      { RISCV_FIRST_FP_REGNUM + 30, { "ft10", "f30" } },
      { RISCV_FIRST_FP_REGNUM + 31, { "ft11", "f31" } },
      { RISCV_CSR_FFLAGS_REGNUM, { "fflags", "csr1" } },
      { RISCV_CSR_FRM_REGNUM, { "frm", "csr2" } },
      { RISCV_CSR_FCSR_REGNUM, { "fcsr", "csr3" } },
    };
  }

  /* Return the preferred name for the register with gdb register number
     REGNUM, which must be in the inclusive range RISCV_FIRST_FP_REGNUM to
     RISCV_LAST_FP_REGNUM.  */
  const char *register_name (int regnum) const
  {
    gdb_static_assert (RISCV_LAST_FP_REGNUM == RISCV_FIRST_FP_REGNUM + 31);
    gdb_assert (regnum >= RISCV_FIRST_FP_REGNUM
		&& regnum <= RISCV_LAST_FP_REGNUM);
    regnum -= RISCV_FIRST_FP_REGNUM;
    return m_registers[regnum].names[0];
  }

  /* Check this feature within TDESC, record the registers from this
     feature into TDESC_DATA and update ALIASES and FEATURES.  */
  bool check (const struct target_desc *tdesc,
	      struct tdesc_arch_data *tdesc_data,
	      std::vector<riscv_pending_register_alias> *aliases,
	      struct riscv_gdbarch_features *features) const
  {
    const struct tdesc_feature *feature_fpu = tdesc_feature (tdesc);

    /* It's fine if this feature is missing.  Update the architecture
       feature set and return.  */
    if (feature_fpu == nullptr)
      {
	features->flen = 0;
	return true;
      }

    /* Check all of the floating pointer registers are present.  We also
       check that the floating point CSRs are present too, though if these
       are missing this is not fatal.  */
    for (const auto &reg : m_registers)
      {
	bool found = reg.check (tdesc_data, feature_fpu, true, aliases);

	bool is_ctrl_reg_p = reg.regnum > RISCV_LAST_FP_REGNUM;

	if (!found && !is_ctrl_reg_p)
	  return false;
      }

    /* Look through all of the floating point registers (not the FP CSRs
       though), and check they all have the same bitsize.  Use this bitsize
       to update the feature set for this gdbarch.  */
    int fp_bitsize = -1;
    for (const auto &reg : m_registers)
      {
	/* Stop once we get to the CSRs which are at the end of the
	   M_REGISTERS list.  */
	if (reg.regnum > RISCV_LAST_FP_REGNUM)
	  break;

	int reg_bitsize = -1;
	for (const char *name : reg.names)
	  {
	    if (tdesc_unnumbered_register (feature_fpu, name))
	      {
		reg_bitsize = tdesc_register_bitsize (feature_fpu, name);
		break;
	      }
	  }
	gdb_assert (reg_bitsize != -1);
	if (fp_bitsize == -1)
	  fp_bitsize = reg_bitsize;
	else if (fp_bitsize != reg_bitsize)
	  return false;
      }

    features->flen = (fp_bitsize / 8);
    return true;
  }
};

/* An instance of the f-register feature set.  */

static const struct riscv_freg_feature riscv_freg_feature;

/* Class representing the virtual registers.  These are not physical
   registers on the hardware, but might be available from the target.
   These are not pseudo registers, reading these really does result in a
   register read from the target, it is just that there might not be a
   physical register backing the result.  */

struct riscv_virtual_feature : public riscv_register_feature
{
  riscv_virtual_feature ()
    : riscv_register_feature (riscv_feature_name_virtual)
  {
    m_registers =  {
      { RISCV_PRIV_REGNUM, { "priv" } }
    };
  }

  bool check (const struct target_desc *tdesc,
	      struct tdesc_arch_data *tdesc_data,
	      std::vector<riscv_pending_register_alias> *aliases,
	      struct riscv_gdbarch_features *features) const
  {
    const struct tdesc_feature *feature_virtual = tdesc_feature (tdesc);

    /* It's fine if this feature is missing.  */
    if (feature_virtual == nullptr)
      return true;

    /* We don't check the return value from the call to check here, all the
       registers in this feature are optional.  */
    for (const auto &reg : m_registers)
      reg.check (tdesc_data, feature_virtual, true, aliases);

    return true;
  }
};

/* An instance of the virtual register feature.  */

static const struct riscv_virtual_feature riscv_virtual_feature;

/* Class representing the CSR feature.  */

struct riscv_csr_feature : public riscv_register_feature
{
  riscv_csr_feature ()
    : riscv_register_feature (riscv_feature_name_csr)
  {
    m_registers = {
#define DECLARE_CSR(NAME,VALUE,CLASS,DEFINE_VER,ABORT_VER)		\
      { RISCV_ ## VALUE ## _REGNUM, { # NAME } },
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
    };
    riscv_create_csr_aliases ();
  }

  bool check (const struct target_desc *tdesc,
	      struct tdesc_arch_data *tdesc_data,
	      std::vector<riscv_pending_register_alias> *aliases,
	      struct riscv_gdbarch_features *features) const
  {
    const struct tdesc_feature *feature_csr = tdesc_feature (tdesc);

    /* It's fine if this feature is missing.  */
    if (feature_csr == nullptr)
      return true;

    /* We don't check the return value from the call to check here, all the
       registers in this feature are optional.  */
    for (const auto &reg : m_registers)
      reg.check (tdesc_data, feature_csr, true, aliases);

    return true;
  }

private:

  /* Complete RISCV_CSR_FEATURE, building the CSR alias names and adding them
     to the name list for each register.  */

  void
  riscv_create_csr_aliases ()
  {
    for (auto &reg : m_registers)
      {
	int csr_num = reg.regnum - RISCV_FIRST_CSR_REGNUM;
	gdb::unique_xmalloc_ptr<char> alias = xstrprintf ("csr%d", csr_num);
	reg.names.push_back (alias.release ());
      }
  }
};

/* An instance of the csr register feature.  */

static const struct riscv_csr_feature riscv_csr_feature;

/* Class representing the v-registers feature set.  */

struct riscv_vector_feature : public riscv_register_feature
{
  riscv_vector_feature ()
    : riscv_register_feature (riscv_feature_name_vector)
  {
    m_registers =  {
      { RISCV_V0_REGNUM + 0, { "v0" } },
      { RISCV_V0_REGNUM + 1, { "v1" } },
      { RISCV_V0_REGNUM + 2, { "v2" } },
      { RISCV_V0_REGNUM + 3, { "v3" } },
      { RISCV_V0_REGNUM + 4, { "v4" } },
      { RISCV_V0_REGNUM + 5, { "v5" } },
      { RISCV_V0_REGNUM + 6, { "v6" } },
      { RISCV_V0_REGNUM + 7, { "v7" } },
      { RISCV_V0_REGNUM + 8, { "v8" } },
      { RISCV_V0_REGNUM + 9, { "v9" } },
      { RISCV_V0_REGNUM + 10, { "v10" } },
      { RISCV_V0_REGNUM + 11, { "v11" } },
      { RISCV_V0_REGNUM + 12, { "v12" } },
      { RISCV_V0_REGNUM + 13, { "v13" } },
      { RISCV_V0_REGNUM + 14, { "v14" } },
      { RISCV_V0_REGNUM + 15, { "v15" } },
      { RISCV_V0_REGNUM + 16, { "v16" } },
      { RISCV_V0_REGNUM + 17, { "v17" } },
      { RISCV_V0_REGNUM + 18, { "v18" } },
      { RISCV_V0_REGNUM + 19, { "v19" } },
      { RISCV_V0_REGNUM + 20, { "v20" } },
      { RISCV_V0_REGNUM + 21, { "v21" } },
      { RISCV_V0_REGNUM + 22, { "v22" } },
      { RISCV_V0_REGNUM + 23, { "v23" } },
      { RISCV_V0_REGNUM + 24, { "v24" } },
      { RISCV_V0_REGNUM + 25, { "v25" } },
      { RISCV_V0_REGNUM + 26, { "v26" } },
      { RISCV_V0_REGNUM + 27, { "v27" } },
      { RISCV_V0_REGNUM + 28, { "v28" } },
      { RISCV_V0_REGNUM + 29, { "v29" } },
      { RISCV_V0_REGNUM + 30, { "v30" } },
      { RISCV_V0_REGNUM + 31, { "v31" } },
    };
  }

  /* Return the preferred name for the register with gdb register number
     REGNUM, which must be in the inclusive range RISCV_V0_REGNUM to
     RISCV_V0_REGNUM + 31.  */
  const char *register_name (int regnum) const
  {
    gdb_assert (regnum >= RISCV_V0_REGNUM
		&& regnum <= RISCV_V0_REGNUM + 31);
    regnum -= RISCV_V0_REGNUM;
    return m_registers[regnum].names[0];
  }

  /* Check this feature within TDESC, record the registers from this
     feature into TDESC_DATA and update ALIASES and FEATURES.  */
  bool check (const struct target_desc *tdesc,
	      struct tdesc_arch_data *tdesc_data,
	      std::vector<riscv_pending_register_alias> *aliases,
	      struct riscv_gdbarch_features *features) const
  {
    const struct tdesc_feature *feature_vector = tdesc_feature (tdesc);

    /* It's fine if this feature is missing.  Update the architecture
       feature set and return.  */
    if (feature_vector == nullptr)
      {
	features->vlen = 0;
	return true;
      }

    /* Check all of the vector registers are present.  */
    for (const auto &reg : m_registers)
      {
	if (!reg.check (tdesc_data, feature_vector, true, aliases))
	  return false;
      }

    /* Look through all of the vector registers and check they all have the
       same bitsize.  Use this bitsize to update the feature set for this
       gdbarch.  */
    int vector_bitsize = -1;
    for (const auto &reg : m_registers)
      {
	int reg_bitsize = -1;
	for (const char *name : reg.names)
	  {
	    if (tdesc_unnumbered_register (feature_vector, name))
	      {
		reg_bitsize = tdesc_register_bitsize (feature_vector, name);
		break;
	      }
	  }
	gdb_assert (reg_bitsize != -1);
	if (vector_bitsize == -1)
	  vector_bitsize = reg_bitsize;
	else if (vector_bitsize != reg_bitsize)
	  return false;
      }

    features->vlen = (vector_bitsize / 8);
    return true;
  }
};

/* An instance of the v-register feature set.  */

static const struct riscv_vector_feature riscv_vector_feature;

/* Controls whether we place compressed breakpoints or not.  When in auto
   mode GDB tries to determine if the target supports compressed
   breakpoints, and uses them if it does.  */

static enum auto_boolean use_compressed_breakpoints;

/* The show callback for 'show riscv use-compressed-breakpoints'.  */

static void
show_use_compressed_breakpoints (struct ui_file *file, int from_tty,
				 struct cmd_list_element *c,
				 const char *value)
{
  gdb_printf (file,
	      _("Debugger's use of compressed breakpoints is set "
		"to %s.\n"), value);
}

/* The set and show lists for 'set riscv' and 'show riscv' prefixes.  */

static struct cmd_list_element *setriscvcmdlist = NULL;
static struct cmd_list_element *showriscvcmdlist = NULL;

/* The set and show lists for 'set riscv' and 'show riscv' prefixes.  */

static struct cmd_list_element *setdebugriscvcmdlist = NULL;
static struct cmd_list_element *showdebugriscvcmdlist = NULL;

/* The show callback for all 'show debug riscv VARNAME' variables.  */

static void
show_riscv_debug_variable (struct ui_file *file, int from_tty,
			   struct cmd_list_element *c,
			   const char *value)
{
  gdb_printf (file,
	      _("RiscV debug variable `%s' is set to: %s\n"),
	      c->name, value);
}

/* See riscv-tdep.h.  */

int
riscv_isa_xlen (struct gdbarch *gdbarch)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  return tdep->isa_features.xlen;
}

/* See riscv-tdep.h.  */

int
riscv_abi_xlen (struct gdbarch *gdbarch)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  return tdep->abi_features.xlen;
}

/* See riscv-tdep.h.  */

int
riscv_isa_flen (struct gdbarch *gdbarch)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  return tdep->isa_features.flen;
}

/* See riscv-tdep.h.  */

int
riscv_abi_flen (struct gdbarch *gdbarch)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  return tdep->abi_features.flen;
}

/* See riscv-tdep.h.  */

bool
riscv_abi_embedded (struct gdbarch *gdbarch)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  return tdep->abi_features.embedded;
}

/* Return true if the target for GDBARCH has floating point hardware.  */

static bool
riscv_has_fp_regs (struct gdbarch *gdbarch)
{
  return (riscv_isa_flen (gdbarch) > 0);
}

/* Return true if GDBARCH is using any of the floating point hardware ABIs.  */

static bool
riscv_has_fp_abi (struct gdbarch *gdbarch)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  return tdep->abi_features.flen > 0;
}

/* Return true if REGNO is a floating pointer register.  */

static bool
riscv_is_fp_regno_p (int regno)
{
  return (regno >= RISCV_FIRST_FP_REGNUM
	  && regno <= RISCV_LAST_FP_REGNUM);
}

/* Implement the breakpoint_kind_from_pc gdbarch method.  */

static int
riscv_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *pcptr)
{
  if (use_compressed_breakpoints == AUTO_BOOLEAN_AUTO)
    {
      bool unaligned_p = false;
      gdb_byte buf[1];

      /* Some targets don't support unaligned reads.  The address can only
	 be unaligned if the C extension is supported.  So it is safe to
	 use a compressed breakpoint in this case.  */
      if (*pcptr & 0x2)
	unaligned_p = true;
      else
	{
	  /* Read the opcode byte to determine the instruction length.  If
	     the read fails this may be because we tried to set the
	     breakpoint at an invalid address, in this case we provide a
	     fake result which will give a breakpoint length of 4.
	     Hopefully when we try to actually insert the breakpoint we
	     will see a failure then too which will be reported to the
	     user.  */
	  if (target_read_code (*pcptr, buf, 1) == -1)
	    buf[0] = 0;
	}

      if (riscv_debug_breakpoints)
	{
	  const char *bp = (unaligned_p || riscv_insn_length (buf[0]) == 2
			    ? "C.EBREAK" : "EBREAK");

	  gdb_printf (gdb_stdlog, "Using %s for breakpoint at %s ",
		      bp, paddress (gdbarch, *pcptr));
	  if (unaligned_p)
	    gdb_printf (gdb_stdlog, "(unaligned address)\n");
	  else
	    gdb_printf (gdb_stdlog, "(instruction length %d)\n",
			riscv_insn_length (buf[0]));
	}
      if (unaligned_p || riscv_insn_length (buf[0]) == 2)
	return 2;
      else
	return 4;
    }
  else if (use_compressed_breakpoints == AUTO_BOOLEAN_TRUE)
    return 2;
  else
    return 4;
}

/* Implement the sw_breakpoint_from_kind gdbarch method.  */

static const gdb_byte *
riscv_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
  static const gdb_byte ebreak[] = { 0x73, 0x00, 0x10, 0x00, };
  static const gdb_byte c_ebreak[] = { 0x02, 0x90 };

  *size = kind;
  switch (kind)
    {
    case 2:
      return c_ebreak;
    case 4:
      return ebreak;
    default:
      gdb_assert_not_reached ("unhandled breakpoint kind");
    }
}

/* Implement the register_name gdbarch method.  This is used instead of
   the function supplied by calling TDESC_USE_REGISTERS so that we can
   ensure the preferred names are offered for x-regs and f-regs.  */

static const char *
riscv_register_name (struct gdbarch *gdbarch, int regnum)
{
  /* Lookup the name through the target description.  If we get back NULL
     then this is an unknown register.  If we do get a name back then we
     look up the registers preferred name below.  */
  const char *name = tdesc_register_name (gdbarch, regnum);
  gdb_assert (name != nullptr);
  if (name[0] == '\0')
    return name;

  /* We want GDB to use the ABI names for registers even if the target
     gives us a target description with the architectural name.  For
     example we want to see 'ra' instead of 'x1' whatever the target
     description called it.  */
  if (regnum >= RISCV_ZERO_REGNUM && regnum < RISCV_FIRST_FP_REGNUM)
    return riscv_xreg_feature.register_name (regnum);

  /* Like with the x-regs we prefer the abi names for the floating point
     registers.  If the target doesn't have floating point registers then
     the tdesc_register_name call above should have returned an empty
     string.  */
  if (regnum >= RISCV_FIRST_FP_REGNUM && regnum <= RISCV_LAST_FP_REGNUM)
    {
      gdb_assert (riscv_has_fp_regs (gdbarch));
      return riscv_freg_feature.register_name (regnum);
    }

  /* Some targets (QEMU) are reporting these three registers twice, once
     in the FPU feature, and once in the CSR feature.  Both of these read
     the same underlying state inside the target, but naming the register
     twice in the target description results in GDB having two registers
     with the same name, only one of which can ever be accessed, but both
     will show up in 'info register all'.  Unless, we identify the
     duplicate copies of these registers (in riscv_tdesc_unknown_reg) and
     then hide the registers here by giving them no name.  */
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  if (tdep->duplicate_fflags_regnum == regnum
      || tdep->duplicate_frm_regnum == regnum
      || tdep->duplicate_fcsr_regnum == regnum)
    return "";

  /* The remaining registers are different.  For all other registers on the
     machine we prefer to see the names that the target description
     provides.  This is particularly important for CSRs which might be
     renamed over time.  If GDB keeps track of the "latest" name, but a
     particular target provides an older name then we don't want to force
     users to see the newer name in register output.

     The other case that reaches here are any registers that the target
     provided that GDB is completely unaware of.  For these we have no
     choice but to accept the target description name.

     Just accept whatever name TDESC_REGISTER_NAME returned.  */
  return name;
}

/* Implement gdbarch_pseudo_register_read.  Read pseudo-register REGNUM
   from REGCACHE and place the register value into BUF.  BUF is sized
   based on the type of register REGNUM, all of BUF should be written too,
   the result should be sign or zero extended as appropriate.  */

static enum register_status
riscv_pseudo_register_read (struct gdbarch *gdbarch,
			    readable_regcache *regcache,
			    int regnum, gdb_byte *buf)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

  if (regnum == tdep->fflags_regnum || regnum == tdep->frm_regnum)
    {
      /* Clear BUF.  */
      memset (buf, 0, register_size (gdbarch, regnum));

      /* Read the first byte of the fcsr register, this contains both frm
	 and fflags.  */
      enum register_status status
	= regcache->raw_read_part (RISCV_CSR_FCSR_REGNUM, 0, 1, buf);

      if (status != REG_VALID)
	return status;

      /* Extract the appropriate parts.  */
      if (regnum == tdep->fflags_regnum)
	buf[0] &= 0x1f;
      else if (regnum == tdep->frm_regnum)
	buf[0] = (buf[0] >> 5) & 0x7;

      return REG_VALID;
    }

  return REG_UNKNOWN;
}

/* Implement gdbarch_pseudo_register_write.  Write the contents of BUF into
   pseudo-register REGNUM in REGCACHE.  BUF is sized based on the type of
   register REGNUM.  */

static void
riscv_pseudo_register_write (struct gdbarch *gdbarch,
			     struct regcache *regcache, int regnum,
			     const gdb_byte *buf)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

  if (regnum == tdep->fflags_regnum || regnum == tdep->frm_regnum)
    {
      int fcsr_regnum = RISCV_CSR_FCSR_REGNUM;
      gdb_byte raw_buf[register_size (gdbarch, fcsr_regnum)];

      regcache->raw_read (fcsr_regnum, raw_buf);

      if (regnum == tdep->fflags_regnum)
	raw_buf[0] = (raw_buf[0] & ~0x1f) | (buf[0] & 0x1f);
      else if (regnum == tdep->frm_regnum)
	raw_buf[0] = (raw_buf[0] & ~(0x7 << 5)) | ((buf[0] & 0x7) << 5);

      regcache->raw_write (fcsr_regnum, raw_buf);
    }
  else
    gdb_assert_not_reached ("unknown pseudo register %d", regnum);
}

/* Implement the cannot_store_register gdbarch method.  The zero register
   (x0) is read-only on RISC-V.  */

static int
riscv_cannot_store_register (struct gdbarch *gdbarch, int regnum)
{
  return regnum == RISCV_ZERO_REGNUM;
}

/* Construct a type for 64-bit FP registers.  */

static struct type *
riscv_fpreg_d_type (struct gdbarch *gdbarch)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

  if (tdep->riscv_fpreg_d_type == nullptr)
    {
      const struct builtin_type *bt = builtin_type (gdbarch);

      /* The type we're building is this: */
#if 0
      union __gdb_builtin_type_fpreg_d
      {
	float f;
	double d;
      };
#endif

      struct type *t;

      t = arch_composite_type (gdbarch,
			       "__gdb_builtin_type_fpreg_d", TYPE_CODE_UNION);
      append_composite_type_field (t, "float", bt->builtin_float);
      append_composite_type_field (t, "double", bt->builtin_double);
      t->set_is_vector (true);
      t->set_name ("builtin_type_fpreg_d");
      tdep->riscv_fpreg_d_type = t;
    }

  return tdep->riscv_fpreg_d_type;
}

/* Implement the register_type gdbarch method.  This is installed as an
   for the override setup by TDESC_USE_REGISTERS, for most registers we
   delegate the type choice to the target description, but for a few
   registers we try to improve the types if the target description has
   taken a simplistic approach.  */

static struct type *
riscv_register_type (struct gdbarch *gdbarch, int regnum)
{
  struct type *type = tdesc_register_type (gdbarch, regnum);
  int xlen = riscv_isa_xlen (gdbarch);

  /* We want to perform some specific type "fixes" in cases where we feel
     that we really can do better than the target description.  For all
     other cases we just return what the target description says.  */
  if (riscv_is_fp_regno_p (regnum))
    {
      /* This spots the case for RV64 where the double is defined as
	 either 'ieee_double' or 'float' (which is the generic name that
	 converts to 'double' on 64-bit).  In these cases its better to
	 present the registers using a union type.  */
      int flen = riscv_isa_flen (gdbarch);
      if (flen == 8
	  && type->code () == TYPE_CODE_FLT
	  && type->length () == flen
	  && (strcmp (type->name (), "builtin_type_ieee_double") == 0
	      || strcmp (type->name (), "double") == 0))
	type = riscv_fpreg_d_type (gdbarch);
    }

  if ((regnum == gdbarch_pc_regnum (gdbarch)
       || regnum == RISCV_RA_REGNUM
       || regnum == RISCV_FP_REGNUM
       || regnum == RISCV_SP_REGNUM
       || regnum == RISCV_GP_REGNUM
       || regnum == RISCV_TP_REGNUM)
      && type->code () == TYPE_CODE_INT
      && type->length () == xlen)
    {
      /* This spots the case where some interesting registers are defined
	 as simple integers of the expected size, we force these registers
	 to be pointers as we believe that is more useful.  */
      if (regnum == gdbarch_pc_regnum (gdbarch)
	  || regnum == RISCV_RA_REGNUM)
	type = builtin_type (gdbarch)->builtin_func_ptr;
      else if (regnum == RISCV_FP_REGNUM
	       || regnum == RISCV_SP_REGNUM
	       || regnum == RISCV_GP_REGNUM
	       || regnum == RISCV_TP_REGNUM)
	type = builtin_type (gdbarch)->builtin_data_ptr;
    }

  return type;
}

/* Helper for riscv_print_registers_info, prints info for a single register
   REGNUM.  */

static void
riscv_print_one_register_info (struct gdbarch *gdbarch,
			       struct ui_file *file,
			       frame_info_ptr frame,
			       int regnum)
{
  const char *name = gdbarch_register_name (gdbarch, regnum);
  struct value *val;
  struct type *regtype;
  int print_raw_format;
  enum tab_stops { value_column_1 = 15 };

  gdb_puts (name, file);
  print_spaces (value_column_1 - strlen (name), file);

  try
    {
      val = value_of_register (regnum, frame);
      regtype = value_type (val);
    }
  catch (const gdb_exception_error &ex)
    {
      /* Handle failure to read a register without interrupting the entire
	 'info registers' flow.  */
      gdb_printf (file, "%s\n", ex.what ());
      return;
    }

  print_raw_format = (value_entirely_available (val)
		      && !value_optimized_out (val));

  if (regtype->code () == TYPE_CODE_FLT
      || (regtype->code () == TYPE_CODE_UNION
	  && regtype->num_fields () == 2
	  && regtype->field (0).type ()->code () == TYPE_CODE_FLT
	  && regtype->field (1).type ()->code () == TYPE_CODE_FLT)
      || (regtype->code () == TYPE_CODE_UNION
	  && regtype->num_fields () == 3
	  && regtype->field (0).type ()->code () == TYPE_CODE_FLT
	  && regtype->field (1).type ()->code () == TYPE_CODE_FLT
	  && regtype->field (2).type ()->code () == TYPE_CODE_FLT))
    {
      struct value_print_options opts;
      const gdb_byte *valaddr = value_contents_for_printing (val).data ();
      enum bfd_endian byte_order = type_byte_order (regtype);

      get_user_print_options (&opts);
      opts.deref_ref = true;

      common_val_print (val, file, 0, &opts, current_language);

      if (print_raw_format)
	{
	  gdb_printf (file, "\t(raw ");
	  print_hex_chars (file, valaddr, regtype->length (), byte_order,
			   true);
	  gdb_printf (file, ")");
	}
    }
  else
    {
      struct value_print_options opts;
      riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

      /* Print the register in hex.  */
      get_formatted_print_options (&opts, 'x');
      opts.deref_ref = true;
      common_val_print (val, file, 0, &opts, current_language);

      if (print_raw_format)
	{
	  if (regnum == RISCV_CSR_MSTATUS_REGNUM)
	    {
	      LONGEST d;
	      int size = register_size (gdbarch, regnum);
	      unsigned xlen;

	      /* The SD field is always in the upper bit of MSTATUS, regardless
		 of the number of bits in MSTATUS.  */
	      d = value_as_long (val);
	      xlen = size * 8;
	      gdb_printf (file,
			  "\tSD:%X VM:%02X MXR:%X PUM:%X MPRV:%X XS:%X "
			  "FS:%X MPP:%x HPP:%X SPP:%X MPIE:%X HPIE:%X "
			  "SPIE:%X UPIE:%X MIE:%X HIE:%X SIE:%X UIE:%X",
			  (int) ((d >> (xlen - 1)) & 0x1),
			  (int) ((d >> 24) & 0x1f),
			  (int) ((d >> 19) & 0x1),
			  (int) ((d >> 18) & 0x1),
			  (int) ((d >> 17) & 0x1),
			  (int) ((d >> 15) & 0x3),
			  (int) ((d >> 13) & 0x3),
			  (int) ((d >> 11) & 0x3),
			  (int) ((d >> 9) & 0x3),
			  (int) ((d >> 8) & 0x1),
			  (int) ((d >> 7) & 0x1),
			  (int) ((d >> 6) & 0x1),
			  (int) ((d >> 5) & 0x1),
			  (int) ((d >> 4) & 0x1),
			  (int) ((d >> 3) & 0x1),
			  (int) ((d >> 2) & 0x1),
			  (int) ((d >> 1) & 0x1),
			  (int) ((d >> 0) & 0x1));
	    }
	  else if (regnum == RISCV_CSR_MISA_REGNUM)
	    {
	      int base;
	      unsigned xlen, i;
	      LONGEST d;
	      int size = register_size (gdbarch, regnum);

	      /* The MXL field is always in the upper two bits of MISA,
		 regardless of the number of bits in MISA.  Mask out other
		 bits to ensure we have a positive value.  */
	      d = value_as_long (val);
	      base = (d >> ((size * 8) - 2)) & 0x3;
	      xlen = 16;

	      for (; base > 0; base--)
		xlen *= 2;
	      gdb_printf (file, "\tRV%d", xlen);

	      for (i = 0; i < 26; i++)
		{
		  if (d & (1 << i))
		    gdb_printf (file, "%c", 'A' + i);
		}
	    }
	  else if (regnum == RISCV_CSR_FCSR_REGNUM
		   || regnum == tdep->fflags_regnum
		   || regnum == tdep->frm_regnum)
	    {
	      LONGEST d = value_as_long (val);

	      gdb_printf (file, "\t");
	      if (regnum != tdep->frm_regnum)
		gdb_printf (file,
			    "NV:%d DZ:%d OF:%d UF:%d NX:%d",
			    (int) ((d >> 4) & 0x1),
			    (int) ((d >> 3) & 0x1),
			    (int) ((d >> 2) & 0x1),
			    (int) ((d >> 1) & 0x1),
			    (int) ((d >> 0) & 0x1));

	      if (regnum != tdep->fflags_regnum)
		{
		  static const char * const sfrm[] =
		    {
		      _("RNE (round to nearest; ties to even)"),
		      _("RTZ (Round towards zero)"),
		      _("RDN (Round down towards -INF)"),
		      _("RUP (Round up towards +INF)"),
		      _("RMM (Round to nearest; ties to max magnitude)"),
		      _("INVALID[5]"),
		      _("INVALID[6]"),
		      /* A value of 0x7 indicates dynamic rounding mode when
			 used within an instructions rounding-mode field, but
			 is invalid within the FRM register.  */
		      _("INVALID[7] (Dynamic rounding mode)"),
		    };
		  int frm = ((regnum == RISCV_CSR_FCSR_REGNUM)
			     ? (d >> 5) : d) & 0x7;

		  gdb_printf (file, "%sFRM:%i [%s]",
			      (regnum == RISCV_CSR_FCSR_REGNUM
			       ? " " : ""),
			      frm, sfrm[frm]);
		}
	    }
	  else if (regnum == RISCV_PRIV_REGNUM)
	    {
	      LONGEST d;
	      uint8_t priv;

	      d = value_as_long (val);
	      priv = d & 0xff;

	      if (priv < 4)
		{
		  static const char * const sprv[] =
		    {
		      "User/Application",
		      "Supervisor",
		      "Hypervisor",
		      "Machine"
		    };
		  gdb_printf (file, "\tprv:%d [%s]",
			      priv, sprv[priv]);
		}
	      else
		gdb_printf (file, "\tprv:%d [INVALID]", priv);
	    }
	  else
	    {
	      /* If not a vector register, print it also according to its
		 natural format.  */
	      if (regtype->is_vector () == 0)
		{
		  get_user_print_options (&opts);
		  opts.deref_ref = true;
		  gdb_printf (file, "\t");
		  common_val_print (val, file, 0, &opts, current_language);
		}
	    }
	}
    }
  gdb_printf (file, "\n");
}

/* Return true if REGNUM is a valid CSR register.  The CSR register space
   is sparsely populated, so not every number is a named CSR.  */

static bool
riscv_is_regnum_a_named_csr (int regnum)
{
  gdb_assert (regnum >= RISCV_FIRST_CSR_REGNUM
	      && regnum <= RISCV_LAST_CSR_REGNUM);

  switch (regnum)
    {
#define DECLARE_CSR(name, num, class, define_ver, abort_ver) case RISCV_ ## num ## _REGNUM:
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
      return true;

    default:
      return false;
    }
}

/* Return true if REGNUM is an unknown CSR identified in
   riscv_tdesc_unknown_reg for GDBARCH.  */

static bool
riscv_is_unknown_csr (struct gdbarch *gdbarch, int regnum)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  return (regnum >= tdep->unknown_csrs_first_regnum
	  && regnum < (tdep->unknown_csrs_first_regnum
		       + tdep->unknown_csrs_count));
}

/* Implement the register_reggroup_p gdbarch method.  Is REGNUM a member
   of REGGROUP?  */

static int
riscv_register_reggroup_p (struct gdbarch  *gdbarch, int regnum,
			   const struct reggroup *reggroup)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

  /* Used by 'info registers' and 'info registers <groupname>'.  */

  if (gdbarch_register_name (gdbarch, regnum)[0] == '\0')
    return 0;

  if (regnum > RISCV_LAST_REGNUM && regnum < gdbarch_num_regs (gdbarch))
    {
      /* Any extra registers from the CSR tdesc_feature (identified in
	 riscv_tdesc_unknown_reg) are removed from the save/restore groups
	 as some targets (QEMU) report CSRs which then can't be read and
	 having unreadable registers in the save/restore group breaks
	 things like inferior calls.

	 The unknown CSRs are also removed from the general group, and
	 added into both the csr and system group.  This is inline with the
	 known CSRs (see below).  */
      if (riscv_is_unknown_csr (gdbarch, regnum))
	{
	  if (reggroup == restore_reggroup || reggroup == save_reggroup
	       || reggroup == general_reggroup)
	    return 0;
	  else if (reggroup == system_reggroup || reggroup == csr_reggroup)
	    return 1;
	}

      /* This is some other unknown register from the target description.
	 In this case we trust whatever the target description says about
	 which groups this register should be in.  */
      int ret = tdesc_register_in_reggroup_p (gdbarch, regnum, reggroup);
      if (ret != -1)
	return ret;

      return default_register_reggroup_p (gdbarch, regnum, reggroup);
    }

  if (reggroup == all_reggroup)
    {
      if (regnum < RISCV_FIRST_CSR_REGNUM || regnum >= RISCV_PRIV_REGNUM)
	return 1;
      if (riscv_is_regnum_a_named_csr (regnum))
	return 1;
      return 0;
    }
  else if (reggroup == float_reggroup)
    return (riscv_is_fp_regno_p (regnum)
	    || regnum == RISCV_CSR_FCSR_REGNUM
	    || regnum == tdep->fflags_regnum
	    || regnum == tdep->frm_regnum);
  else if (reggroup == general_reggroup)
    return regnum < RISCV_FIRST_FP_REGNUM;
  else if (reggroup == restore_reggroup || reggroup == save_reggroup)
    {
      if (riscv_has_fp_regs (gdbarch))
	return (regnum <= RISCV_LAST_FP_REGNUM
		|| regnum == RISCV_CSR_FCSR_REGNUM
		|| regnum == tdep->fflags_regnum
		|| regnum == tdep->frm_regnum);
      else
	return regnum < RISCV_FIRST_FP_REGNUM;
    }
  else if (reggroup == system_reggroup || reggroup == csr_reggroup)
    {
      if (regnum == RISCV_PRIV_REGNUM)
	return 1;
      if (regnum < RISCV_FIRST_CSR_REGNUM || regnum > RISCV_LAST_CSR_REGNUM)
	return 0;
      if (riscv_is_regnum_a_named_csr (regnum))
	return 1;
      return 0;
    }
  else if (reggroup == vector_reggroup)
    return (regnum >= RISCV_V0_REGNUM && regnum <= RISCV_V31_REGNUM);
  else
    return 0;
}

/* Return the name for pseudo-register REGNUM for GDBARCH.  */

static const char *
riscv_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

  if (regnum == tdep->fflags_regnum)
    return "fflags";
  else if (regnum == tdep->frm_regnum)
    return "frm";
  else
    gdb_assert_not_reached ("unknown pseudo register number %d", regnum);
}

/* Return the type for pseudo-register REGNUM for GDBARCH.  */

static struct type *
riscv_pseudo_register_type (struct gdbarch *gdbarch, int regnum)
{
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

  if (regnum == tdep->fflags_regnum || regnum == tdep->frm_regnum)
   return builtin_type (gdbarch)->builtin_int32;
  else
    gdb_assert_not_reached ("unknown pseudo register number %d", regnum);
}

/* Return true (non-zero) if pseudo-register REGNUM from GDBARCH is a
   member of REGGROUP, otherwise return false (zero).  */

static int
riscv_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
				  const struct reggroup *reggroup)
{
  /* The standard function will also work for pseudo-registers.  */
  return riscv_register_reggroup_p (gdbarch, regnum, reggroup);
}

/* Implement the print_registers_info gdbarch method.  This is used by
   'info registers' and 'info all-registers'.  */

static void
riscv_print_registers_info (struct gdbarch *gdbarch,
			    struct ui_file *file,
			    frame_info_ptr frame,
			    int regnum, int print_all)
{
  if (regnum != -1)
    {
      /* Print one specified register.  */
      if (*(gdbarch_register_name (gdbarch, regnum)) == '\0')
	error (_("Not a valid register for the current processor type"));
      riscv_print_one_register_info (gdbarch, file, frame, regnum);
    }
  else
    {
      const struct reggroup *reggroup;

      if (print_all)
	reggroup = all_reggroup;
      else
	reggroup = general_reggroup;

      for (regnum = 0; regnum < gdbarch_num_cooked_regs (gdbarch); ++regnum)
	{
	  /* Zero never changes, so might as well hide by default.  */
	  if (regnum == RISCV_ZERO_REGNUM && !print_all)
	    continue;

	  /* Registers with no name are not valid on this ISA.  */
	  if (*(gdbarch_register_name (gdbarch, regnum)) == '\0')
	    continue;

	  /* Is the register in the group we're interested in?  */
	  if (!gdbarch_register_reggroup_p (gdbarch, regnum, reggroup))
	    continue;

	  riscv_print_one_register_info (gdbarch, file, frame, regnum);
	}
    }
}

/* Class that handles one decoded RiscV instruction.  */

class riscv_insn
{
public:

  /* Enum of all the opcodes that GDB cares about during the prologue scan.  */
  enum opcode
    {
      /* Unknown value is used at initialisation time.  */
      UNKNOWN = 0,

      /* These instructions are all the ones we are interested in during the
	 prologue scan.  */
      ADD,
      ADDI,
      ADDIW,
      ADDW,
      AUIPC,
      LUI,
      SD,
      SW,
      LD,
      LW,
      MV,
      /* These are needed for software breakpoint support.  */
      JAL,
      JALR,
      BEQ,
      BNE,
      BLT,
      BGE,
      BLTU,
      BGEU,
      /* These are needed for stepping over atomic sequences.  */
      LR,
      SC,
      /* This instruction is used to do a syscall.  */
      ECALL,

      /* Other instructions are not interesting during the prologue scan, and
	 are ignored.  */
      OTHER
    };

  riscv_insn ()
    : m_length (0),
      m_opcode (OTHER),
      m_rd (0),
      m_rs1 (0),
      m_rs2 (0)
  {
    /* Nothing.  */
  }

  void decode (struct gdbarch *gdbarch, CORE_ADDR pc);

  /* Get the length of the instruction in bytes.  */
  int length () const
  { return m_length; }

  /* Get the opcode for this instruction.  */
  enum opcode opcode () const
  { return m_opcode; }

  /* Get destination register field for this instruction.  This is only
     valid if the OPCODE implies there is such a field for this
     instruction.  */
  int rd () const
  { return m_rd; }

  /* Get the RS1 register field for this instruction.  This is only valid
     if the OPCODE implies there is such a field for this instruction.  */
  int rs1 () const
  { return m_rs1; }

  /* Get the RS2 register field for this instruction.  This is only valid
     if the OPCODE implies there is such a field for this instruction.  */
  int rs2 () const
  { return m_rs2; }

  /* Get the immediate for this instruction in signed form.  This is only
     valid if the OPCODE implies there is such a field for this
     instruction.  */
  int imm_signed () const
  { return m_imm.s; }

private:

  /* Extract 5 bit register field at OFFSET from instruction OPCODE.  */
  int decode_register_index (unsigned long opcode, int offset)
  {
    return (opcode >> offset) & 0x1F;
  }

  /* Extract 5 bit register field at OFFSET from instruction OPCODE.  */
  int decode_register_index_short (unsigned long opcode, int offset)
  {
    return ((opcode >> offset) & 0x7) + 8;
  }

  /* Helper for DECODE, decode 32-bit R-type instruction.  */
  void decode_r_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rd = decode_register_index (ival, OP_SH_RD);
    m_rs1 = decode_register_index (ival, OP_SH_RS1);
    m_rs2 = decode_register_index (ival, OP_SH_RS2);
  }

  /* Helper for DECODE, decode 16-bit compressed R-type instruction.  */
  void decode_cr_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rd = m_rs1 = decode_register_index (ival, OP_SH_CRS1S);
    m_rs2 = decode_register_index (ival, OP_SH_CRS2);
  }

  /* Helper for DECODE, decode 32-bit I-type instruction.  */
  void decode_i_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rd = decode_register_index (ival, OP_SH_RD);
    m_rs1 = decode_register_index (ival, OP_SH_RS1);
    m_imm.s = EXTRACT_ITYPE_IMM (ival);
  }

  /* Helper for DECODE, decode 16-bit compressed I-type instruction.  */
  void decode_ci_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rd = m_rs1 = decode_register_index (ival, OP_SH_CRS1S);
    m_imm.s = EXTRACT_CITYPE_IMM (ival);
  }

  /* Helper for DECODE, decode 16-bit compressed CL-type instruction.  */
  void decode_cl_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rd = decode_register_index_short (ival, OP_SH_CRS2S);
    m_rs1 = decode_register_index_short (ival, OP_SH_CRS1S);
    m_imm.s = EXTRACT_CLTYPE_IMM (ival);
  }

  /* Helper for DECODE, decode 32-bit S-type instruction.  */
  void decode_s_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rs1 = decode_register_index (ival, OP_SH_RS1);
    m_rs2 = decode_register_index (ival, OP_SH_RS2);
    m_imm.s = EXTRACT_STYPE_IMM (ival);
  }

  /* Helper for DECODE, decode 16-bit CS-type instruction.  The immediate
     encoding is different for each CS format instruction, so extracting
     the immediate is left up to the caller, who should pass the extracted
     immediate value through in IMM.  */
  void decode_cs_type_insn (enum opcode opcode, ULONGEST ival, int imm)
  {
    m_opcode = opcode;
    m_imm.s = imm;
    m_rs1 = decode_register_index_short (ival, OP_SH_CRS1S);
    m_rs2 = decode_register_index_short (ival, OP_SH_CRS2S);
  }

  /* Helper for DECODE, decode 16-bit CSS-type instruction.  The immediate
     encoding is different for each CSS format instruction, so extracting
     the immediate is left up to the caller, who should pass the extracted
     immediate value through in IMM.  */
  void decode_css_type_insn (enum opcode opcode, ULONGEST ival, int imm)
  {
    m_opcode = opcode;
    m_imm.s = imm;
    m_rs1 = RISCV_SP_REGNUM;
    /* Not a compressed register number in this case.  */
    m_rs2 = decode_register_index (ival, OP_SH_CRS2);
  }

  /* Helper for DECODE, decode 32-bit U-type instruction.  */
  void decode_u_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rd = decode_register_index (ival, OP_SH_RD);
    m_imm.s = EXTRACT_UTYPE_IMM (ival);
  }

  /* Helper for DECODE, decode 32-bit J-type instruction.  */
  void decode_j_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rd = decode_register_index (ival, OP_SH_RD);
    m_imm.s = EXTRACT_JTYPE_IMM (ival);
  }

  /* Helper for DECODE, decode 32-bit J-type instruction.  */
  void decode_cj_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_imm.s = EXTRACT_CJTYPE_IMM (ival);
  }

  void decode_b_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rs1 = decode_register_index (ival, OP_SH_RS1);
    m_rs2 = decode_register_index (ival, OP_SH_RS2);
    m_imm.s = EXTRACT_BTYPE_IMM (ival);
  }

  void decode_cb_type_insn (enum opcode opcode, ULONGEST ival)
  {
    m_opcode = opcode;
    m_rs1 = decode_register_index_short (ival, OP_SH_CRS1S);
    m_imm.s = EXTRACT_CBTYPE_IMM (ival);
  }

  /* Fetch instruction from target memory at ADDR, return the content of
     the instruction, and update LEN with the instruction length.  */
  static ULONGEST fetch_instruction (struct gdbarch *gdbarch,
				     CORE_ADDR addr, int *len);

  /* The length of the instruction in bytes.  Should be 2 or 4.  */
  int m_length;

  /* The instruction opcode.  */
  enum opcode m_opcode;

  /* The three possible registers an instruction might reference.  Not
     every instruction fills in all of these registers.  Which fields are
     valid depends on the opcode.  The naming of these fields matches the
     naming in the riscv isa manual.  */
  int m_rd;
  int m_rs1;
  int m_rs2;

  /* Possible instruction immediate.  This is only valid if the instruction
     format contains an immediate, not all instruction, whether this is
     valid depends on the opcode.  Despite only having one format for now
     the immediate is packed into a union, later instructions might require
     an unsigned formatted immediate, having the union in place now will
     reduce the need for code churn later.  */
  union riscv_insn_immediate
  {
    riscv_insn_immediate ()
      : s (0)
    {
      /* Nothing.  */
    }

    int s;
  } m_imm;
};

/* Fetch instruction from target memory at ADDR, return the content of the
   instruction, and update LEN with the instruction length.  */

ULONGEST
riscv_insn::fetch_instruction (struct gdbarch *gdbarch,
			       CORE_ADDR addr, int *len)
{
  enum bfd_endian byte_order = gdbarch_byte_order_for_code (gdbarch);
  gdb_byte buf[RISCV_MAX_INSN_LEN];
  int instlen, status;

  /* All insns are at least 16 bits.  */
  status = target_read_memory (addr, buf, 2);
  if (status)
    memory_error (TARGET_XFER_E_IO, addr);

  /* If we need more, grab it now.  */
  instlen = riscv_insn_length (buf[0]);
  gdb_assert (instlen <= sizeof (buf));
  *len = instlen;

  if (instlen > 2)
    {
      status = target_read_memory (addr + 2, buf + 2, instlen - 2);
      if (status)
	memory_error (TARGET_XFER_E_IO, addr + 2);
    }

  return extract_unsigned_integer (buf, instlen, byte_order);
}

/* Fetch from target memory an instruction at PC and decode it.  This can
   throw an error if the memory access fails, callers are responsible for
   handling this error if that is appropriate.  */

void
riscv_insn::decode (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  ULONGEST ival;

  /* Fetch the instruction, and the instructions length.  */
  ival = fetch_instruction (gdbarch, pc, &m_length);

  if (m_length == 4)
    {
      if (is_add_insn (ival))
	decode_r_type_insn (ADD, ival);
      else if (is_addw_insn (ival))
	decode_r_type_insn (ADDW, ival);
      else if (is_addi_insn (ival))
	decode_i_type_insn (ADDI, ival);
      else if (is_addiw_insn (ival))
	decode_i_type_insn (ADDIW, ival);
      else if (is_auipc_insn (ival))
	decode_u_type_insn (AUIPC, ival);
      else if (is_lui_insn (ival))
	decode_u_type_insn (LUI, ival);
      else if (is_sd_insn (ival))
	decode_s_type_insn (SD, ival);
      else if (is_sw_insn (ival))
	decode_s_type_insn (SW, ival);
      else if (is_jal_insn (ival))
	decode_j_type_insn (JAL, ival);
      else if (is_jalr_insn (ival))
	decode_i_type_insn (JALR, ival);
      else if (is_beq_insn (ival))
	decode_b_type_insn (BEQ, ival);
      else if (is_bne_insn (ival))
	decode_b_type_insn (BNE, ival);
      else if (is_blt_insn (ival))
	decode_b_type_insn (BLT, ival);
      else if (is_bge_insn (ival))
	decode_b_type_insn (BGE, ival);
      else if (is_bltu_insn (ival))
	decode_b_type_insn (BLTU, ival);
      else if (is_bgeu_insn (ival))
	decode_b_type_insn (BGEU, ival);
      else if (is_lr_w_insn (ival))
	decode_r_type_insn (LR, ival);
      else if (is_lr_d_insn (ival))
	decode_r_type_insn (LR, ival);
      else if (is_sc_w_insn (ival))
	decode_r_type_insn (SC, ival);
      else if (is_sc_d_insn (ival))
	decode_r_type_insn (SC, ival);
      else if (is_ecall_insn (ival))
	decode_i_type_insn (ECALL, ival);
      else if (is_ld_insn (ival))
	decode_i_type_insn (LD, ival);
      else if (is_lw_insn (ival))
	decode_i_type_insn (LW, ival);
      else
	/* None of the other fields are valid in this case.  */
	m_opcode = OTHER;
    }
  else if (m_length == 2)
    {
      int xlen = riscv_isa_xlen (gdbarch);

      /* C_ADD and C_JALR have the same opcode.  If RS2 is 0, then this is a
	 C_JALR.  So must try to match C_JALR first as it has more bits in
	 mask.  */
      if (is_c_jalr_insn (ival))
	decode_cr_type_insn (JALR, ival);
      else if (is_c_add_insn (ival))
	decode_cr_type_insn (ADD, ival);
      /* C_ADDW is RV64 and RV128 only.  */
      else if (xlen != 4 && is_c_addw_insn (ival))
	decode_cr_type_insn (ADDW, ival);
      else if (is_c_addi_insn (ival))
	decode_ci_type_insn (ADDI, ival);
      /* C_ADDIW and C_JAL have the same opcode.  C_ADDIW is RV64 and RV128
	 only and C_JAL is RV32 only.  */
      else if (xlen != 4 && is_c_addiw_insn (ival))
	decode_ci_type_insn (ADDIW, ival);
      else if (xlen == 4 && is_c_jal_insn (ival))
	decode_cj_type_insn (JAL, ival);
      /* C_ADDI16SP and C_LUI have the same opcode.  If RD is 2, then this is a
	 C_ADDI16SP.  So must try to match C_ADDI16SP first as it has more bits
	 in mask.  */
      else if (is_c_addi16sp_insn (ival))
	{
	  m_opcode = ADDI;
	  m_rd = m_rs1 = decode_register_index (ival, OP_SH_RD);
	  m_imm.s = EXTRACT_CITYPE_ADDI16SP_IMM (ival);
	}
      else if (is_c_addi4spn_insn (ival))
	{
	  m_opcode = ADDI;
	  m_rd = decode_register_index_short (ival, OP_SH_CRS2S);
	  m_rs1 = RISCV_SP_REGNUM;
	  m_imm.s = EXTRACT_CIWTYPE_ADDI4SPN_IMM (ival);
	}
      else if (is_c_lui_insn (ival))
	{
	  m_opcode = LUI;
	  m_rd = decode_register_index (ival, OP_SH_CRS1S);
	  m_imm.s = EXTRACT_CITYPE_LUI_IMM (ival);
	}
      /* C_SD and C_FSW have the same opcode.  C_SD is RV64 and RV128 only,
	 and C_FSW is RV32 only.  */
      else if (xlen != 4 && is_c_sd_insn (ival))
	decode_cs_type_insn (SD, ival, EXTRACT_CLTYPE_LD_IMM (ival));
      else if (is_c_sw_insn (ival))
	decode_cs_type_insn (SW, ival, EXTRACT_CLTYPE_LW_IMM (ival));
      else if (is_c_swsp_insn (ival))
	decode_css_type_insn (SW, ival, EXTRACT_CSSTYPE_SWSP_IMM (ival));
      else if (xlen != 4 && is_c_sdsp_insn (ival))
	decode_css_type_insn (SD, ival, EXTRACT_CSSTYPE_SDSP_IMM (ival));
      /* C_JR and C_MV have the same opcode.  If RS2 is 0, then this is a C_JR.
	 So must try to match C_JR first as it has more bits in mask.  */
      else if (is_c_jr_insn (ival))
	decode_cr_type_insn (JALR, ival);
      else if (is_c_mv_insn (ival))
	decode_cr_type_insn (MV, ival);
      else if (is_c_j_insn (ival))
	decode_cj_type_insn (JAL, ival);
      else if (is_c_beqz_insn (ival))
	decode_cb_type_insn (BEQ, ival);
      else if (is_c_bnez_insn (ival))
	decode_cb_type_insn (BNE, ival);
      else if (is_c_ld_insn (ival))
	decode_cl_type_insn (LD, ival);
      else if (is_c_lw_insn (ival))
	decode_cl_type_insn (LW, ival);
      else
	/* None of the other fields of INSN are valid in this case.  */
	m_opcode = OTHER;
    }
  else
    {
      /* 6 bytes or more.  If the instruction is longer than 8 bytes, we don't
	 have full instruction bits in ival.  At least, such long instructions
	 are not defined yet, so just ignore it.  */
      gdb_assert (m_length > 0 && m_length % 2 == 0);
      m_opcode = OTHER;
    }
}

/* The prologue scanner.  This is currently only used for skipping the
   prologue of a function when the DWARF information is not sufficient.
   However, it is written with filling of the frame cache in mind, which
   is why different groups of stack setup instructions are split apart
   during the core of the inner loop.  In the future, the intention is to
   extend this function to fully support building up a frame cache that
   can unwind register values when there is no DWARF information.  */

static CORE_ADDR
riscv_scan_prologue (struct gdbarch *gdbarch,
		     CORE_ADDR start_pc, CORE_ADDR end_pc,
		     struct riscv_unwind_cache *cache)
{
  CORE_ADDR cur_pc, next_pc, after_prologue_pc;
  CORE_ADDR end_prologue_addr = 0;

  /* Find an upper limit on the function prologue using the debug
     information.  If the debug information could not be used to provide
     that bound, then use an arbitrary large number as the upper bound.  */
  after_prologue_pc = skip_prologue_using_sal (gdbarch, start_pc);
  if (after_prologue_pc == 0)
    after_prologue_pc = start_pc + 100;   /* Arbitrary large number.  */
  if (after_prologue_pc < end_pc)
    end_pc = after_prologue_pc;

  pv_t regs[RISCV_NUM_INTEGER_REGS]; /* Number of GPR.  */
  for (int regno = 0; regno < RISCV_NUM_INTEGER_REGS; regno++)
    regs[regno] = pv_register (regno, 0);
  pv_area stack (RISCV_SP_REGNUM, gdbarch_addr_bit (gdbarch));

  if (riscv_debug_unwinder)
    gdb_printf
      (gdb_stdlog,
       "Prologue scan for function starting at %s (limit %s)\n",
       core_addr_to_string (start_pc),
       core_addr_to_string (end_pc));

  for (next_pc = cur_pc = start_pc; cur_pc < end_pc; cur_pc = next_pc)
    {
      struct riscv_insn insn;

      /* Decode the current instruction, and decide where the next
	 instruction lives based on the size of this instruction.  */
      insn.decode (gdbarch, cur_pc);
      gdb_assert (insn.length () > 0);
      next_pc = cur_pc + insn.length ();

      /* Look for common stack adjustment insns.  */
      if ((insn.opcode () == riscv_insn::ADDI
	   || insn.opcode () == riscv_insn::ADDIW)
	  && insn.rd () == RISCV_SP_REGNUM
	  && insn.rs1 () == RISCV_SP_REGNUM)
	{
	  /* Handle: addi sp, sp, -i
	     or:     addiw sp, sp, -i  */
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
	  regs[insn.rd ()]
	    = pv_add_constant (regs[insn.rs1 ()], insn.imm_signed ());
	}
      else if ((insn.opcode () == riscv_insn::SW
		|| insn.opcode () == riscv_insn::SD)
	       && (insn.rs1 () == RISCV_SP_REGNUM
		   || insn.rs1 () == RISCV_FP_REGNUM))
	{
	  /* Handle: sw reg, offset(sp)
	     or:     sd reg, offset(sp)
	     or:     sw reg, offset(s0)
	     or:     sd reg, offset(s0)  */
	  /* Instruction storing a register onto the stack.  */
	  gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs2 () < RISCV_NUM_INTEGER_REGS);
	  stack.store (pv_add_constant (regs[insn.rs1 ()], insn.imm_signed ()),
			(insn.opcode () == riscv_insn::SW ? 4 : 8),
			regs[insn.rs2 ()]);
	}
      else if (insn.opcode () == riscv_insn::ADDI
	       && insn.rd () == RISCV_FP_REGNUM
	       && insn.rs1 () == RISCV_SP_REGNUM)
	{
	  /* Handle: addi s0, sp, size  */
	  /* Instructions setting up the frame pointer.  */
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
	  regs[insn.rd ()]
	    = pv_add_constant (regs[insn.rs1 ()], insn.imm_signed ());
	}
      else if ((insn.opcode () == riscv_insn::ADD
		|| insn.opcode () == riscv_insn::ADDW)
	       && insn.rd () == RISCV_FP_REGNUM
	       && insn.rs1 () == RISCV_SP_REGNUM
	       && insn.rs2 () == RISCV_ZERO_REGNUM)
	{
	  /* Handle: add s0, sp, 0
	     or:     addw s0, sp, 0  */
	  /* Instructions setting up the frame pointer.  */
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
	  regs[insn.rd ()] = pv_add_constant (regs[insn.rs1 ()], 0);
	}
      else if ((insn.opcode () == riscv_insn::ADDI
		&& insn.rd () == RISCV_ZERO_REGNUM
		&& insn.rs1 () == RISCV_ZERO_REGNUM
		&& insn.imm_signed () == 0))
	{
	  /* Handle: add x0, x0, 0   (NOP)  */
	}
      else if (insn.opcode () == riscv_insn::AUIPC)
	{
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  regs[insn.rd ()] = pv_constant (cur_pc + insn.imm_signed ());
	}
      else if (insn.opcode () == riscv_insn::LUI)
	{
	  /* Handle: lui REG, n
	     Where REG is not gp register.  */
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  regs[insn.rd ()] = pv_constant (insn.imm_signed ());
	}
      else if (insn.opcode () == riscv_insn::ADDI)
	{
	  /* Handle: addi REG1, REG2, IMM  */
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
	  regs[insn.rd ()]
	    = pv_add_constant (regs[insn.rs1 ()], insn.imm_signed ());
	}
      else if (insn.opcode () == riscv_insn::ADD)
	{
	  /* Handle: add REG1, REG2, REG3  */
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs2 () < RISCV_NUM_INTEGER_REGS);
	  regs[insn.rd ()] = pv_add (regs[insn.rs1 ()], regs[insn.rs2 ()]);
	}
      else if (insn.opcode () == riscv_insn::LD
	       || insn.opcode () == riscv_insn::LW)
	{
	  /* Handle: ld reg, offset(rs1)
	     or:     c.ld reg, offset(rs1)
	     or:     lw reg, offset(rs1)
	     or:     c.lw reg, offset(rs1)  */
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs1 () < RISCV_NUM_INTEGER_REGS);
	  regs[insn.rd ()]
	    = stack.fetch (pv_add_constant (regs[insn.rs1 ()],
					    insn.imm_signed ()),
			   (insn.opcode () == riscv_insn::LW ? 4 : 8));
	}
      else if (insn.opcode () == riscv_insn::MV)
	{
	  /* Handle: c.mv RD, RS2  */
	  gdb_assert (insn.rd () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs2 () < RISCV_NUM_INTEGER_REGS);
	  gdb_assert (insn.rs2 () > 0);
	  regs[insn.rd ()] = regs[insn.rs2 ()];
	}
      else
	{
	  end_prologue_addr = cur_pc;
	  break;
	}
    }

  if (end_prologue_addr == 0)
    end_prologue_addr = cur_pc;

  if (riscv_debug_unwinder)
    gdb_printf (gdb_stdlog, "End of prologue at %s\n",
		core_addr_to_string (end_prologue_addr));

  if (cache != NULL)
    {
      /* Figure out if it is a frame pointer or just a stack pointer.  Also
	 the offset held in the pv_t is from the original register value to
	 the current value, which for a grows down stack means a negative
	 value.  The FRAME_BASE_OFFSET is the negation of this, how to get
	 from the current value to the original value.  */
      if (pv_is_register (regs[RISCV_FP_REGNUM], RISCV_SP_REGNUM))
	{
	  cache->frame_base_reg = RISCV_FP_REGNUM;
	  cache->frame_base_offset = -regs[RISCV_FP_REGNUM].k;
	}
      else
	{
	  cache->frame_base_reg = RISCV_SP_REGNUM;
	  cache->frame_base_offset = -regs[RISCV_SP_REGNUM].k;
	}

      /* Assign offset from old SP to all saved registers.  As we don't
	 have the previous value for the frame base register at this
	 point, we store the offset as the address in the trad_frame, and
	 then convert this to an actual address later.  */
      for (int i = 0; i <= RISCV_NUM_INTEGER_REGS; i++)
	{
	  CORE_ADDR offset;
	  if (stack.find_reg (gdbarch, i, &offset))
	    {
	      if (riscv_debug_unwinder)
		{
		  /* Display OFFSET as a signed value, the offsets are from
		     the frame base address to the registers location on
		     the stack, with a descending stack this means the
		     offsets are always negative.  */
		  gdb_printf (gdb_stdlog,
			      "Register $%s at stack offset %s\n",
			      gdbarch_register_name (gdbarch, i),
			      plongest ((LONGEST) offset));
		}
	      cache->regs[i].set_addr (offset);
	    }
	}
    }

  return end_prologue_addr;
}

/* Implement the riscv_skip_prologue gdbarch method.  */

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

  /* 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 (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 (pc, post_prologue_pc);
    }

  /* Can't determine prologue from the symbol table, need to examine
     instructions.  Pass -1 for the end address to indicate the prologue
     scanner can scan as far as it needs to find the end of the prologue.  */
  return riscv_scan_prologue (gdbarch, pc, ((CORE_ADDR) -1), NULL);
}

/* Implement the gdbarch push dummy code callback.  */

static CORE_ADDR
riscv_push_dummy_code (struct gdbarch *gdbarch, CORE_ADDR sp,
		       CORE_ADDR funaddr, struct value **args, int nargs,
		       struct type *value_type, CORE_ADDR *real_pc,
		       CORE_ADDR *bp_addr, struct regcache *regcache)
{
  /* A nop instruction is 'add x0, x0, 0'.  */
  static const gdb_byte nop_insn[] = { 0x13, 0x00, 0x00, 0x00 };

  /* Allocate space for a breakpoint, and keep the stack correctly
     aligned.  The space allocated here must be at least big enough to
     accommodate the NOP_INSN defined above.  */
  sp -= 16;
  *bp_addr = sp;
  *real_pc = funaddr;

  /* When we insert a breakpoint we select whether to use a compressed
     breakpoint or not based on the existing contents of the memory.

     If the breakpoint is being placed onto the stack as part of setting up
     for an inferior call from GDB, then the existing stack contents may
     randomly appear to be a compressed instruction, causing GDB to insert
     a compressed breakpoint.  If this happens on a target that does not
     support compressed instructions then this could cause problems.

     To prevent this issue we write an uncompressed nop onto the stack at
     the location where the breakpoint will be inserted.  In this way we
     ensure that we always use an uncompressed breakpoint, which should
     work on all targets.

     We call TARGET_WRITE_MEMORY here so that if the write fails we don't
     throw an exception.  Instead we ignore the error and move on.  The
     assumption is that either GDB will error later when actually trying to
     insert a software breakpoint, or GDB will use hardware breakpoints and
     there will be no need to write to memory later.  */
  int status = target_write_memory (*bp_addr, nop_insn, sizeof (nop_insn));

  if (riscv_debug_breakpoints || riscv_debug_infcall)
    gdb_printf (gdb_stdlog,
		"Writing %s-byte nop instruction to %s: %s\n",
		plongest (sizeof (nop_insn)),
		paddress (gdbarch, *bp_addr),
		(status == 0 ? "success" : "failed"));

  return sp;
}

/* Implement the gdbarch type alignment method, overrides the generic
   alignment algorithm for anything that is RISC-V specific.  */

static ULONGEST
riscv_type_align (gdbarch *gdbarch, type *type)
{
  type = check_typedef (type);
  if (type->code () == TYPE_CODE_ARRAY && type->is_vector ())
    return std::min (type->length (), (ULONGEST) BIGGEST_ALIGNMENT);

  /* Anything else will be aligned by the generic code.  */
  return 0;
}

/* Holds information about a single argument either being passed to an
   inferior function, or returned from an inferior function.  This includes
   information about the size, type, etc of the argument, and also
   information about how the argument will be passed (or returned).  */

struct riscv_arg_info
{
  /* Contents of the argument.  */
  const gdb_byte *contents;

  /* Length of argument.  */
  int length;

  /* Alignment required for an argument of this type.  */
  int align;

  /* The type for this argument.  */
  struct type *type;

  /* Each argument can have either 1 or 2 locations assigned to it.  Each
     location describes where part of the argument will be placed.  The
     second location is valid based on the LOC_TYPE and C_LENGTH fields
     of the first location (which is always valid).  */
  struct location
  {
    /* What type of location this is.  */
    enum location_type
      {
       /* Argument passed in a register.  */
       in_reg,

       /* Argument passed as an on stack argument.  */
       on_stack,

       /* Argument passed by reference.  The second location is always
	  valid for a BY_REF argument, and describes where the address
	  of the BY_REF argument should be placed.  */
       by_ref
      } loc_type;

    /* Information that depends on the location type.  */
    union
    {
      /* Which register number to use.  */
      int regno;

      /* The offset into the stack region.  */
      int offset;
    } loc_data;

    /* The length of contents covered by this location.  If this is less
       than the total length of the argument, then the second location
       will be valid, and will describe where the rest of the argument
       will go.  */
    int c_length;

    /* The offset within CONTENTS for this part of the argument.  This can
       be non-zero even for the first part (the first field of a struct can
       have a non-zero offset due to padding).  For the second part of the
       argument, this might be the C_LENGTH value of the first part,
       however, if we are passing a structure in two registers, and there's
       is padding between the first and second field, then this offset
       might be greater than the length of the first argument part.  When
       the second argument location is not holding part of the argument
       value, but is instead holding the address of a reference argument,
       then this offset will be set to 0.  */
    int c_offset;
  } argloc[2];

  /* TRUE if this is an unnamed argument.  */
  bool is_unnamed;
};

/* Information about a set of registers being used for passing arguments as
   part of a function call.  The register set must be numerically
   sequential from NEXT_REGNUM to LAST_REGNUM.  The register set can be
   disabled from use by setting NEXT_REGNUM greater than LAST_REGNUM.  */

struct riscv_arg_reg
{
  riscv_arg_reg (int first, int last)
    : next_regnum (first),
      last_regnum (last)
  {
    /* Nothing.  */
  }

  /* The GDB register number to use in this set.  */
  int next_regnum;

  /* The last GDB register number to use in this set.  */
  int last_regnum;
};

/* Arguments can be passed as on stack arguments, or by reference.  The
   on stack arguments must be in a continuous region starting from $sp,
   while the by reference arguments can be anywhere, but we'll put them
   on the stack after (at higher address) the on stack arguments.

   This might not be the right approach to take.  The ABI is clear that
   an argument passed by reference can be modified by the callee, which
   us placing the argument (temporarily) onto the stack will not achieve
   (changes will be lost).  There's also the possibility that very large
   arguments could overflow the stack.

   This struct is used to track offset into these two areas for where
   arguments are to be placed.  */
struct riscv_memory_offsets
{
  riscv_memory_offsets ()
    : arg_offset (0),
      ref_offset (0)
  {
    /* Nothing.  */
  }

  /* Offset into on stack argument area.  */
  int arg_offset;

  /* Offset into the pass by reference area.  */
  int ref_offset;
};

/* Holds information about where arguments to a call will be placed.  This
   is updated as arguments are added onto the call, and can be used to
   figure out where the next argument should be placed.  */

struct riscv_call_info
{
  riscv_call_info (struct gdbarch *gdbarch)
    : int_regs (RISCV_A0_REGNUM, RISCV_A0_REGNUM + 7),
      float_regs (RISCV_FA0_REGNUM, RISCV_FA0_REGNUM + 7)
  {
    xlen = riscv_abi_xlen (gdbarch);
    flen = riscv_abi_flen (gdbarch);

    /* Reduce the number of integer argument registers when using the
       embedded abi (i.e. rv32e).  */
    if (riscv_abi_embedded (gdbarch))
      int_regs.last_regnum = RISCV_A0_REGNUM + 5;

    /* Disable use of floating point registers if needed.  */
    if (!riscv_has_fp_abi (gdbarch))
      float_regs.next_regnum = float_regs.last_regnum + 1;
  }

  /* Track the memory areas used for holding in-memory arguments to a
     call.  */
  struct riscv_memory_offsets memory;

  /* Holds information about the next integer register to use for passing
     an argument.  */
  struct riscv_arg_reg int_regs;

  /* Holds information about the next floating point register to use for
     passing an argument.  */
  struct riscv_arg_reg float_regs;

  /* The XLEN and FLEN are copied in to this structure for convenience, and
     are just the results of calling RISCV_ABI_XLEN and RISCV_ABI_FLEN.  */
  int xlen;
  int flen;
};

/* Return the number of registers available for use as parameters in the
   register set REG.  Returned value can be 0 or more.  */

static int
riscv_arg_regs_available (struct riscv_arg_reg *reg)
{
  if (reg->next_regnum > reg->last_regnum)
    return 0;

  return (reg->last_regnum - reg->next_regnum + 1);
}

/* If there is at least one register available in the register set REG then
   the next register from REG is assigned to LOC and the length field of
   LOC is updated to LENGTH.  The register set REG is updated to indicate
   that the assigned register is no longer available and the function
   returns true.

   If there are no registers available in REG then the function returns
   false, and LOC and REG are unchanged.  */

static bool
riscv_assign_reg_location (struct riscv_arg_info::location *loc,
			   struct riscv_arg_reg *reg,
			   int length, int offset)
{
  if (reg->next_regnum <= reg->last_regnum)
    {
      loc->loc_type = riscv_arg_info::location::in_reg;
      loc->loc_data.regno = reg->next_regnum;
      reg->next_regnum++;
      loc->c_length = length;
      loc->c_offset = offset;
      return true;
    }

  return false;
}

/* Assign LOC a location as the next stack parameter, and update MEMORY to
   record that an area of stack has been used to hold the parameter
   described by LOC.

   The length field of LOC is updated to LENGTH, the length of the
   parameter being stored, and ALIGN is the alignment required by the
   parameter, which will affect how memory is allocated out of MEMORY.  */

static void
riscv_assign_stack_location (struct riscv_arg_info::location *loc,
			     struct riscv_memory_offsets *memory,
			     int length, int align)
{
  loc->loc_type = riscv_arg_info::location::on_stack;
  memory->arg_offset
    = align_up (memory->arg_offset, align);
  loc->loc_data.offset = memory->arg_offset;
  memory->arg_offset += length;
  loc->c_length = length;

  /* Offset is always 0, either we're the first location part, in which
     case we're reading content from the start of the argument, or we're
     passing the address of a reference argument, so 0.  */
  loc->c_offset = 0;
}

/* Update AINFO, which describes an argument that should be passed or
   returned using the integer ABI.  The argloc fields within AINFO are
   updated to describe the location in which the argument will be passed to
   a function, or returned from a function.

   The CINFO structure contains the ongoing call information, the holds
   information such as which argument registers are remaining to be
   assigned to parameter, and how much memory has been used by parameters
   so far.

   By examining the state of CINFO a suitable location can be selected,
   and assigned to AINFO.  */

static void
riscv_call_arg_scalar_int (struct riscv_arg_info *ainfo,
			   struct riscv_call_info *cinfo)
{
  if (ainfo->length > (2 * cinfo->xlen))
    {
      /* Argument is going to be passed by reference.  */
      ainfo->argloc[0].loc_type
	= riscv_arg_info::location::by_ref;
      cinfo->memory.ref_offset
	= align_up (cinfo->memory.ref_offset, ainfo->align);
      ainfo->argloc[0].loc_data.offset = cinfo->memory.ref_offset;
      cinfo->memory.ref_offset += ainfo->length;
      ainfo->argloc[0].c_length = ainfo->length;

      /* The second location for this argument is given over to holding the
	 address of the by-reference data.  Pass 0 for the offset as this
	 is not part of the actual argument value.  */
      if (!riscv_assign_reg_location (&ainfo->argloc[1],
				      &cinfo->int_regs,
				      cinfo->xlen, 0))
	riscv_assign_stack_location (&ainfo->argloc[1],
				     &cinfo->memory, cinfo->xlen,
				     cinfo->xlen);
    }
  else
    {
      int len = std::min (ainfo->length, cinfo->xlen);
      int align = std::max (ainfo->align, cinfo->xlen);

      /* Unnamed arguments in registers that require 2*XLEN alignment are
	 passed in an aligned register pair.  */
      if (ainfo->is_unnamed && (align == cinfo->xlen * 2)
	  && cinfo->int_regs.next_regnum & 1)
	cinfo->int_regs.next_regnum++;

      if (!riscv_assign_reg_location (&ainfo->argloc[0],
				      &cinfo->int_regs, len, 0))
	riscv_assign_stack_location (&ainfo->argloc[0],
				     &cinfo->memory, len, align);

      if (len < ainfo->length)
	{
	  len = ainfo->length - len;
	  if (!riscv_assign_reg_location (&ainfo->argloc[1],
					  &cinfo->int_regs, len,
					  cinfo->xlen))
	    riscv_assign_stack_location (&ainfo->argloc[1],
					 &cinfo->memory, len, cinfo->xlen);
	}
    }
}

/* Like RISCV_CALL_ARG_SCALAR_INT, except the argument described by AINFO
   is being passed with the floating point ABI.  */

static void
riscv_call_arg_scalar_float (struct riscv_arg_info *ainfo,
			     struct riscv_call_info *cinfo)
{
  if (ainfo->length > cinfo->flen || ainfo->is_unnamed)
    return riscv_call_arg_scalar_int (ainfo, cinfo);
  else
    {
      if (!riscv_assign_reg_location (&ainfo->argloc[0],
				      &cinfo->float_regs,
				      ainfo->length, 0))
	return riscv_call_arg_scalar_int (ainfo, cinfo);
    }
}

/* Like RISCV_CALL_ARG_SCALAR_INT, except the argument described by AINFO
   is a complex floating point argument, and is therefore handled
   differently to other argument types.  */

static void
riscv_call_arg_complex_float (struct riscv_arg_info *ainfo,
			      struct riscv_call_info *cinfo)
{
  if (ainfo->length <= (2 * cinfo->flen)
      && riscv_arg_regs_available (&cinfo->float_regs) >= 2
      && !ainfo->is_unnamed)
    {
      bool result;
      int len = ainfo->length / 2;

      result = riscv_assign_reg_location (&ainfo->argloc[0],
					  &cinfo->float_regs, len, 0);
      gdb_assert (result);

      result = riscv_assign_reg_location (&ainfo->argloc[1],
					  &cinfo->float_regs, len, len);
      gdb_assert (result);
    }
  else
    return riscv_call_arg_scalar_int (ainfo, cinfo);
}

/* A structure used for holding information about a structure type within
   the inferior program.  The RiscV ABI has special rules for handling some
   structures with a single field or with two fields.  The counting of
   fields here is done after flattening out all nested structures.  */

class riscv_struct_info
{
public:
  riscv_struct_info ()
    : m_number_of_fields (0),
      m_types { nullptr, nullptr },
      m_offsets { 0, 0 }
  {
    /* Nothing.  */
  }

  /* Analyse TYPE descending into nested structures, count the number of
     scalar fields and record the types of the first two fields found.  */
  void analyse (struct type *type)
  {
    analyse_inner (type, 0);
  }

  /* The number of scalar fields found in the analysed type.  This is
     currently only accurate if the value returned is 0, 1, or 2 as the
     analysis stops counting when the number of fields is 3.  This is
     because the RiscV ABI only has special cases for 1 or 2 fields,
     anything else we just don't care about.  */
  int number_of_fields () const
  { return m_number_of_fields; }

  /* Return the type for scalar field INDEX within the analysed type.  Will
     return nullptr if there is no field at that index.  Only INDEX values
     0 and 1 can be requested as the RiscV ABI only has special cases for
     structures with 1 or 2 fields.  */
  struct type *field_type (int index) const
  {
    gdb_assert (index < (sizeof (m_types) / sizeof (m_types[0])));
    return m_types[index];
  }

  /* Return the offset of scalar field INDEX within the analysed type. Will
     return 0 if there is no field at that index.  Only INDEX values 0 and
     1 can be requested as the RiscV ABI only has special cases for
     structures with 1 or 2 fields.  */
  int field_offset (int index) const
  {
    gdb_assert (index < (sizeof (m_offsets) / sizeof (m_offsets[0])));
    return m_offsets[index];
  }

private:
  /* The number of scalar fields found within the structure after recursing
     into nested structures.  */
  int m_number_of_fields;

  /* The types of the first two scalar fields found within the structure
     after recursing into nested structures.  */
  struct type *m_types[2];

  /* The offsets of the first two scalar fields found within the structure
     after recursing into nested structures.  */
  int m_offsets[2];

  /* Recursive core for ANALYSE, the OFFSET parameter tracks the byte
     offset from the start of the top level structure being analysed.  */
  void analyse_inner (struct type *type, int offset);
};

/* See description in class declaration.  */

void
riscv_struct_info::analyse_inner (struct type *type, int offset)
{
  unsigned int count = type->num_fields ();
  unsigned int i;

  for (i = 0; i < count; ++i)
    {
      if (type->field (i).loc_kind () != FIELD_LOC_KIND_BITPOS)
	continue;

      struct type *field_type = type->field (i).type ();
      field_type = check_typedef (field_type);
      int field_offset
	= offset + type->field (i).loc_bitpos () / TARGET_CHAR_BIT;

      switch (field_type->code ())
	{
	case TYPE_CODE_STRUCT:
	  analyse_inner (field_type, field_offset);
	  break;

	default:
	  /* RiscV only flattens out structures.  Anything else does not
	     need to be flattened, we just record the type, and when we
	     look at the analysis results we'll realise this is not a
	     structure we can special case, and pass the structure in
	     memory.  */
	  if (m_number_of_fields < 2)
	    {
	      m_types[m_number_of_fields] = field_type;
	      m_offsets[m_number_of_fields] = field_offset;
	    }
	  m_number_of_fields++;
	  break;
	}

      /* RiscV only has special handling for structures with 1 or 2 scalar
	 fields, any more than that and the structure is just passed in
	 memory.  We can safely drop out early when we find 3 or more
	 fields then.  */

      if (m_number_of_fields > 2)
	return;
    }
}

/* Like RISCV_CALL_ARG_SCALAR_INT, except the argument described by AINFO
   is a structure.  Small structures on RiscV have some special case
   handling in order that the structure might be passed in register.
   Larger structures are passed in memory.  After assigning location
   information to AINFO, CINFO will have been updated.  */

static void
riscv_call_arg_struct (struct riscv_arg_info *ainfo,
		       struct riscv_call_info *cinfo)
{
  if (riscv_arg_regs_available (&cinfo->float_regs) >= 1)
    {
      struct riscv_struct_info sinfo;

      sinfo.analyse (ainfo->type);
      if (sinfo.number_of_fields () == 1
	  && sinfo.field_type(0)->code () == TYPE_CODE_COMPLEX)
	{
	  /* The following is similar to RISCV_CALL_ARG_COMPLEX_FLOAT,
	     except we use the type of the complex field instead of the
	     type from AINFO, and the first location might be at a non-zero
	     offset.  */
	  if (sinfo.field_type (0)->length () <= (2 * cinfo->flen)
	      && riscv_arg_regs_available (&cinfo->float_regs) >= 2
	      && !ainfo->is_unnamed)
	    {
	      bool result;
	      int len = sinfo.field_type (0)->length () / 2;
	      int offset = sinfo.field_offset (0);

	      result = riscv_assign_reg_location (&ainfo->argloc[0],
						  &cinfo->float_regs, len,
						  offset);
	      gdb_assert (result);

	      result = riscv_assign_reg_location (&ainfo->argloc[1],
						  &cinfo->float_regs, len,
						  (offset + len));
	      gdb_assert (result);
	    }
	  else
	    riscv_call_arg_scalar_int (ainfo, cinfo);
	  return;
	}

      if (sinfo.number_of_fields () == 1
	  && sinfo.field_type(0)->code () == TYPE_CODE_FLT)
	{
	  /* The following is similar to RISCV_CALL_ARG_SCALAR_FLOAT,
	     except we use the type of the first scalar field instead of
	     the type from AINFO.  Also the location might be at a non-zero
	     offset.  */
	  if (sinfo.field_type (0)->length () > cinfo->flen
	      || ainfo->is_unnamed)
	    riscv_call_arg_scalar_int (ainfo, cinfo);
	  else
	    {
	      int offset = sinfo.field_offset (0);
	      int len = sinfo.field_type (0)->length ();

	      if (!riscv_assign_reg_location (&ainfo->argloc[0],
					      &cinfo->float_regs,
					      len, offset))
		riscv_call_arg_scalar_int (ainfo, cinfo);
	    }
	  return;
	}

      if (sinfo.number_of_fields () == 2
	  && sinfo.field_type(0)->code () == TYPE_CODE_FLT
	  && sinfo.field_type (0)->length () <= cinfo->flen
	  && sinfo.field_type(1)->code () == TYPE_CODE_FLT
	  && sinfo.field_type (1)->length () <= cinfo->flen
	  && riscv_arg_regs_available (&cinfo->float_regs) >= 2)
	{
	  int len0 = sinfo.field_type (0)->length ();
	  int offset = sinfo.field_offset (0);
	  if (!riscv_assign_reg_location (&ainfo->argloc[0],
					  &cinfo->float_regs, len0, offset))
	    error (_("failed during argument setup"));

	  int len1 = sinfo.field_type (1)->length ();
	  offset = sinfo.field_offset (1);
	  gdb_assert (len1 <= (ainfo->type->length ()
			       - sinfo.field_type (0)->length ()));

	  if (!riscv_assign_reg_location (&ainfo->argloc[1],
					  &cinfo->float_regs,
					  len1, offset))
	    error (_("failed during argument setup"));
	  return;
	}

      if (sinfo.number_of_fields () == 2
	  && riscv_arg_regs_available (&cinfo->int_regs) >= 1
	  && (sinfo.field_type(0)->code () == TYPE_CODE_FLT
	      && sinfo.field_type (0)->length () <= cinfo->flen
	      && is_integral_type (sinfo.field_type (1))
	      && sinfo.field_type (1)->length () <= cinfo->xlen))
	{
	  int  len0 = sinfo.field_type (0)->length ();
	  int offset = sinfo.field_offset (0);
	  if (!riscv_assign_reg_location (&ainfo->argloc[0],
					  &cinfo->float_regs, len0, offset))
	    error (_("failed during argument setup"));

	  int len1 = sinfo.field_type (1)->length ();
	  offset = sinfo.field_offset (1);
	  gdb_assert (len1 <= cinfo->xlen);
	  if (!riscv_assign_reg_location (&ainfo->argloc[1],
					  &cinfo->int_regs, len1, offset))
	    error (_("failed during argument setup"));
	  return;
	}

      if (sinfo.number_of_fields () == 2
	  && riscv_arg_regs_available (&cinfo->int_regs) >= 1
	  && (is_integral_type (sinfo.field_type (0))
	      && sinfo.field_type (0)->length () <= cinfo->xlen
	      && sinfo.field_type(1)->code () == TYPE_CODE_FLT
	      && sinfo.field_type (1)->length () <= cinfo->flen))
	{
	  int len0 = sinfo.field_type (0)->length ();
	  int len1 = sinfo.field_type (1)->length ();

	  gdb_assert (len0 <= cinfo->xlen);
	  gdb_assert (len1 <= cinfo->flen);

	  int offset = sinfo.field_offset (0);
	  if (!riscv_assign_reg_location (&ainfo->argloc[0],
					  &cinfo->int_regs, len0, offset))
	    error (_("failed during argument setup"));

	  offset = sinfo.field_offset (1);
	  if (!riscv_assign_reg_location (&ainfo->argloc[1],
					  &cinfo->float_regs,
					  len1, offset))
	    error (_("failed during argument setup"));

	  return;
	}
    }

  /* Non of the structure flattening cases apply, so we just pass using
     the integer ABI.  */
  riscv_call_arg_scalar_int (ainfo, cinfo);
}

/* Assign a location to call (or return) argument AINFO, the location is
   selected from CINFO which holds information about what call argument
   locations are available for use next.  The TYPE is the type of the
   argument being passed, this information is recorded into AINFO (along
   with some additional information derived from the type).  IS_UNNAMED
   is true if this is an unnamed (stdarg) argument, this info is also
   recorded into AINFO.

   After assigning a location to AINFO, CINFO will have been updated.  */

static void
riscv_arg_location (struct gdbarch *gdbarch,
		    struct riscv_arg_info *ainfo,
		    struct riscv_call_info *cinfo,
		    struct type *type, bool is_unnamed)
{
  ainfo->type = type;
  ainfo->length = ainfo->type->length ();
  ainfo->align = type_align (ainfo->type);
  ainfo->is_unnamed = is_unnamed;
  ainfo->contents = nullptr;
  ainfo->argloc[0].c_length = 0;
  ainfo->argloc[1].c_length = 0;

  switch (ainfo->type->code ())
    {
    case TYPE_CODE_INT:
    case TYPE_CODE_BOOL:
    case TYPE_CODE_CHAR:
    case TYPE_CODE_RANGE:
    case TYPE_CODE_ENUM:
    case TYPE_CODE_PTR:
    case TYPE_CODE_FIXED_POINT:
      if (ainfo->length <= cinfo->xlen)
	{
	  ainfo->type = builtin_type (gdbarch)->builtin_long;
	  ainfo->length = cinfo->xlen;
	}
      else if (ainfo->length <= (2 * cinfo->xlen))
	{
	  ainfo->type = builtin_type (gdbarch)->builtin_long_long;
	  ainfo->length = 2 * cinfo->xlen;
	}

      /* Recalculate the alignment requirement.  */
      ainfo->align = type_align (ainfo->type);
      riscv_call_arg_scalar_int (ainfo, cinfo);
      break;

    case TYPE_CODE_FLT:
      riscv_call_arg_scalar_float (ainfo, cinfo);
      break;

    case TYPE_CODE_COMPLEX:
      riscv_call_arg_complex_float (ainfo, cinfo);
      break;

    case TYPE_CODE_STRUCT:
      riscv_call_arg_struct (ainfo, cinfo);
      break;

    default:
      riscv_call_arg_scalar_int (ainfo, cinfo);
      break;
    }
}

/* Used for printing debug information about the call argument location in
   INFO to STREAM.  The addresses in SP_REFS and SP_ARGS are the base
   addresses for the location of pass-by-reference and
   arguments-on-the-stack memory areas.  */

static void
riscv_print_arg_location (ui_file *stream, struct gdbarch *gdbarch,
			  struct riscv_arg_info *info,
			  CORE_ADDR sp_refs, CORE_ADDR sp_args)
{
  gdb_printf (stream, "type: '%s', length: 0x%x, alignment: 0x%x",
	      TYPE_SAFE_NAME (info->type), info->length, info->align);
  switch (info->argloc[0].loc_type)
    {
    case riscv_arg_info::location::in_reg:
      gdb_printf
	(stream, ", register %s",
	 gdbarch_register_name (gdbarch, info->argloc[0].loc_data.regno));
      if (info->argloc[0].c_length < info->length)
	{
	  switch (info->argloc[1].loc_type)
	    {
	    case riscv_arg_info::location::in_reg:
	      gdb_printf
		(stream, ", register %s",
		 gdbarch_register_name (gdbarch,
					info->argloc[1].loc_data.regno));
	      break;

	    case riscv_arg_info::location::on_stack:
	      gdb_printf (stream, ", on stack at offset 0x%x",
			  info->argloc[1].loc_data.offset);
	      break;

	    case riscv_arg_info::location::by_ref:
	    default:
	      /* The second location should never be a reference, any
		 argument being passed by reference just places its address
		 in the first location and is done.  */
	      error (_("invalid argument location"));
	      break;
	    }

	  if (info->argloc[1].c_offset > info->argloc[0].c_length)
	    gdb_printf (stream, " (offset 0x%x)",
			info->argloc[1].c_offset);
	}
      break;

    case riscv_arg_info::location::on_stack:
      gdb_printf (stream, ", on stack at offset 0x%x",
		  info->argloc[0].loc_data.offset);
      break;

    case riscv_arg_info::location::by_ref:
      gdb_printf
	(stream, ", by reference, data at offset 0x%x (%s)",
	 info->argloc[0].loc_data.offset,
	 core_addr_to_string (sp_refs + info->argloc[0].loc_data.offset));
      if (info->argloc[1].loc_type
	  == riscv_arg_info::location::in_reg)
	gdb_printf
	  (stream, ", address in register %s",
	   gdbarch_register_name (gdbarch, info->argloc[1].loc_data.regno));
      else
	{
	  gdb_assert (info->argloc[1].loc_type
		      == riscv_arg_info::location::on_stack);
	  gdb_printf
	    (stream, ", address on stack at offset 0x%x (%s)",
	     info->argloc[1].loc_data.offset,
	     core_addr_to_string (sp_args + info->argloc[1].loc_data.offset));
	}
      break;

    default:
      gdb_assert_not_reached ("unknown argument location type");
    }
}

/* Wrapper around REGCACHE->cooked_write.  Places the LEN bytes of DATA
   into a buffer that is at least as big as the register REGNUM, padding
   out the DATA with either 0x00, or 0xff.  For floating point registers
   0xff is used, for everyone else 0x00 is used.  */

static void
riscv_regcache_cooked_write (int regnum, const gdb_byte *data, int len,
			     struct regcache *regcache, int flen)
{
  gdb_byte tmp [sizeof (ULONGEST)];

  /* FP values in FP registers must be NaN-boxed.  */
  if (riscv_is_fp_regno_p (regnum) && len < flen)
    memset (tmp, -1, sizeof (tmp));
  else
    memset (tmp, 0, sizeof (tmp));
  memcpy (tmp, data, len);
  regcache->cooked_write (regnum, tmp);
}

/* Implement the push dummy call gdbarch callback.  */

static CORE_ADDR
riscv_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 i;
  CORE_ADDR sp_args, sp_refs;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);

  struct riscv_arg_info *arg_info =
    (struct riscv_arg_info *) alloca (nargs * sizeof (struct riscv_arg_info));

  struct riscv_call_info call_info (gdbarch);

  CORE_ADDR osp = sp;

  struct type *ftype = check_typedef (value_type (function));

  if (ftype->code () == TYPE_CODE_PTR)
    ftype = check_typedef (ftype->target_type ());

  /* We'll use register $a0 if we're returning a struct.  */
  if (return_method == return_method_struct)
    ++call_info.int_regs.next_regnum;

  for (i = 0; i < nargs; ++i)
    {
      struct value *arg_value;
      struct type *arg_type;
      struct riscv_arg_info *info = &arg_info[i];

      arg_value = args[i];
      arg_type = check_typedef (value_type (arg_value));

      riscv_arg_location (gdbarch, info, &call_info, arg_type,
			  ftype->has_varargs () && i >= ftype->num_fields ());

      if (info->type != arg_type)
	arg_value = value_cast (info->type, arg_value);
      info->contents = value_contents (arg_value).data ();
    }

  /* Adjust the stack pointer and align it.  */
  sp = sp_refs = align_down (sp - call_info.memory.ref_offset, SP_ALIGNMENT);
  sp = sp_args = align_down (sp - call_info.memory.arg_offset, SP_ALIGNMENT);

  if (riscv_debug_infcall > 0)
    {
      gdb_printf (gdb_stdlog, "dummy call args:\n");
      gdb_printf (gdb_stdlog, ": floating point ABI %s in use\n",
		  (riscv_has_fp_abi (gdbarch) ? "is" : "is not"));
      gdb_printf (gdb_stdlog, ": xlen: %d\n: flen: %d\n",
		  call_info.xlen, call_info.flen);
      if (return_method == return_method_struct)
	gdb_printf (gdb_stdlog,
		    "[*] struct return pointer in register $A0\n");
      for (i = 0; i < nargs; ++i)
	{
	  struct riscv_arg_info *info = &arg_info [i];

	  gdb_printf (gdb_stdlog, "[%2d] ", i);
	  riscv_print_arg_location (gdb_stdlog, gdbarch, info, sp_refs, sp_args);
	  gdb_printf (gdb_stdlog, "\n");
	}
      if (call_info.memory.arg_offset > 0
	  || call_info.memory.ref_offset > 0)
	{
	  gdb_printf (gdb_stdlog, "              Original sp: %s\n",
		      core_addr_to_string (osp));
	  gdb_printf (gdb_stdlog, "Stack required (for args): 0x%x\n",
		      call_info.memory.arg_offset);
	  gdb_printf (gdb_stdlog, "Stack required (for refs): 0x%x\n",
		      call_info.memory.ref_offset);
	  gdb_printf (gdb_stdlog, "          Stack allocated: %s\n",
		      core_addr_to_string_nz (osp - sp));
	}
    }

  /* Now load the argument into registers, or onto the stack.  */

  if (return_method == return_method_struct)
    {
      gdb_byte buf[sizeof (LONGEST)];

      store_unsigned_integer (buf, call_info.xlen, byte_order, struct_addr);
      regcache->cooked_write (RISCV_A0_REGNUM, buf);
    }

  for (i = 0; i < nargs; ++i)
    {
      CORE_ADDR dst;
      int second_arg_length = 0;
      const gdb_byte *second_arg_data;
      struct riscv_arg_info *info = &arg_info [i];

      gdb_assert (info->length > 0);

      switch (info->argloc[0].loc_type)
	{
	case riscv_arg_info::location::in_reg:
	  {
	    gdb_assert (info->argloc[0].c_length <= info->length);

	    riscv_regcache_cooked_write (info->argloc[0].loc_data.regno,
					 (info->contents
					  + info->argloc[0].c_offset),
					 info->argloc[0].c_length,
					 regcache, call_info.flen);
	    second_arg_length =
	      (((info->argloc[0].c_length + info->argloc[0].c_offset) < info->length)
	       ? info->argloc[1].c_length : 0);
	    second_arg_data = info->contents + info->argloc[1].c_offset;
	  }
	  break;

	case riscv_arg_info::location::on_stack:
	  dst = sp_args + info->argloc[0].loc_data.offset;
	  write_memory (dst, info->contents, info->length);
	  second_arg_length = 0;
	  break;

	case riscv_arg_info::location::by_ref:
	  dst = sp_refs + info->argloc[0].loc_data.offset;
	  write_memory (dst, info->contents, info->length);

	  second_arg_length = call_info.xlen;
	  second_arg_data = (gdb_byte *) &dst;
	  break;

	default:
	  gdb_assert_not_reached ("unknown argument location type");
	}

      if (second_arg_length > 0)
	{
	  switch (info->argloc[1].loc_type)
	    {
	    case riscv_arg_info::location::in_reg:
	      {
		gdb_assert ((riscv_is_fp_regno_p (info->argloc[1].loc_data.regno)
			     && second_arg_length <= call_info.flen)
			    || second_arg_length <= call_info.xlen);
		riscv_regcache_cooked_write (info->argloc[1].loc_data.regno,
					     second_arg_data,
					     second_arg_length,
					     regcache, call_info.flen);
	      }
	      break;

	    case riscv_arg_info::location::on_stack:
	      {
		CORE_ADDR arg_addr;

		arg_addr = sp_args + info->argloc[1].loc_data.offset;
		write_memory (arg_addr, second_arg_data, second_arg_length);
		break;
	      }

	    case riscv_arg_info::location::by_ref:
	    default:
	      /* The second location should never be a reference, any
		 argument being passed by reference just places its address
		 in the first location and is done.  */
	      error (_("invalid argument location"));
	      break;
	    }
	}
    }

  /* Set the dummy return value to bp_addr.
     A dummy breakpoint will be setup to execute the call.  */

  if (riscv_debug_infcall > 0)
    gdb_printf (gdb_stdlog, ": writing $ra = %s\n",
		core_addr_to_string (bp_addr));
  regcache_cooked_write_unsigned (regcache, RISCV_RA_REGNUM, bp_addr);

  /* Finally, update the stack pointer.  */

  if (riscv_debug_infcall > 0)
    gdb_printf (gdb_stdlog, ": writing $sp = %s\n",
		core_addr_to_string (sp));
  regcache_cooked_write_unsigned (regcache, RISCV_SP_REGNUM, sp);

  return sp;
}

/* Implement the return_value gdbarch method.  */

static enum return_value_convention
riscv_return_value (struct gdbarch  *gdbarch,
		    struct value *function,
		    struct type *type,
		    struct regcache *regcache,
		    struct value **read_value,
		    const gdb_byte *writebuf)
{
  struct riscv_call_info call_info (gdbarch);
  struct riscv_arg_info info;
  struct type *arg_type;

  gdb_byte *readbuf = nullptr;
  if (read_value != nullptr)
    {
      *read_value = allocate_value (type);
      readbuf = value_contents_raw (*read_value).data ();
    }

  arg_type = check_typedef (type);
  riscv_arg_location (gdbarch, &info, &call_info, arg_type, false);

  if (riscv_debug_infcall > 0)
    {
      gdb_printf (gdb_stdlog, "riscv return value:\n");
      gdb_printf (gdb_stdlog, "[R] ");
      riscv_print_arg_location (gdb_stdlog, gdbarch, &info, 0, 0);
      gdb_printf (gdb_stdlog, "\n");
    }

  if (readbuf != nullptr || writebuf != nullptr)
    {
      unsigned int arg_len;
      struct value *abi_val;
      gdb_byte *old_readbuf = nullptr;
      int regnum;

      /* We only do one thing at a time.  */
      gdb_assert (readbuf == nullptr || writebuf == nullptr);

      /* In some cases the argument is not returned as the declared type,
	 and we need to cast to or from the ABI type in order to
	 correctly access the argument.  When writing to the machine we
	 do the cast here, when reading from the machine the cast occurs
	 later, after extracting the value.  As the ABI type can be
	 larger than the declared type, then the read or write buffers
	 passed in might be too small.  Here we ensure that we are using
	 buffers of sufficient size.  */
      if (writebuf != nullptr)
	{
	  struct value *arg_val;

	  if (is_fixed_point_type (arg_type))
	    {
	      /* Convert the argument to the type used to pass
		 the return value, but being careful to preserve
		 the fact that the value needs to be returned
		 unscaled.  */
	      gdb_mpz unscaled;

	      unscaled.read (gdb::make_array_view (writebuf,
						   arg_type->length ()),
			     type_byte_order (arg_type),
			     arg_type->is_unsigned ());
	      abi_val = allocate_value (info.type);
	      unscaled.write (value_contents_raw (abi_val),
			      type_byte_order (info.type),
			      info.type->is_unsigned ());
	    }
	  else
	    {
	      arg_val = value_from_contents (arg_type, writebuf);
	      abi_val = value_cast (info.type, arg_val);
	    }
	  writebuf = value_contents_raw (abi_val).data ();
	}
      else
	{
	  abi_val = allocate_value (info.type);
	  old_readbuf = readbuf;
	  readbuf = value_contents_raw (abi_val).data ();
	}
      arg_len = info.type->length ();

      switch (info.argloc[0].loc_type)
	{
	  /* Return value in register(s).  */
	case riscv_arg_info::location::in_reg:
	  {
	    regnum = info.argloc[0].loc_data.regno;
	    gdb_assert (info.argloc[0].c_length <= arg_len);
	    gdb_assert (info.argloc[0].c_length
			<= register_size (gdbarch, regnum));

	    if (readbuf)
	      {
		gdb_byte *ptr = readbuf + info.argloc[0].c_offset;
		regcache->cooked_read_part (regnum, 0,
					    info.argloc[0].c_length,
					    ptr);
	      }

	    if (writebuf)
	      {
		const gdb_byte *ptr = writebuf + info.argloc[0].c_offset;
		riscv_regcache_cooked_write (regnum, ptr,
					     info.argloc[0].c_length,
					     regcache, call_info.flen);
	      }

	    /* A return value in register can have a second part in a
	       second register.  */
	    if (info.argloc[1].c_length > 0)
	      {
		switch (info.argloc[1].loc_type)
		  {
		  case riscv_arg_info::location::in_reg:
		    regnum = info.argloc[1].loc_data.regno;

		    gdb_assert ((info.argloc[0].c_length
				 + info.argloc[1].c_length) <= arg_len);
		    gdb_assert (info.argloc[1].c_length
				<= register_size (gdbarch, regnum));

		    if (readbuf)
		      {
			readbuf += info.argloc[1].c_offset;
			regcache->cooked_read_part (regnum, 0,
						    info.argloc[1].c_length,
						    readbuf);
		      }

		    if (writebuf)
		      {
			const gdb_byte *ptr
			  = writebuf + info.argloc[1].c_offset;
			riscv_regcache_cooked_write
			  (regnum, ptr, info.argloc[1].c_length,
			   regcache, call_info.flen);
		      }
		    break;

		  case riscv_arg_info::location::by_ref:
		  case riscv_arg_info::location::on_stack:
		  default:
		    error (_("invalid argument location"));
		    break;
		  }
	      }
	  }
	  break;

	  /* Return value by reference will have its address in A0.  */
	case riscv_arg_info::location::by_ref:
	  {
	    ULONGEST addr;

	    regcache_cooked_read_unsigned (regcache, RISCV_A0_REGNUM,
					   &addr);
	    if (readbuf != nullptr)
	      read_memory (addr, readbuf, info.length);
	    if (writebuf != nullptr)
	      write_memory (addr, writebuf, info.length);
	  }
	  break;

	case riscv_arg_info::location::on_stack:
	default:
	  error (_("invalid argument location"));
	  break;
	}

      /* This completes the cast from abi type back to the declared type
	 in the case that we are reading from the machine.  See the
	 comment at the head of this block for more details.  */
      if (readbuf != nullptr)
	{
	  struct value *arg_val;

	  if (is_fixed_point_type (arg_type))
	    {
	      /* Convert abi_val to the actual return type, but
		 being careful to preserve the fact that abi_val
		 is unscaled.  */
	      gdb_mpz unscaled;

	      unscaled.read (value_contents (abi_val),
			     type_byte_order (info.type),
			     info.type->is_unsigned ());
	      arg_val = allocate_value (arg_type);
	      unscaled.write (value_contents_raw (arg_val),
			      type_byte_order (arg_type),
			      arg_type->is_unsigned ());
	    }
	  else
	    arg_val = value_cast (arg_type, abi_val);
	  memcpy (old_readbuf, value_contents_raw (arg_val).data (),
		  arg_type->length ());
	}
    }

  switch (info.argloc[0].loc_type)
    {
    case riscv_arg_info::location::in_reg:
      return RETURN_VALUE_REGISTER_CONVENTION;
    case riscv_arg_info::location::by_ref:
      return RETURN_VALUE_ABI_PRESERVES_ADDRESS;
    case riscv_arg_info::location::on_stack:
    default:
      error (_("invalid argument location"));
    }
}

/* Implement the frame_align gdbarch method.  */

static CORE_ADDR
riscv_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return align_down (addr, 16);
}

/* Generate, or return the cached frame cache for the RiscV frame
   unwinder.  */

static struct riscv_unwind_cache *
riscv_frame_cache (frame_info_ptr this_frame, void **this_cache)
{
  CORE_ADDR pc, start_addr;
  struct riscv_unwind_cache *cache;
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  int numregs, regno;

  if ((*this_cache) != NULL)
    return (struct riscv_unwind_cache *) *this_cache;

  cache = FRAME_OBSTACK_ZALLOC (struct riscv_unwind_cache);
  cache->regs = trad_frame_alloc_saved_regs (this_frame);
  (*this_cache) = cache;

  /* Scan the prologue, filling in the cache.  */
  start_addr = get_frame_func (this_frame);
  pc = get_frame_pc (this_frame);
  riscv_scan_prologue (gdbarch, start_addr, pc, cache);

  /* We can now calculate the frame base address.  */
  cache->frame_base
    = (get_frame_register_unsigned (this_frame, cache->frame_base_reg)
       + cache->frame_base_offset);
  if (riscv_debug_unwinder)
    gdb_printf (gdb_stdlog, "Frame base is %s ($%s + 0x%x)\n",
		core_addr_to_string (cache->frame_base),
		gdbarch_register_name (gdbarch,
				       cache->frame_base_reg),
		cache->frame_base_offset);

  /* The prologue scanner sets the address of registers stored to the stack
     as the offset of that register from the frame base.  The prologue
     scanner doesn't know the actual frame base value, and so is unable to
     compute the exact address.  We do now know the frame base value, so
     update the address of registers stored to the stack.  */
  numregs = gdbarch_num_regs (gdbarch) + gdbarch_num_pseudo_regs (gdbarch);
  for (regno = 0; regno < numregs; ++regno)
    {
      if (cache->regs[regno].is_addr ())
	cache->regs[regno].set_addr (cache->regs[regno].addr ()
				     + cache->frame_base);
    }

  /* The previous $pc can be found wherever the $ra value can be found.
     The previous $ra value is gone, this would have been stored be the
     previous frame if required.  */
  cache->regs[gdbarch_pc_regnum (gdbarch)] = cache->regs[RISCV_RA_REGNUM];
  cache->regs[RISCV_RA_REGNUM].set_unknown ();

  /* Build the frame id.  */
  cache->this_id = frame_id_build (cache->frame_base, start_addr);

  /* The previous $sp value is the frame base value.  */
  cache->regs[gdbarch_sp_regnum (gdbarch)].set_value (cache->frame_base);

  return cache;
}

/* Implement the this_id callback for RiscV frame unwinder.  */

static void
riscv_frame_this_id (frame_info_ptr this_frame,
		     void **prologue_cache,
		     struct frame_id *this_id)
{
  struct riscv_unwind_cache *cache;

  try
    {
      cache = riscv_frame_cache (this_frame, prologue_cache);
      *this_id = cache->this_id;
    }
  catch (const gdb_exception_error &ex)
    {
      /* Ignore errors, this leaves the frame id as the predefined outer
	 frame id which terminates the backtrace at this point.  */
    }
}

/* Implement the prev_register callback for RiscV frame unwinder.  */

static struct value *
riscv_frame_prev_register (frame_info_ptr this_frame,
			   void **prologue_cache,
			   int regnum)
{
  struct riscv_unwind_cache *cache;

  cache = riscv_frame_cache (this_frame, prologue_cache);
  return trad_frame_get_prev_register (this_frame, cache->regs, regnum);
}

/* Structure defining the RiscV normal frame unwind functions.  Since we
   are the fallback unwinder (DWARF unwinder is used first), we use the
   default frame sniffer, which always accepts the frame.  */

static const struct frame_unwind riscv_frame_unwind =
{
  /*.name          =*/ "riscv prologue",
  /*.type          =*/ NORMAL_FRAME,
  /*.stop_reason   =*/ default_frame_unwind_stop_reason,
  /*.this_id       =*/ riscv_frame_this_id,
  /*.prev_register =*/ riscv_frame_prev_register,
  /*.unwind_data   =*/ NULL,
  /*.sniffer       =*/ default_frame_sniffer,
  /*.dealloc_cache =*/ NULL,
  /*.prev_arch     =*/ NULL,
};

/* Extract a set of required target features out of ABFD.  If ABFD is
   nullptr then a RISCV_GDBARCH_FEATURES is returned in its default state.  */

static struct riscv_gdbarch_features
riscv_features_from_bfd (const bfd *abfd)
{
  struct riscv_gdbarch_features features;

  /* Now try to improve on the defaults by looking at the binary we are
     going to execute.  We assume the user knows what they are doing and
     that the target will match the binary.  Remember, this code path is
     only used at all if the target hasn't given us a description, so this
     is really a last ditched effort to do something sane before giving
     up.  */
  if (abfd != nullptr && bfd_get_flavour (abfd) == bfd_target_elf_flavour)
    {
      unsigned char eclass = elf_elfheader (abfd)->e_ident[EI_CLASS];
      int e_flags = elf_elfheader (abfd)->e_flags;

      if (eclass == ELFCLASS32)
	features.xlen = 4;
      else if (eclass == ELFCLASS64)
	features.xlen = 8;
      else
	internal_error (_("unknown ELF header class %d"), eclass);

      if (e_flags & EF_RISCV_FLOAT_ABI_DOUBLE)
	features.flen = 8;
      else if (e_flags & EF_RISCV_FLOAT_ABI_SINGLE)
	features.flen = 4;

      if (e_flags & EF_RISCV_RVE)
	{
	  if (features.xlen == 8)
	    {
	      warning (_("64-bit ELF with RV32E flag set!  Assuming 32-bit"));
	      features.xlen = 4;
	    }
	  features.embedded = true;
	}
    }

  return features;
}

/* Find a suitable default target description.  Use the contents of INFO,
   specifically the bfd object being executed, to guide the selection of a
   suitable default target description.  */

static const struct target_desc *
riscv_find_default_target_description (const struct gdbarch_info info)
{
  /* Extract desired feature set from INFO.  */
  struct riscv_gdbarch_features features
    = riscv_features_from_bfd (info.abfd);

  /* If the XLEN field is still 0 then we got nothing useful from INFO.BFD,
     maybe there was no bfd object.  In this case we fall back to a minimal
     useful target with no floating point, the x-register size is selected
     based on the architecture from INFO.  */
  if (features.xlen == 0)
    features.xlen = info.bfd_arch_info->bits_per_word == 32 ? 4 : 8;

  /* Now build a target description based on the feature set.  */
  return riscv_lookup_target_description (features);
}

/* Add all the RISC-V specific register groups into GDBARCH.  */

static void
riscv_add_reggroups (struct gdbarch *gdbarch)
{
  reggroup_add (gdbarch, csr_reggroup);
}

/* Implement the "dwarf2_reg_to_regnum" gdbarch method.  */

static int
riscv_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
  if (reg <= RISCV_DWARF_REGNUM_X31)
    return RISCV_ZERO_REGNUM + (reg - RISCV_DWARF_REGNUM_X0);

  else if (reg <= RISCV_DWARF_REGNUM_F31)
    return RISCV_FIRST_FP_REGNUM + (reg - RISCV_DWARF_REGNUM_F0);

  else if (reg >= RISCV_DWARF_FIRST_CSR && reg <= RISCV_DWARF_LAST_CSR)
    return RISCV_FIRST_CSR_REGNUM + (reg - RISCV_DWARF_FIRST_CSR);

  else if (reg >= RISCV_DWARF_REGNUM_V0 && reg <= RISCV_DWARF_REGNUM_V31)
    return RISCV_V0_REGNUM + (reg - RISCV_DWARF_REGNUM_V0);

  return -1;
}

/* Implement the gcc_target_options method.  We have to select the arch and abi
   from the feature info.  We have enough feature info to select the abi, but
   not enough info for the arch given all of the possible architecture
   extensions.  So choose reasonable defaults for now.  */

static std::string
riscv_gcc_target_options (struct gdbarch *gdbarch)
{
  int isa_xlen = riscv_isa_xlen (gdbarch);
  int isa_flen = riscv_isa_flen (gdbarch);
  int abi_xlen = riscv_abi_xlen (gdbarch);
  int abi_flen = riscv_abi_flen (gdbarch);
  std::string target_options;

  target_options = "-march=rv";
  if (isa_xlen == 8)
    target_options += "64";
  else
    target_options += "32";
  if (isa_flen == 8)
    target_options += "gc";
  else if (isa_flen == 4)
    target_options += "imafc";
  else
    target_options += "imac";

  target_options += " -mabi=";
  if (abi_xlen == 8)
    target_options += "lp64";
  else
    target_options += "ilp32";
  if (abi_flen == 8)
    target_options += "d";
  else if (abi_flen == 4)
    target_options += "f";

  /* The gdb loader doesn't handle link-time relaxation relocations.  */
  target_options += " -mno-relax";

  return target_options;
}

/* Call back from tdesc_use_registers, called for each unknown register
   found in the target description.

   See target-description.h (typedef tdesc_unknown_register_ftype) for a
   discussion of the arguments and return values.  */

static int
riscv_tdesc_unknown_reg (struct gdbarch *gdbarch, tdesc_feature *feature,
			 const char *reg_name, int possible_regnum)
{
  /* At one point in time GDB had an incorrect default target description
     that duplicated the fflags, frm, and fcsr registers in both the FPU
     and CSR register sets.

     Some targets (QEMU) copied these target descriptions into their source
     tree, and so we're now stuck working with some versions of QEMU that
     declare the same registers twice.

     To make matters worse, if GDB tries to read or write to these
     registers using the register number assigned in the FPU feature set,
     then QEMU will fail to read the register, so we must use the register
     number declared in the CSR feature set.

     Luckily, GDB scans the FPU feature first, and then the CSR feature,
     which means that the CSR feature will be the one we end up using, the
     versions of these registers in the FPU feature will appear as unknown
     registers and will be passed through to this code.

     To prevent these duplicate registers showing up in any of the register
     lists, and to prevent GDB every trying to access the FPU feature copies,
     we spot the three problematic registers here, and record the register
     number that GDB has assigned them.  Then in riscv_register_name we will
     return no name for the three duplicates, this hides the duplicates from
     the user.  */
  if (strcmp (tdesc_feature_name (feature), riscv_freg_feature.name ()) == 0)
    {
      riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
      int *regnum_ptr = nullptr;

      if (strcmp (reg_name, "fflags") == 0)
	regnum_ptr = &tdep->duplicate_fflags_regnum;
      else if (strcmp (reg_name, "frm") == 0)
	regnum_ptr = &tdep->duplicate_frm_regnum;
      else if (strcmp (reg_name, "fcsr") == 0)
	regnum_ptr = &tdep->duplicate_fcsr_regnum;

      if (regnum_ptr != nullptr)
	{
	  /* This means the register appears more than twice in the target
	     description.  Just let GDB add this as another register.
	     We'll have duplicates in the register name list, but there's
	     not much more we can do.  */
	  if (*regnum_ptr != -1)
	    return -1;

	  /* Record the number assigned to this register, then return the
	     number (so it actually gets assigned to this register).  */
	  *regnum_ptr = possible_regnum;
	  return possible_regnum;
	}
    }

  /* Any unknown registers in the CSR feature are recorded within a single
     block so we can easily identify these registers when making choices
     about register groups in riscv_register_reggroup_p.  */
  if (strcmp (tdesc_feature_name (feature), riscv_csr_feature.name ()) == 0)
    {
      riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
      if (tdep->unknown_csrs_first_regnum == -1)
	tdep->unknown_csrs_first_regnum = possible_regnum;
      gdb_assert (tdep->unknown_csrs_first_regnum
		  + tdep->unknown_csrs_count == possible_regnum);
      tdep->unknown_csrs_count++;
      return possible_regnum;
    }

  /* Some other unknown register.  Don't assign this a number now, it will
     be assigned a number automatically later by the target description
     handling code.  */
  return -1;
}

/* Implement the gnu_triplet_regexp method.  A single compiler supports both
   32-bit and 64-bit code, and may be named riscv32 or riscv64 or (not
   recommended) riscv.  */

static const char *
riscv_gnu_triplet_regexp (struct gdbarch *gdbarch)
{
  return "riscv(32|64)?";
}

/* Initialize the current architecture based on INFO.  If possible,
   re-use an architecture from ARCHES, which is a list of
   architectures already created during this debugging session.

   Called e.g. at program startup, when reading a core file, and when
   reading a binary file.  */

static struct gdbarch *
riscv_gdbarch_init (struct gdbarch_info info,
		    struct gdbarch_list *arches)
{
  struct gdbarch *gdbarch;
  struct riscv_gdbarch_features features;
  const struct target_desc *tdesc = info.target_desc;

  /* Ensure we always have a target description.  */
  if (!tdesc_has_registers (tdesc))
    tdesc = riscv_find_default_target_description (info);
  gdb_assert (tdesc != nullptr);

  if (riscv_debug_gdbarch)
    gdb_printf (gdb_stdlog, "Have got a target description\n");

  tdesc_arch_data_up tdesc_data = tdesc_data_alloc ();
  std::vector<riscv_pending_register_alias> pending_aliases;

  bool valid_p = (riscv_xreg_feature.check (tdesc, tdesc_data.get (),
					    &pending_aliases, &features)
		  && riscv_freg_feature.check (tdesc, tdesc_data.get (),
					       &pending_aliases, &features)
		  && riscv_virtual_feature.check (tdesc, tdesc_data.get (),
						  &pending_aliases, &features)
		  && riscv_csr_feature.check (tdesc, tdesc_data.get (),
					      &pending_aliases, &features)
		  && riscv_vector_feature.check (tdesc, tdesc_data.get (),
						 &pending_aliases, &features));
  if (!valid_p)
    {
      if (riscv_debug_gdbarch)
	gdb_printf (gdb_stdlog, "Target description is not valid\n");
      return NULL;
    }

  if (tdesc_found_register (tdesc_data.get (), RISCV_CSR_FFLAGS_REGNUM))
    features.has_fflags_reg = true;
  if (tdesc_found_register (tdesc_data.get (), RISCV_CSR_FRM_REGNUM))
    features.has_frm_reg = true;
  if (tdesc_found_register (tdesc_data.get (), RISCV_CSR_FCSR_REGNUM))
    features.has_fcsr_reg = true;

  /* Have a look at what the supplied (if any) bfd object requires of the
     target, then check that this matches with what the target is
     providing.  */
  struct riscv_gdbarch_features abi_features
    = riscv_features_from_bfd (info.abfd);

  /* If the ABI_FEATURES xlen is 0 then this indicates we got no useful abi
     features from the INFO object.  In this case we just treat the
     hardware features as defining the abi.  */
  if (abi_features.xlen == 0)
    abi_features = features;

  /* In theory a binary compiled for RV32 could run on an RV64 target,
     however, this has not been tested in GDB yet, so for now we require
     that the requested xlen match the targets xlen.  */
  if (abi_features.xlen != features.xlen)
    error (_("bfd requires xlen %d, but target has xlen %d"),
	    abi_features.xlen, features.xlen);
  /* We do support running binaries compiled for 32-bit float on targets
     with 64-bit float, so we only complain if the binary requires more
     than the target has available.  */
  if (abi_features.flen > features.flen)
    error (_("bfd requires flen %d, but target has flen %d"),
	    abi_features.flen, features.flen);

  /* Find a candidate among the list of pre-declared architectures.  */
  for (arches = gdbarch_list_lookup_by_info (arches, &info);
       arches != NULL;
       arches = gdbarch_list_lookup_by_info (arches->next, &info))
    {
      /* Check that the feature set of the ARCHES matches the feature set
	 we are looking for.  If it doesn't then we can't reuse this
	 gdbarch.  */
      riscv_gdbarch_tdep *other_tdep
	= gdbarch_tdep<riscv_gdbarch_tdep> (arches->gdbarch);

      if (other_tdep->isa_features != features
	  || other_tdep->abi_features != abi_features)
	continue;

      break;
    }

  if (arches != NULL)
    return arches->gdbarch;

  /* None found, so create a new architecture from the information provided.  */
  riscv_gdbarch_tdep *tdep = new riscv_gdbarch_tdep;
  gdbarch = gdbarch_alloc (&info, tdep);
  tdep->isa_features = features;
  tdep->abi_features = abi_features;

  /* Target data types.  */
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 32);
  set_gdbarch_long_bit (gdbarch, riscv_isa_xlen (gdbarch) * 8);
  set_gdbarch_long_long_bit (gdbarch, 64);
  set_gdbarch_float_bit (gdbarch, 32);
  set_gdbarch_double_bit (gdbarch, 64);
  set_gdbarch_long_double_bit (gdbarch, 128);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_quad);
  set_gdbarch_ptr_bit (gdbarch, riscv_isa_xlen (gdbarch) * 8);
  set_gdbarch_char_signed (gdbarch, 0);
  set_gdbarch_type_align (gdbarch, riscv_type_align);

  /* Information about the target architecture.  */
  set_gdbarch_return_value_as_value (gdbarch, riscv_return_value);
  set_gdbarch_breakpoint_kind_from_pc (gdbarch, riscv_breakpoint_kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch, riscv_sw_breakpoint_from_kind);
  set_gdbarch_have_nonsteppable_watchpoint (gdbarch, 1);

  /* Functions to analyze frames.  */
  set_gdbarch_skip_prologue (gdbarch, riscv_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
  set_gdbarch_frame_align (gdbarch, riscv_frame_align);

  /* Functions handling dummy frames.  */
  set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
  set_gdbarch_push_dummy_code (gdbarch, riscv_push_dummy_code);
  set_gdbarch_push_dummy_call (gdbarch, riscv_push_dummy_call);

  /* Frame unwinders.  Use DWARF debug info if available, otherwise use our own
     unwinder.  */
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &riscv_frame_unwind);

  /* Register architecture.  */
  riscv_add_reggroups (gdbarch);

  /* Internal <-> external register number maps.  */
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, riscv_dwarf_reg_to_regnum);

  /* We reserve all possible register numbers for the known registers.
     This means the target description mechanism will add any target
     specific registers after this number.  This helps make debugging GDB
     just a little easier.  */
  set_gdbarch_num_regs (gdbarch, RISCV_LAST_REGNUM + 1);

  /* Some specific register numbers GDB likes to know about.  */
  set_gdbarch_sp_regnum (gdbarch, RISCV_SP_REGNUM);
  set_gdbarch_pc_regnum (gdbarch, RISCV_PC_REGNUM);

  set_gdbarch_print_registers_info (gdbarch, riscv_print_registers_info);

  set_tdesc_pseudo_register_name (gdbarch, riscv_pseudo_register_name);
  set_tdesc_pseudo_register_type (gdbarch, riscv_pseudo_register_type);
  set_tdesc_pseudo_register_reggroup_p (gdbarch,
					riscv_pseudo_register_reggroup_p);
  set_gdbarch_pseudo_register_read (gdbarch, riscv_pseudo_register_read);
  set_gdbarch_pseudo_register_write (gdbarch, riscv_pseudo_register_write);

  /* Finalise the target description registers.  */
  tdesc_use_registers (gdbarch, tdesc, std::move (tdesc_data),
		       riscv_tdesc_unknown_reg);

  /* Calculate the number of pseudo registers we need.  The fflags and frm
     registers are sub-fields of the fcsr CSR register (csr3).  However,
     these registers can also be accessed directly as separate CSR
     registers (fflags is csr1, and frm is csr2).  And so, some targets
     might choose to offer direct access to all three registers in the
     target description, while other targets might choose to only offer
     access to fcsr.

     As we scan the target description we spot which of fcsr, fflags, and
     frm are available.  If fcsr is available but either of fflags and/or
     frm are not available, then we add pseudo-registers to provide the
     missing functionality.

     This has to be done after the call to tdesc_use_registers as we don't
     know the final register number until after that call, and the pseudo
     register numbers need to be after the physical registers.  */
  int num_pseudo_regs = 0;
  int next_pseudo_regnum = gdbarch_num_regs (gdbarch);

  if (features.has_fflags_reg)
    tdep->fflags_regnum = RISCV_CSR_FFLAGS_REGNUM;
  else if (features.has_fcsr_reg)
    {
      tdep->fflags_regnum = next_pseudo_regnum;
      pending_aliases.emplace_back ("csr1", (void *) &tdep->fflags_regnum);
      next_pseudo_regnum++;
      num_pseudo_regs++;
    }

  if (features.has_frm_reg)
    tdep->frm_regnum = RISCV_CSR_FRM_REGNUM;
  else if (features.has_fcsr_reg)
    {
      tdep->frm_regnum = next_pseudo_regnum;
      pending_aliases.emplace_back ("csr2", (void *) &tdep->frm_regnum);
      next_pseudo_regnum++;
      num_pseudo_regs++;
    }

  set_gdbarch_num_pseudo_regs (gdbarch, num_pseudo_regs);

  /* Override the register type callback setup by the target description
     mechanism.  This allows us to provide special type for floating point
     registers.  */
  set_gdbarch_register_type (gdbarch, riscv_register_type);

  /* Override the register name callback setup by the target description
     mechanism.  This allows us to force our preferred names for the
     registers, no matter what the target description called them.  */
  set_gdbarch_register_name (gdbarch, riscv_register_name);

  /* Tell GDB which RISC-V registers are read-only. */
  set_gdbarch_cannot_store_register (gdbarch, riscv_cannot_store_register);

  /* Override the register group callback setup by the target description
     mechanism.  This allows us to force registers into the groups we
     want, ignoring what the target tells us.  */
  set_gdbarch_register_reggroup_p (gdbarch, riscv_register_reggroup_p);

  /* Create register aliases for alternative register names.  We only
     create aliases for registers which were mentioned in the target
     description.  */
  for (const auto &alias : pending_aliases)
    alias.create (gdbarch);

  /* Compile command hooks.  */
  set_gdbarch_gcc_target_options (gdbarch, riscv_gcc_target_options);
  set_gdbarch_gnu_triplet_regexp (gdbarch, riscv_gnu_triplet_regexp);

  /* Disassembler options support.  */
  set_gdbarch_valid_disassembler_options (gdbarch,
					  disassembler_options_riscv ());
  set_gdbarch_disassembler_options (gdbarch, &riscv_disassembler_options);

  /* Hook in OS ABI-specific overrides, if they have been registered.  */
  gdbarch_init_osabi (info, gdbarch);

  register_riscv_ravenscar_ops (gdbarch);

  return gdbarch;
}

/* This decodes the current instruction and determines the address of the
   next instruction.  */

static CORE_ADDR
riscv_next_pc (struct regcache *regcache, CORE_ADDR pc)
{
  struct gdbarch *gdbarch = regcache->arch ();
  const riscv_gdbarch_tdep *tdep
    = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);
  struct riscv_insn insn;
  CORE_ADDR next_pc;

  insn.decode (gdbarch, pc);
  next_pc = pc + insn.length ();

  if (insn.opcode () == riscv_insn::JAL)
    next_pc = pc + insn.imm_signed ();
  else if (insn.opcode () == riscv_insn::JALR)
    {
      LONGEST source;
      regcache->cooked_read (insn.rs1 (), &source);
      next_pc = (source + insn.imm_signed ()) & ~(CORE_ADDR) 0x1;
    }
  else if (insn.opcode () == riscv_insn::BEQ)
    {
      LONGEST src1, src2;
      regcache->cooked_read (insn.rs1 (), &src1);
      regcache->cooked_read (insn.rs2 (), &src2);
      if (src1 == src2)
	next_pc = pc + insn.imm_signed ();
    }
  else if (insn.opcode () == riscv_insn::BNE)
    {
      LONGEST src1, src2;
      regcache->cooked_read (insn.rs1 (), &src1);
      regcache->cooked_read (insn.rs2 (), &src2);
      if (src1 != src2)
	next_pc = pc + insn.imm_signed ();
    }
  else if (insn.opcode () == riscv_insn::BLT)
    {
      LONGEST src1, src2;
      regcache->cooked_read (insn.rs1 (), &src1);
      regcache->cooked_read (insn.rs2 (), &src2);
      if (src1 < src2)
	next_pc = pc + insn.imm_signed ();
    }
  else if (insn.opcode () == riscv_insn::BGE)
    {
      LONGEST src1, src2;
      regcache->cooked_read (insn.rs1 (), &src1);
      regcache->cooked_read (insn.rs2 (), &src2);
      if (src1 >= src2)
	next_pc = pc + insn.imm_signed ();
    }
  else if (insn.opcode () == riscv_insn::BLTU)
    {
      ULONGEST src1, src2;
      regcache->cooked_read (insn.rs1 (), &src1);
      regcache->cooked_read (insn.rs2 (), &src2);
      if (src1 < src2)
	next_pc = pc + insn.imm_signed ();
    }
  else if (insn.opcode () == riscv_insn::BGEU)
    {
      ULONGEST src1, src2;
      regcache->cooked_read (insn.rs1 (), &src1);
      regcache->cooked_read (insn.rs2 (), &src2);
      if (src1 >= src2)
	next_pc = pc + insn.imm_signed ();
    }
  else if (insn.opcode () == riscv_insn::ECALL)
    {
      if (tdep->syscall_next_pc != nullptr)
	next_pc = tdep->syscall_next_pc (get_current_frame ());
    }

  return next_pc;
}

/* We can't put a breakpoint in the middle of a lr/sc atomic sequence, so look
   for the end of the sequence and put the breakpoint there.  */

static bool
riscv_next_pc_atomic_sequence (struct regcache *regcache, CORE_ADDR pc,
			       CORE_ADDR *next_pc)
{
  struct gdbarch *gdbarch = regcache->arch ();
  struct riscv_insn insn;
  CORE_ADDR cur_step_pc = pc;
  CORE_ADDR last_addr = 0;

  /* First instruction has to be a load reserved.  */
  insn.decode (gdbarch, cur_step_pc);
  if (insn.opcode () != riscv_insn::LR)
    return false;
  cur_step_pc = cur_step_pc + insn.length ();

  /* Next instruction should be branch to exit.  */
  insn.decode (gdbarch, cur_step_pc);
  if (insn.opcode () != riscv_insn::BNE)
    return false;
  last_addr = cur_step_pc + insn.imm_signed ();
  cur_step_pc = cur_step_pc + insn.length ();

  /* Next instruction should be store conditional.  */
  insn.decode (gdbarch, cur_step_pc);
  if (insn.opcode () != riscv_insn::SC)
    return false;
  cur_step_pc = cur_step_pc + insn.length ();

  /* Next instruction should be branch to start.  */
  insn.decode (gdbarch, cur_step_pc);
  if (insn.opcode () != riscv_insn::BNE)
    return false;
  if (pc != (cur_step_pc + insn.imm_signed ()))
    return false;
  cur_step_pc = cur_step_pc + insn.length ();

  /* We should now be at the end of the sequence.  */
  if (cur_step_pc != last_addr)
    return false;

  *next_pc = cur_step_pc;
  return true;
}

/* This is called just before we want to resume the inferior, if we want to
   single-step it but there is no hardware or kernel single-step support.  We
   find the target of the coming instruction and breakpoint it.  */

std::vector<CORE_ADDR>
riscv_software_single_step (struct regcache *regcache)
{
  CORE_ADDR pc, next_pc;

  pc = regcache_read_pc (regcache);

  if (riscv_next_pc_atomic_sequence (regcache, pc, &next_pc))
    return {next_pc};

  next_pc = riscv_next_pc (regcache, pc);

  return {next_pc};
}

/* Create RISC-V specific reggroups.  */

static void
riscv_init_reggroups ()
{
  csr_reggroup = reggroup_new ("csr", USER_REGGROUP);
}

/* See riscv-tdep.h.  */

void
riscv_supply_regset (const struct regset *regset,
		     struct regcache *regcache, int regnum,
		     const void *regs, size_t len)
{
  regcache->supply_regset (regset, regnum, regs, len);

  if (regnum == -1 || regnum == RISCV_ZERO_REGNUM)
    regcache->raw_supply_zeroed (RISCV_ZERO_REGNUM);

  struct gdbarch *gdbarch = regcache->arch ();
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

  if (regnum == -1
      || regnum == tdep->fflags_regnum
      || regnum == tdep->frm_regnum)
    {
      int fcsr_regnum = RISCV_CSR_FCSR_REGNUM;

      /* Ensure that FCSR has been read into REGCACHE.  */
      if (regnum != -1)
	regcache->supply_regset (regset, fcsr_regnum, regs, len);

      /* Grab the FCSR value if it is now in the regcache.  We must check
	 the status first as, if the register was not supplied by REGSET,
	 this call will trigger a recursive attempt to fetch the
	 registers.  */
      if (regcache->get_register_status (fcsr_regnum) == REG_VALID)
	{
	  /* If we have an fcsr register then we should have fflags and frm
	     too, either provided by the target, or provided as a pseudo
	     register by GDB.  */
	  gdb_assert (tdep->fflags_regnum >= 0);
	  gdb_assert (tdep->frm_regnum >= 0);

	  ULONGEST fcsr_val;
	  regcache->raw_read (fcsr_regnum, &fcsr_val);

	  /* Extract the fflags and frm values.  */
	  ULONGEST fflags_val = fcsr_val & 0x1f;
	  ULONGEST frm_val = (fcsr_val >> 5) & 0x7;

	  /* And supply these if needed.  We can only supply real
	     registers, so don't try to supply fflags or frm if they are
	     implemented as pseudo-registers.  */
	  if ((regnum == -1 || regnum == tdep->fflags_regnum)
	      && tdep->fflags_regnum < gdbarch_num_regs (gdbarch))
	    regcache->raw_supply_integer (tdep->fflags_regnum,
					  (gdb_byte *) &fflags_val,
					  sizeof (fflags_val),
					  /* is_signed */ false);

	  if ((regnum == -1 || regnum == tdep->frm_regnum)
	      && tdep->frm_regnum < gdbarch_num_regs (gdbarch))
	    regcache->raw_supply_integer (tdep->frm_regnum,
					  (gdb_byte *)&frm_val,
					  sizeof (fflags_val),
					  /* is_signed */ false);
	}
    }
}

void _initialize_riscv_tdep ();
void
_initialize_riscv_tdep ()
{
  riscv_init_reggroups ();

  gdbarch_register (bfd_arch_riscv, riscv_gdbarch_init, NULL);

  /* Add root prefix command for all "set debug riscv" and "show debug
     riscv" commands.  */
  add_setshow_prefix_cmd ("riscv", no_class,
			  _("RISC-V specific debug commands."),
			  _("RISC-V specific debug commands."),
			  &setdebugriscvcmdlist, &showdebugriscvcmdlist,
			  &setdebuglist, &showdebuglist);

  add_setshow_zuinteger_cmd ("breakpoints", class_maintenance,
			     &riscv_debug_breakpoints,  _("\
Set riscv breakpoint debugging."), _("\
Show riscv breakpoint debugging."), _("\
When non-zero, print debugging information for the riscv specific parts\n\
of the breakpoint mechanism."),
			     NULL,
			     show_riscv_debug_variable,
			     &setdebugriscvcmdlist, &showdebugriscvcmdlist);

  add_setshow_zuinteger_cmd ("infcall", class_maintenance,
			     &riscv_debug_infcall,  _("\
Set riscv inferior call debugging."), _("\
Show riscv inferior call debugging."), _("\
When non-zero, print debugging information for the riscv specific parts\n\
of the inferior call mechanism."),
			     NULL,
			     show_riscv_debug_variable,
			     &setdebugriscvcmdlist, &showdebugriscvcmdlist);

  add_setshow_zuinteger_cmd ("unwinder", class_maintenance,
			     &riscv_debug_unwinder,  _("\
Set riscv stack unwinding debugging."), _("\
Show riscv stack unwinding debugging."), _("\
When non-zero, print debugging information for the riscv specific parts\n\
of the stack unwinding mechanism."),
			     NULL,
			     show_riscv_debug_variable,
			     &setdebugriscvcmdlist, &showdebugriscvcmdlist);

  add_setshow_zuinteger_cmd ("gdbarch", class_maintenance,
			     &riscv_debug_gdbarch,  _("\
Set riscv gdbarch initialisation debugging."), _("\
Show riscv gdbarch initialisation debugging."), _("\
When non-zero, print debugging information for the riscv gdbarch\n\
initialisation process."),
			     NULL,
			     show_riscv_debug_variable,
			     &setdebugriscvcmdlist, &showdebugriscvcmdlist);

  /* Add root prefix command for all "set riscv" and "show riscv" commands.  */
  add_setshow_prefix_cmd ("riscv", no_class,
			  _("RISC-V specific commands."),
			  _("RISC-V specific commands."),
			  &setriscvcmdlist, &showriscvcmdlist,
			  &setlist, &showlist);


  use_compressed_breakpoints = AUTO_BOOLEAN_AUTO;
  add_setshow_auto_boolean_cmd ("use-compressed-breakpoints", no_class,
				&use_compressed_breakpoints,
				_("\
Set debugger's use of compressed breakpoints."), _("	\
Show debugger's use of compressed breakpoints."), _("\
Debugging compressed code requires compressed breakpoints to be used. If\n\
left to 'auto' then gdb will use them if the existing instruction is a\n\
compressed instruction. If that doesn't give the correct behavior, then\n\
this option can be used."),
				NULL,
				show_use_compressed_breakpoints,
				&setriscvcmdlist,
				&showriscvcmdlist);
}
