/* 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 "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"
#include "gdbsupport/gdb-safe-ctype.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 true debugging information about breakpoint kinds will be
   printed.  */

static bool riscv_debug_breakpoints = false;

/* Print a "riscv-breakpoints" debug statement.  */

#define riscv_breakpoints_debug_printf(fmt, ...)	\
  debug_prefixed_printf_cond (riscv_debug_breakpoints,	\
			      "riscv-breakpoints",	\
			      fmt, ##__VA_ARGS__)

/* When this is true debugging information about inferior calls will be
   printed.  */

static bool riscv_debug_infcall = false;

/* Print a "riscv-infcall" debug statement.  */

#define riscv_infcall_debug_printf(fmt, ...)				\
  debug_prefixed_printf_cond (riscv_debug_infcall, "riscv-infcall",	\
			      fmt, ##__VA_ARGS__)

/* Print "riscv-infcall" start/end debug statements.  */

#define RISCV_INFCALL_SCOPED_DEBUG_START_END(fmt, ...)		\
  scoped_debug_start_end (riscv_debug_infcall, "riscv-infcall", \
			  fmt, ##__VA_ARGS__)

/* When this is true debugging information about stack unwinding will be
   printed.  */

static bool riscv_debug_unwinder = false;

/* Print a "riscv-unwinder" debug statement.  */

#define riscv_unwinder_debug_printf(fmt, ...)				\
  debug_prefixed_printf_cond (riscv_debug_unwinder, "riscv-unwinder",	\
			      fmt, ##__VA_ARGS__)

/* When this is true debugging information about gdbarch initialisation
   will be printed.  */

static bool riscv_debug_gdbarch = false;

/* Print a "riscv-gdbarch" debug statement.  */

#define riscv_gdbarch_debug_printf(fmt, ...)				\
  debug_prefixed_printf_cond (riscv_debug_gdbarch, "riscv-gdbarch",	\
			      fmt, ##__VA_ARGS__)

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

	  std::string suffix;
	  if (unaligned_p)
	    suffix = "(unaligned address)";
	  else
	    suffix = string_printf ("(instruction length %d)",
				    riscv_insn_length (buf[0]));
	  riscv_breakpoints_debug_printf ("Using %s for breakpoint at %s %s",
					  bp, paddress (gdbarch, *pcptr),
					  suffix.c_str ());
	}
      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 (std::max<int> (1, value_column_1 - strlen (name)), file);

  try
    {
      val = value_of_register (regnum, frame);
      regtype = val->type ();
    }
  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 = (val->entirely_available ()
		      && !val->optimized_out ());

  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 = val->contents_for_printing ().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,
      LI,
      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.  Some
     of the CI instruction have a hard-coded rs1 register, while others
     just use rd for both the source and destination.  RS1_REGNUM, if
     passed, is the value to place in rs1, otherwise rd is duplicated into
     rs1.  */
  void decode_ci_type_insn (enum opcode opcode, ULONGEST ival,
			    std::optional<int> rs1_regnum = {})
  {
    m_opcode = opcode;
    m_rd = decode_register_index (ival, OP_SH_CRS1S);
    if (rs1_regnum.has_value ())
      m_rs1 = *rs1_regnum;
    else
      m_rs1 = m_rd;
    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)
{
  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);
    }

  /* RISC-V Specification states instructions are always little endian */
  return extract_unsigned_integer (buf, instlen, BFD_ENDIAN_LITTLE);
}

/* 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);
	}
      else if (is_c_li_insn (ival))
	decode_ci_type_insn (LI, 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 if (is_c_ldsp_insn (ival))
	decode_ci_type_insn (LD, ival, RISCV_SP_REGNUM);
      else if (is_c_lwsp_insn (ival))
	decode_ci_type_insn (LW, ival, RISCV_SP_REGNUM);
      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;
    }
}

/* Return true if INSN represents an instruction something like:

   ld fp,IMMEDIATE(sp)

   That is, a load from stack-pointer plus some immediate offset, with the
   result stored into the frame pointer.  We also accept 'lw' as well as
   'ld'.  */

static bool
is_insn_load_of_fp_from_sp (const struct riscv_insn &insn)
{
  return ((insn.opcode () == riscv_insn::LD
	   || insn.opcode () == riscv_insn::LW)
	  && insn.rd () == RISCV_FP_REGNUM
	  && insn.rs1 () == RISCV_SP_REGNUM);
}

/* Return true if INSN represents an instruction something like:

   add sp,sp,IMMEDIATE

   That is, an add of an immediate to the value in the stack pointer
   register, with the result stored back to the stack pointer register.  */

static bool
is_insn_addi_of_sp_to_sp (const struct riscv_insn &insn)
{
  return ((insn.opcode () == riscv_insn::ADDI
	   || insn.opcode () == riscv_insn::ADDIW)
	  && insn.rd () == RISCV_SP_REGNUM
	  && insn.rs1 () == RISCV_SP_REGNUM);
}

/* Is the instruction in code memory prior to address PC a load from stack
   instruction?  Return true if it is, otherwise, return false.

   This is a best effort that is used as part of the function prologue
   scanning logic.  With compressed instructions and arbitrary control
   flow in the inferior, we can never be certain what the instruction
   prior to PC is.

   This function first looks for a compressed instruction, then looks for
   a 32-bit non-compressed instruction.  */

static bool
previous_insn_is_load_fp_from_stack (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  struct riscv_insn insn;
  insn.decode (gdbarch, pc - 2);
  gdb_assert (insn.length () > 0);

  if (insn.length () != 2 || !is_insn_load_of_fp_from_sp (insn))
    {
      insn.decode (gdbarch, pc - 4);
      gdb_assert (insn.length () > 0);

      if (insn.length () != 4 || !is_insn_load_of_fp_from_sp (insn))
	return false;
    }

  riscv_unwinder_debug_printf
    ("previous instruction at %s (length %d) was 'ld'",
     core_addr_to_string (pc - insn.length ()), insn.length ());
  return true;
}

/* Is the instruction in code memory prior to address PC an add of an
   immediate to the stack pointer, with the result being written back into
   the stack pointer?  Return true and set *PREV_PC to the address of the
   previous instruction if we believe the previous instruction is such an
   add, otherwise return false and *PREV_PC is undefined.

   This is a best effort that is used as part of the function prologue
   scanning logic.  With compressed instructions and arbitrary control
   flow in the inferior, we can never be certain what the instruction
   prior to PC is.

   This function first looks for a compressed instruction, then looks for
   a 32-bit non-compressed instruction.  */

static bool
previous_insn_is_add_imm_to_sp (struct gdbarch *gdbarch, CORE_ADDR pc,
				CORE_ADDR *prev_pc)
{
  struct riscv_insn insn;
  insn.decode (gdbarch, pc - 2);
  gdb_assert (insn.length () > 0);

  if (insn.length () != 2 || !is_insn_addi_of_sp_to_sp (insn))
    {
      insn.decode (gdbarch, pc - 4);
      gdb_assert (insn.length () > 0);

      if (insn.length () != 4 || !is_insn_addi_of_sp_to_sp (insn))
	return false;
    }

  riscv_unwinder_debug_printf
    ("previous instruction at %s (length %d) was 'add'",
     core_addr_to_string (pc - insn.length ()), insn.length ());
  *prev_pc = pc - insn.length ();
  return true;
}

/* Try to spot when PC is located in an exit sequence for a particular
   function.  Detecting an exit sequence involves a limited amount of
   scanning backwards through the disassembly, and so, when considering
   compressed instructions, we can never be certain that we have
   disassembled the preceding instructions correctly.  On top of that, we
   can't be certain that the inferior arrived at PC by passing through the
   preceding instructions.

   With all that said, we know that using prologue scanning to figure a
   functions unwind information starts to fail when we consider returns
   from an instruction -- we must pass through some instructions that
   restore the previous state prior to the final return instruction, and
   with state partially restored, our prologue derived unwind information
   is no longer valid.

   This function then, aims to spot instruction sequences like this:

     ld     fp, IMM_1(sp)
     add    sp, sp, IMM_2
     ret

   The first instruction restores the previous frame-pointer value, the
   second restores the previous stack pointer value, and the final
   instruction is the actual return.

   We need to consider that some or all of these instructions might be
   compressed.

   This function makes the assumption that, when the inferior reaches the
   'ret' instruction the stack pointer will have been restored to its value
   on entry to this function.  This assumption will be true in most well
   formed programs.

   Return true if we detect that we are in such an instruction sequence,
   that is PC points at one of the three instructions given above.  In this
   case, set *OFFSET to IMM_2 if PC points to either of the first
   two instructions (the 'ld' or 'add'), otherwise set *OFFSET to 0.

   Otherwise, this function returns false, and the contents of *OFFSET are
   undefined.  */

static bool
riscv_detect_end_of_function (struct gdbarch *gdbarch, CORE_ADDR pc,
			      int *offset)
{
  *offset = 0;

  /* We only want to scan a maximum of 3 instructions.  */
  for (int i = 0; i < 3; ++i)
    {
      struct riscv_insn insn;
      insn.decode (gdbarch, pc);
      gdb_assert (insn.length () > 0);

      if (is_insn_load_of_fp_from_sp (insn))
	{
	  riscv_unwinder_debug_printf ("found 'ld' instruction at %s",
				       core_addr_to_string (pc));
	  if (i > 0)
	    return false;
	  pc += insn.length ();
	}
      else if (is_insn_addi_of_sp_to_sp (insn))
	{
	  riscv_unwinder_debug_printf ("found 'add' instruction at %s",
				       core_addr_to_string (pc));
	  if (i > 1)
	    return false;
	  if (i == 0)
	    {
	      if (!previous_insn_is_load_fp_from_stack (gdbarch, pc))
		return false;

	      i = 1;
	    }
	  *offset = insn.imm_signed ();
	  pc += insn.length ();
	}
      else if (insn.opcode () == riscv_insn::JALR
	       && insn.rs1 () == RISCV_RA_REGNUM
	       && insn.rs2 () == RISCV_ZERO_REGNUM)
	{
	  riscv_unwinder_debug_printf ("found 'ret' instruction at %s",
				       core_addr_to_string (pc));
	  gdb_assert (i != 1);
	  if (i == 0)
	    {
	      CORE_ADDR prev_pc;
	      if (!previous_insn_is_add_imm_to_sp (gdbarch, pc, &prev_pc))
		return false;
	      if (!previous_insn_is_load_fp_from_stack (gdbarch, prev_pc))
		return false;
	      i = 2;
	    }

	  pc += insn.length ();
	}
      else
	return false;
    }

  return true;
}

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

  riscv_unwinder_debug_printf ("function starting at %s (limit %s)",
			       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 (is_insn_addi_of_sp_to_sp (insn))
	{
	  /* 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
	       || insn.opcode () == riscv_insn::LI)
	{
	  /* Handle: lui REG, n
	     or:     li  REG, n  */
	  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;

  riscv_unwinder_debug_printf ("end of prologue at %s",
			       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;
	}

      /* Check to see if we are located near to a return instruction in
	 this function.  If we are then the one or both of the stack
	 pointer and frame pointer may have been restored to their previous
	 value.  If we can spot this situation then we can adjust which
	 register and offset we use for the frame base.  */
      if (cache->frame_base_reg != RISCV_SP_REGNUM
	  || cache->frame_base_offset != 0)
	{
	  int sp_offset;

	  if (riscv_detect_end_of_function (gdbarch, original_end_pc,
					    &sp_offset))
	    {
	      riscv_unwinder_debug_printf
		("in function epilogue at %s, stack offset is %d",
		 core_addr_to_string (original_end_pc), sp_offset);
	      cache->frame_base_reg= RISCV_SP_REGNUM;
	      cache->frame_base_offset = sp_offset;
	    }
	}

      /* 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))
	    {
	      /* 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.  */
	      riscv_unwinder_debug_printf ("register $%s at stack offset %s",
					   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));

  riscv_infcall_debug_printf ("writing %s-byte nop instruction to %s: %s",
			      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 (TYPE_HAS_DYNAMIC_LENGTH (ainfo->type)
      || 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:
      if (!TYPE_HAS_DYNAMIC_LENGTH (ainfo->type))
	{
	  riscv_call_arg_struct (ainfo, cinfo);
	  break;
	}
      [[fallthrough]];

    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 (function->type ());

  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 (arg_value->type ());

      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 = arg_value->contents ().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)
    {
      RISCV_INFCALL_SCOPED_DEBUG_START_END ("dummy call args");
      riscv_infcall_debug_printf ("floating point ABI %s in use",
				  (riscv_has_fp_abi (gdbarch)
				   ? "is" : "is not"));
      riscv_infcall_debug_printf ("xlen: %d", call_info.xlen);
      riscv_infcall_debug_printf ("flen: %d", call_info.flen);
      if (return_method == return_method_struct)
	riscv_infcall_debug_printf
	  ("[**] struct return pointer in register $A0");
      for (i = 0; i < nargs; ++i)
	{
	  struct riscv_arg_info *info = &arg_info [i];
	  string_file tmp;

	  riscv_print_arg_location (&tmp, gdbarch, info, sp_refs, sp_args);
	  riscv_infcall_debug_printf ("[%2d] %s", i, tmp.string ().c_str ());
	}
      if (call_info.memory.arg_offset > 0
	  || call_info.memory.ref_offset > 0)
	{
	  riscv_infcall_debug_printf ("              Original sp: %s",
				      core_addr_to_string (osp));
	  riscv_infcall_debug_printf ("Stack required (for args): 0x%x",
				      call_info.memory.arg_offset);
	  riscv_infcall_debug_printf ("Stack required (for refs): 0x%x",
				      call_info.memory.ref_offset);
	  riscv_infcall_debug_printf ("          Stack allocated: %s",
				      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.  */

  riscv_infcall_debug_printf ("writing $ra = %s",
			      core_addr_to_string (bp_addr));
  regcache_cooked_write_unsigned (regcache, RISCV_RA_REGNUM, bp_addr);

  /* Finally, update the stack pointer.  */

  riscv_infcall_debug_printf ("writing $sp = %s", 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;

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

  if (riscv_debug_infcall)
    {
      string_file tmp;
      riscv_print_arg_location (&tmp, gdbarch, &info, 0, 0);
      riscv_infcall_debug_printf ("[R] %s", tmp.string ().c_str ());
    }

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

      /* We only do one thing at a time.  */
      gdb_assert (read_value == 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 = value::allocate (info.type);
	      unscaled.write (abi_val->contents_raw (),
			      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 = abi_val->contents_raw ().data ();
	}
      else
	{
	  abi_val = value::allocate (info.type);
	  readbuf = abi_val->contents_raw ().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 (read_value != nullptr)
	      {
		abi_val = value_at_non_lval (type, addr);
		/* Also reset the expected type, so that the cast
		   later on is a no-op.  If the cast is not a no-op,
		   and if the return type is variably-sized, then the
		   type of ABI_VAL will differ from ARG_TYPE due to
		   dynamic type resolution, and so will most likely
		   fail.  */
		arg_type = abi_val->type ();
	      }
	    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 (read_value != nullptr)
	{
	  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 (abi_val->contents (),
			     type_byte_order (info.type),
			     info.type->is_unsigned ());
	      *read_value = value::allocate (arg_type);
	      unscaled.write ((*read_value)->contents_raw (),
			      type_byte_order (arg_type),
			      arg_type->is_unsigned ());
	    }
	  else
	    *read_value = value_cast (arg_type, abi_val);
	}
    }

  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);
  riscv_unwinder_debug_printf ("frame base is %s ($%s + 0x%x)",
			       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)?";
}

/* Implementation of `gdbarch_stap_is_single_operand', as defined in
   gdbarch.h.  */

static int
riscv_stap_is_single_operand (struct gdbarch *gdbarch, const char *s)
{
  return (ISDIGIT (*s) /* Literal number.  */
	  || *s == '(' /* Register indirection.  */
	  || ISALPHA (*s)); /* Register value.  */
}

/* String that appears before a register name in a SystemTap register
   indirect expression.  */

static const char *const stap_register_indirection_prefixes[] =
{
  "(", nullptr
};

/* String that appears after a register name in a SystemTap register
   indirect expression.  */

static const char *const stap_register_indirection_suffixes[] =
{
  ")", nullptr
};

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

  riscv_gdbarch_debug_printf ("have got a target description");

  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)
    {
      riscv_gdbarch_debug_printf ("target description is not valid");
      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.  */
  gdbarch *gdbarch
    = gdbarch_alloc (&info, gdbarch_tdep_up (new riscv_gdbarch_tdep));
  riscv_gdbarch_tdep *tdep = gdbarch_tdep<riscv_gdbarch_tdep> (gdbarch);

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

  /* SystemTap Support.  */
  set_gdbarch_stap_is_single_operand (gdbarch, riscv_stap_is_single_operand);
  set_gdbarch_stap_register_indirection_prefixes
    (gdbarch, stap_register_indirection_prefixes);
  set_gdbarch_stap_register_indirection_suffixes
    (gdbarch, stap_register_indirection_suffixes);

  /* 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_boolean_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."),
			   nullptr,
			   show_riscv_debug_variable,
			   &setdebugriscvcmdlist, &showdebugriscvcmdlist);

  add_setshow_boolean_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."),
			   nullptr,
			   show_riscv_debug_variable,
			   &setdebugriscvcmdlist, &showdebugriscvcmdlist);

  add_setshow_boolean_cmd ("unwinder", class_maintenance,
			   &riscv_debug_unwinder,  _("\
Set riscv stack unwinding debugging."), _("\
Show riscv stack unwinding debugging."), _("\
When on, print debugging information for the riscv specific parts\n\
of the stack unwinding mechanism."),
			   nullptr,
			   show_riscv_debug_variable,
			   &setdebugriscvcmdlist, &showdebugriscvcmdlist);

  add_setshow_boolean_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."),
			   nullptr,
			   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);
}
