/* Target-dependent code for the AMDGPU architectures.

   Copyright (C) 2019-2024 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 "amd-dbgapi-target.h"
#include "amdgpu-tdep.h"
#include "arch-utils.h"
#include "disasm.h"
#include "dwarf2/frame.h"
#include "frame-unwind.h"
#include "gdbarch.h"
#include "gdbsupport/selftest.h"
#include "gdbtypes.h"
#include "inferior.h"
#include "producer.h"
#include "reggroups.h"

/* See amdgpu-tdep.h.  */

bool
is_amdgpu_arch (struct gdbarch *arch)
{
  gdb_assert (arch != nullptr);
  return gdbarch_bfd_arch_info (arch)->arch == bfd_arch_amdgcn;
}

/* See amdgpu-tdep.h.  */

amdgpu_gdbarch_tdep *
get_amdgpu_gdbarch_tdep (gdbarch *arch)
{
  return gdbarch_tdep<amdgpu_gdbarch_tdep> (arch);
}

/* Dummy implementation of gdbarch_return_value_as_value.  */

static return_value_convention
amdgpu_return_value_as_value (gdbarch *arch, value *function, type *valtype,
			      regcache *regcache, value **read_value,
			      const gdb_byte *writebuf)
{
  gdb_assert_not_reached ("not implemented");
}

/* Return the name of register REGNUM.  */

static const char *
amdgpu_register_name (struct gdbarch *gdbarch, int regnum)
{
  /* The list of registers reported by amd-dbgapi for a given architecture
     contains some duplicate names.  For instance, there is an "exec" register
     for waves in the wave32 mode and one for the waves in the wave64 mode.
     However, at most one register with a given name is actually allocated for
     a specific wave.  If INFERIOR_PTID represents a GPU wave, we query
     amd-dbgapi to know whether the requested register actually exists for the
     current wave, so there won't be duplicates in the the register names we
     report for that wave.

     But there are two known cases where INFERIOR_PTID doesn't represent a GPU
     wave:

      - The user does "set arch amdgcn:gfxNNN" followed with "maint print
	registers"
      - The "register_name" selftest

     In these cases, we can't query amd-dbgapi to know whether we should hide
     the register or not.  The "register_name" selftest checks that there aren't
     duplicates in the register names returned by the gdbarch, so if we simply
     return all register names, that test will fail.  The other simple option is
     to never return a register name, which is what we do here.  */
  if (!ptid_is_gpu (inferior_ptid))
    return "";

  amd_dbgapi_wave_id_t wave_id = get_amd_dbgapi_wave_id (inferior_ptid);
  amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);

  amd_dbgapi_register_exists_t register_exists;
  if (amd_dbgapi_wave_register_exists (wave_id, tdep->register_ids[regnum],
				       &register_exists)
	!= AMD_DBGAPI_STATUS_SUCCESS
      || register_exists != AMD_DBGAPI_REGISTER_PRESENT)
    return "";

  return tdep->register_names[regnum].c_str ();
}

/* Return the internal register number for the DWARF register number DWARF_REG.

   Return -1 if there's no internal register mapping to DWARF_REG.  */

static int
amdgpu_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int dwarf_reg)
{
  amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);

  if (dwarf_reg < tdep->dwarf_regnum_to_gdb_regnum.size ())
    return tdep->dwarf_regnum_to_gdb_regnum[dwarf_reg];

  return -1;
}

/* A hierarchy of classes to represent an amd-dbgapi register type.  */

struct amd_dbgapi_register_type
{
  enum class kind
    {
      INTEGER,
      FLOAT,
      DOUBLE,
      VECTOR,
      CODE_PTR,
      FLAGS,
      ENUM,
    };

  amd_dbgapi_register_type (kind kind, std::string lookup_name)
    : m_kind (kind), m_lookup_name (std::move (lookup_name))
  {}

  virtual ~amd_dbgapi_register_type () = default;

  /* Return the type's kind.  */
  kind kind () const
  { return m_kind; }

  /* Name to use for this type in the existing type map.  */
  const std::string &lookup_name () const
  { return m_lookup_name; }

private:
  enum kind m_kind;
  std::string m_lookup_name;
};

using amd_dbgapi_register_type_up = std::unique_ptr<amd_dbgapi_register_type>;

struct amd_dbgapi_register_type_integer : public amd_dbgapi_register_type
{
  amd_dbgapi_register_type_integer (bool is_unsigned, unsigned int bit_size)
    : amd_dbgapi_register_type
	(kind::INTEGER,
	 string_printf ("%sint%d", is_unsigned ? "u" : "", bit_size)),
      m_is_unsigned (is_unsigned),
      m_bit_size (bit_size)
  {}

  bool is_unsigned () const
  { return m_is_unsigned; }

  unsigned int bit_size () const
  { return m_bit_size; }

private:
  bool m_is_unsigned;
  unsigned int m_bit_size;
};

struct amd_dbgapi_register_type_float : public amd_dbgapi_register_type
{
  amd_dbgapi_register_type_float ()
    : amd_dbgapi_register_type (kind::FLOAT, "float")
  {}
};

struct amd_dbgapi_register_type_double : public amd_dbgapi_register_type
{
  amd_dbgapi_register_type_double ()
    : amd_dbgapi_register_type (kind::DOUBLE, "double")
  {}
};

struct amd_dbgapi_register_type_vector : public amd_dbgapi_register_type
{
  amd_dbgapi_register_type_vector (const amd_dbgapi_register_type &element_type,
				   unsigned int count)
    : amd_dbgapi_register_type (kind::VECTOR,
				make_lookup_name (element_type, count)),
      m_element_type (element_type),
      m_count (count)
  {}

  const amd_dbgapi_register_type &element_type () const
  { return m_element_type; }

  unsigned int count () const
  { return m_count; }

  static std::string make_lookup_name
    (const amd_dbgapi_register_type &element_type, unsigned int count)
  {
    return string_printf ("%s[%d]", element_type.lookup_name ().c_str (),
			  count);
  }

private:
  const amd_dbgapi_register_type &m_element_type;
  unsigned int m_count;
};

struct amd_dbgapi_register_type_code_ptr : public amd_dbgapi_register_type
{
  amd_dbgapi_register_type_code_ptr ()
    : amd_dbgapi_register_type (kind::CODE_PTR, "void (*)()")
  {}
};

struct amd_dbgapi_register_type_flags : public amd_dbgapi_register_type
{
  struct field
  {
    std::string name;
    unsigned int bit_pos_start;
    unsigned int bit_pos_end;
    const amd_dbgapi_register_type *type;
  };

  using container_type = std::vector<field>;
  using const_iterator_type = container_type::const_iterator;

  amd_dbgapi_register_type_flags (unsigned int bit_size, std::string_view name)
    : amd_dbgapi_register_type (kind::FLAGS,
				make_lookup_name (bit_size, name)),
      m_bit_size (bit_size),
      m_name (std::move (name))
  {}

  unsigned int bit_size () const
  { return m_bit_size; }

  void add_field (std::string name, unsigned int bit_pos_start,
		  unsigned int bit_pos_end,
		  const amd_dbgapi_register_type *type)
  {
    m_fields.push_back (field {std::move (name), bit_pos_start,
			       bit_pos_end, type});
  }

  container_type::size_type size () const
  { return m_fields.size (); }

  const field &operator[] (container_type::size_type pos) const
  { return m_fields[pos]; }

  const_iterator_type begin () const
  { return m_fields.begin (); }

  const_iterator_type end () const
  { return m_fields.end (); }

  const std::string &name () const
  { return m_name; }

  static std::string make_lookup_name (int bits, std::string_view name)
  {
    std::string res = string_printf ("flags%d_t ", bits);
    res.append (name.data (), name.size ());
    return res;
  }

private:
  unsigned int m_bit_size;
  container_type m_fields;
  std::string m_name;
};

using amd_dbgapi_register_type_flags_up
  = std::unique_ptr<amd_dbgapi_register_type_flags>;

struct amd_dbgapi_register_type_enum : public amd_dbgapi_register_type
{
  struct enumerator
  {
    std::string name;
    ULONGEST value;
  };

  using container_type = std::vector<enumerator>;
  using const_iterator_type = container_type::const_iterator;

  amd_dbgapi_register_type_enum (std::string_view name)
    : amd_dbgapi_register_type (kind::ENUM, make_lookup_name (name)),
      m_name (name.data (), name.length ())
  {}

  void set_bit_size (int bit_size)
  { m_bit_size = bit_size; }

  unsigned int bit_size () const
  { return m_bit_size; }

  void add_enumerator (std::string name, ULONGEST value)
  { m_enumerators.push_back (enumerator {std::move (name), value}); }

  container_type::size_type size () const
  { return m_enumerators.size (); }

  const enumerator &operator[] (container_type::size_type pos) const
  { return m_enumerators[pos]; }

  const_iterator_type begin () const
  { return m_enumerators.begin (); }

  const_iterator_type end () const
  { return m_enumerators.end (); }

  const std::string &name () const
  { return m_name; }

  static std::string make_lookup_name (std::string_view name)
  {
    std::string res = "enum ";
    res.append (name.data (), name.length ());
    return res;
  }

private:
  unsigned int m_bit_size = 32;
  container_type m_enumerators;
  std::string m_name;
};

using amd_dbgapi_register_type_enum_up
  = std::unique_ptr<amd_dbgapi_register_type_enum>;

/* Map type lookup names to types.  */
using amd_dbgapi_register_type_map
  = std::unordered_map<std::string, amd_dbgapi_register_type_up>;

/* Parse S as a ULONGEST, raise an error on overflow.  */

static ULONGEST
try_strtoulst (std::string_view s)
{
  errno = 0;
  ULONGEST value = strtoulst (s.data (), nullptr, 0);
  if (errno != 0)
    error (_("Failed to parse integer."));

  return value;
};

/* Shared regex bits.  */
#define IDENTIFIER "[A-Za-z0-9_.]+"
#define WS "[ \t]+"
#define WSOPT "[ \t]*"

static const amd_dbgapi_register_type &
parse_amd_dbgapi_register_type (std::string_view type_name,
				amd_dbgapi_register_type_map &type_map);


/* parse_amd_dbgapi_register_type helper for enum types.  */

static void
parse_amd_dbgapi_register_type_enum_fields
  (amd_dbgapi_register_type_enum &enum_type, std::string_view fields)
{
  compiled_regex regex (/* name */
			"^(" IDENTIFIER ")"
			WSOPT "=" WSOPT
			/* value */
			"([0-9]+)"
			WSOPT "(," WSOPT ")?",
			REG_EXTENDED,
			_("Error in AMDGPU enum register type regex"));
  regmatch_t matches[4];

  while (!fields.empty ())
    {
      int res = regex.exec (fields.data (), ARRAY_SIZE (matches), matches, 0);
      if (res == REG_NOMATCH)
	error (_("Failed to parse enum fields"));

      auto sv_from_match = [fields] (const regmatch_t &m)
	{ return fields.substr (m.rm_so, m.rm_eo - m.rm_so); };

      std::string_view name = sv_from_match (matches[1]);
      std::string_view value_str = sv_from_match (matches[2]);
      ULONGEST value = try_strtoulst (value_str);

      if (value > std::numeric_limits<uint32_t>::max ())
	enum_type.set_bit_size (64);

      enum_type.add_enumerator (std::string (name), value);

      fields = fields.substr (matches[0].rm_eo);
    }
}

/* parse_amd_dbgapi_register_type helper for flags types.  */

static void
parse_amd_dbgapi_register_type_flags_fields
  (amd_dbgapi_register_type_flags &flags_type,
   int bits, std::string_view name, std::string_view fields,
   amd_dbgapi_register_type_map &type_map)
{
  gdb_assert (bits == 32 || bits == 64);

  std::string regex_str
    = string_printf (/* type */
		     "^(bool|uint%d_t|enum" WS IDENTIFIER WSOPT "(\\{[^}]*})?)"
		     WS
		     /* name */
		     "(" IDENTIFIER ")" WSOPT
		     /* bit position */
		     "@([0-9]+)(-[0-9]+)?" WSOPT ";" WSOPT,
		     bits);
  compiled_regex regex (regex_str.c_str (), REG_EXTENDED,
			_("Error in AMDGPU register type flags fields regex"));
  regmatch_t matches[6];

  while (!fields.empty ())
    {
      int res = regex.exec (fields.data (), ARRAY_SIZE (matches), matches, 0);
      if (res == REG_NOMATCH)
	error (_("Failed to parse flags type fields string"));

      auto sv_from_match = [fields] (const regmatch_t &m)
	{ return fields.substr (m.rm_so, m.rm_eo - m.rm_so); };

      std::string_view field_type_str = sv_from_match (matches[1]);
      std::string_view field_name = sv_from_match (matches[3]);
      std::string_view pos_begin_str = sv_from_match (matches[4]);
      ULONGEST pos_begin = try_strtoulst (pos_begin_str);

      if (field_type_str == "bool")
	flags_type.add_field (std::string (field_name), pos_begin, pos_begin,
			      nullptr);
      else
	{
	  if (matches[5].rm_so == -1)
	    error (_("Missing end bit position"));

	  std::string_view pos_end_str = sv_from_match (matches[5]);
	  ULONGEST pos_end = try_strtoulst (pos_end_str.substr (1));
	  const amd_dbgapi_register_type &field_type
	    = parse_amd_dbgapi_register_type (field_type_str, type_map);
	  flags_type.add_field (std::string (field_name), pos_begin, pos_end,
				&field_type);
	}

      fields = fields.substr (matches[0].rm_eo);
    }
}

/* parse_amd_dbgapi_register_type helper for scalars.  */

static const amd_dbgapi_register_type &
parse_amd_dbgapi_register_type_scalar (std::string_view name,
				       amd_dbgapi_register_type_map &type_map)
{
  std::string name_str (name);
  auto it = type_map.find (name_str);
  if (it != type_map.end ())
    {
      enum amd_dbgapi_register_type::kind kind = it->second->kind ();
      if (kind != amd_dbgapi_register_type::kind::INTEGER
	  && kind != amd_dbgapi_register_type::kind::FLOAT
	  && kind != amd_dbgapi_register_type::kind::DOUBLE
	  && kind != amd_dbgapi_register_type::kind::CODE_PTR)
	error (_("type mismatch"));

      return *it->second;
    }

  amd_dbgapi_register_type_up type;
  if (name == "int32_t")
    type.reset (new amd_dbgapi_register_type_integer (false, 32));
  else if (name == "uint32_t")
    type.reset (new amd_dbgapi_register_type_integer (true, 32));
  else if (name == "int64_t")
    type.reset (new amd_dbgapi_register_type_integer (false, 64));
  else if (name == "uint64_t")
    type.reset (new amd_dbgapi_register_type_integer (true, 64));
  else if (name == "float")
    type.reset (new amd_dbgapi_register_type_float ());
  else if (name == "double")
    type.reset (new amd_dbgapi_register_type_double ());
  else if (name == "void (*)()")
    type.reset (new amd_dbgapi_register_type_code_ptr ());
  else
    error (_("unknown type %s"), name_str.c_str ());

  auto insertion_pair = type_map.emplace (name, std::move (type));
  return *insertion_pair.first->second;
}

/* Parse an amd-dbgapi register type string into an amd_dbgapi_register_type
   object.

   See the documentation of AMD_DBGAPI_REGISTER_INFO_TYPE in amd-dbgapi.h for
   details about the format.  */

static const amd_dbgapi_register_type &
parse_amd_dbgapi_register_type (std::string_view type_str,
				amd_dbgapi_register_type_map &type_map)
{
  size_t pos_open_bracket = type_str.find_last_of ('[');
  auto sv_from_match = [type_str] (const regmatch_t &m)
    { return type_str.substr (m.rm_so, m.rm_eo - m.rm_so); };

  if (pos_open_bracket != std::string_view::npos)
    {
      /* Vector types.  */
      std::string_view element_type_str
	= type_str.substr (0, pos_open_bracket);
      const amd_dbgapi_register_type &element_type
	= parse_amd_dbgapi_register_type (element_type_str, type_map);

      size_t pos_close_bracket = type_str.find_last_of (']');
      gdb_assert (pos_close_bracket != std::string_view::npos);
      std::string_view count_str_view
	= type_str.substr (pos_open_bracket + 1,
			    pos_close_bracket - pos_open_bracket);
      std::string count_str (count_str_view);
      unsigned int count = std::stoul (count_str);

      std::string lookup_name
	= amd_dbgapi_register_type_vector::make_lookup_name (element_type, count);
      auto existing_type_it = type_map.find (lookup_name);
      if (existing_type_it != type_map.end ())
	{
	  gdb_assert (existing_type_it->second->kind ()
		      == amd_dbgapi_register_type::kind::VECTOR);
	  return *existing_type_it->second;
	}

      amd_dbgapi_register_type_up type
	(new amd_dbgapi_register_type_vector (element_type, count));
      auto insertion_pair
	= type_map.emplace (type->lookup_name (), std::move (type));
      return *insertion_pair.first->second;
    }

  if (type_str.find ("flags32_t") == 0 || type_str.find ("flags64_t") == 0)
    {
      /* Split 'type_str' into 4 tokens: "(type) (name) ({ (fields) })".  */
      compiled_regex regex ("^(flags32_t|flags64_t)"
			    WS "(" IDENTIFIER ")" WSOPT
			    "(\\{" WSOPT "(.*)})?",
			    REG_EXTENDED,
			    _("Error in AMDGPU register type regex"));

      regmatch_t matches[5];
      int res = regex.exec (type_str.data (), ARRAY_SIZE (matches), matches, 0);
      if (res == REG_NOMATCH)
	error (_("Failed to parse flags type string"));

      std::string_view flags_keyword = sv_from_match (matches[1]);
      unsigned int bit_size = flags_keyword == "flags32_t" ? 32 : 64;
      std::string_view name = sv_from_match (matches[2]);
      std::string lookup_name
	= amd_dbgapi_register_type_flags::make_lookup_name (bit_size, name);
      auto existing_type_it = type_map.find (lookup_name);

      if (matches[3].rm_so == -1)
	{
	  /* No braces, lookup existing type.  */
	  if (existing_type_it == type_map.end ())
	    error (_("reference to unknown type %s."),
		   std::string (name).c_str ());

	  if (existing_type_it->second->kind ()
	      != amd_dbgapi_register_type::kind::FLAGS)
	    error (_("type mismatch"));

	  return *existing_type_it->second;
	}
      else
	{
	  /* With braces, it's a definition.  */
	  if (existing_type_it != type_map.end ())
	    error (_("re-definition of type %s."),
		   std::string (name).c_str ());

	  amd_dbgapi_register_type_flags_up flags_type
	    (new amd_dbgapi_register_type_flags (bit_size, name));
	  std::string_view fields_without_braces = sv_from_match (matches[4]);

	  parse_amd_dbgapi_register_type_flags_fields
	    (*flags_type, bit_size, name, fields_without_braces, type_map);

	  auto insertion_pair
	    = type_map.emplace (flags_type->lookup_name (),
				std::move (flags_type));
	  return *insertion_pair.first->second;
	}
    }

  if (type_str.find ("enum") == 0)
    {
      compiled_regex regex ("^enum" WS "(" IDENTIFIER ")" WSOPT "(\\{" WSOPT "([^}]*)})?",
			    REG_EXTENDED,
			    _("Error in AMDGPU register type enum regex"));

      /* Split 'type_name' into 3 tokens: "(name) ( { (fields) } )".  */
      regmatch_t matches[4];
      int res = regex.exec (type_str.data (), ARRAY_SIZE (matches), matches, 0);
      if (res == REG_NOMATCH)
	error (_("Failed to parse flags type string"));

      std::string_view name = sv_from_match (matches[1]);

      std::string lookup_name
	= amd_dbgapi_register_type_enum::make_lookup_name (name);
      auto existing_type_it = type_map.find (lookup_name);

      if (matches[2].rm_so == -1)
	{
	  /* No braces, lookup existing type.  */
	  if (existing_type_it == type_map.end ())
	    error (_("reference to unknown type %s"),
		   std::string (name).c_str ());

	  if (existing_type_it->second->kind ()
	      != amd_dbgapi_register_type::kind::ENUM)
	    error (_("type mismatch"));

	  return *existing_type_it->second;
	}
      else
	{
	  /* With braces, it's a definition.  */
	  if (existing_type_it != type_map.end ())
	    error (_("re-definition of type %s"),
		   std::string (name).c_str ());

	  amd_dbgapi_register_type_enum_up enum_type
	    (new amd_dbgapi_register_type_enum (name));
	  std::string_view fields_without_braces = sv_from_match (matches[3]);

	  parse_amd_dbgapi_register_type_enum_fields
	    (*enum_type, fields_without_braces);

	  auto insertion_pair
	    = type_map.emplace (enum_type->lookup_name (),
				std::move (enum_type));
	  return *insertion_pair.first->second;
	}
    }

  return parse_amd_dbgapi_register_type_scalar (type_str, type_map);
}

/* Convert an amd_dbgapi_register_type object to a GDB type.  */

static type *
amd_dbgapi_register_type_to_gdb_type (const amd_dbgapi_register_type &type,
				      struct gdbarch *gdbarch)
{
  switch (type.kind ())
    {
    case amd_dbgapi_register_type::kind::INTEGER:
      {
	const auto &integer_type
	  = gdb::checked_static_cast<const amd_dbgapi_register_type_integer &>
	      (type);
	switch (integer_type.bit_size ())
	  {
	  case 32:
	    if (integer_type.is_unsigned ())
	      return builtin_type (gdbarch)->builtin_uint32;
	    else
	      return builtin_type (gdbarch)->builtin_int32;

	  case 64:
	    if (integer_type.is_unsigned ())
	      return builtin_type (gdbarch)->builtin_uint64;
	    else
	      return builtin_type (gdbarch)->builtin_int64;

	  default:
	    gdb_assert_not_reached ("invalid bit size");
	  }
      }

    case amd_dbgapi_register_type::kind::VECTOR:
      {
	const auto &vector_type
	  = gdb::checked_static_cast<const amd_dbgapi_register_type_vector &>
	      (type);
	struct type *element_type
	  = amd_dbgapi_register_type_to_gdb_type (vector_type.element_type (),
						  gdbarch);
	return init_vector_type (element_type, vector_type.count ());
      }

    case amd_dbgapi_register_type::kind::FLOAT:
      return builtin_type (gdbarch)->builtin_float;

    case amd_dbgapi_register_type::kind::DOUBLE:
      return builtin_type (gdbarch)->builtin_double;

    case amd_dbgapi_register_type::kind::CODE_PTR:
      return builtin_type (gdbarch)->builtin_func_ptr;

    case amd_dbgapi_register_type::kind::FLAGS:
      {
	const auto &flags_type
	  = gdb::checked_static_cast<const amd_dbgapi_register_type_flags &>
	      (type);
	struct type *gdb_type
	  = arch_flags_type (gdbarch, flags_type.name ().c_str (),
			     flags_type.bit_size ());

	for (const auto &field : flags_type)
	  {
	    if (field.type == nullptr)
	      {
		gdb_assert (field.bit_pos_start == field.bit_pos_end);
		append_flags_type_flag (gdb_type, field.bit_pos_start,
					field.name.c_str ());
	      }
	    else
	      {
		struct type *field_type
		  = amd_dbgapi_register_type_to_gdb_type (*field.type, gdbarch);
		gdb_assert (field_type != nullptr);
		append_flags_type_field
		  (gdb_type, field.bit_pos_start,
		   field.bit_pos_end - field.bit_pos_start + 1,
		   field_type, field.name.c_str ());
	      }
	  }

	return gdb_type;
      }

    case amd_dbgapi_register_type::kind::ENUM:
      {
	const auto &enum_type
	  = gdb::checked_static_cast<const amd_dbgapi_register_type_enum &>
	      (type);
	struct type *gdb_type
	  = (type_allocator (gdbarch)
	     .new_type (TYPE_CODE_ENUM, enum_type.bit_size (),
			enum_type.name ().c_str ()));

	gdb_type->alloc_fields (enum_type.size ());
	gdb_type->set_is_unsigned (true);

	for (size_t i = 0; i < enum_type.size (); ++i)
	  {
	    const auto &field = enum_type[i];
	    gdb_type->field (i).set_name (xstrdup (field.name.c_str ()));
	    gdb_type->field (i).set_loc_enumval (field.value);
	  }

	return gdb_type;
      }

    default:
      gdb_assert_not_reached ("unhandled amd_dbgapi_register_type kind");
    }
}

static type *
amdgpu_register_type (struct gdbarch *gdbarch, int regnum)
{
  amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);

  if (tdep->register_types[regnum] == nullptr)
    {
      /* This is done lazily (not at gdbarch initialization time), because it
	 requires access to builtin_type, which can't be used while the gdbarch
	 is not fully initialized.  */
      char *bytes;
      amd_dbgapi_status_t status
	= amd_dbgapi_register_get_info (tdep->register_ids[regnum],
					AMD_DBGAPI_REGISTER_INFO_TYPE,
					sizeof (bytes), &bytes);
      if (status != AMD_DBGAPI_STATUS_SUCCESS)
	error (_("Failed to get register type from amd-dbgapi"));

      gdb::unique_xmalloc_ptr<char> bytes_holder (bytes);
      amd_dbgapi_register_type_map type_map;
      const amd_dbgapi_register_type &register_type
	= parse_amd_dbgapi_register_type (bytes, type_map);
      tdep->register_types[regnum]
	= amd_dbgapi_register_type_to_gdb_type (register_type, gdbarch);
      gdb_assert (tdep->register_types[regnum] != nullptr);
    }

  return tdep->register_types[regnum];
}

static int
amdgpu_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
			    const reggroup *group)
{
  amdgpu_gdbarch_tdep *tdep = get_amdgpu_gdbarch_tdep (gdbarch);

  auto it = tdep->register_class_map.find (group->name ());
  if (it == tdep->register_class_map.end ())
    return group == all_reggroup;

  amd_dbgapi_register_class_state_t state;
  if (amd_dbgapi_register_is_in_register_class (it->second,
						tdep->register_ids[regnum],
						&state)
      != AMD_DBGAPI_STATUS_SUCCESS)
    return group == all_reggroup;

  return (state == AMD_DBGAPI_REGISTER_CLASS_STATE_MEMBER
	  || group == all_reggroup);
}

static int
amdgpu_breakpoint_kind_from_pc (struct gdbarch *gdbarch, CORE_ADDR *)
{
  return get_amdgpu_gdbarch_tdep (gdbarch)->breakpoint_instruction_size;
}

static const gdb_byte *
amdgpu_sw_breakpoint_from_kind (struct gdbarch *gdbarch, int kind, int *size)
{
  *size = kind;
  return get_amdgpu_gdbarch_tdep (gdbarch)->breakpoint_instruction_bytes.get ();
}

struct amdgpu_frame_cache
{
  CORE_ADDR base;
  CORE_ADDR pc;
};

static amdgpu_frame_cache *
amdgpu_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  if (*this_cache != nullptr)
    return (struct amdgpu_frame_cache *) *this_cache;

  struct amdgpu_frame_cache *cache
    = FRAME_OBSTACK_ZALLOC (struct amdgpu_frame_cache);
  (*this_cache) = cache;

  cache->pc = get_frame_func (this_frame);
  cache->base = 0;

  return cache;
}

static void
amdgpu_frame_this_id (const frame_info_ptr &this_frame, void **this_cache,
		      frame_id *this_id)
{
  struct amdgpu_frame_cache *cache
    = amdgpu_frame_cache (this_frame, this_cache);

  if (get_frame_type (this_frame) == INLINE_FRAME)
    (*this_id) = frame_id_build (cache->base, cache->pc);
  else
    (*this_id) = outer_frame_id;

  frame_debug_printf ("this_frame=%d, type=%d, this_id=%s",
		      frame_relative_level (this_frame),
		      get_frame_type (this_frame),
		      this_id->to_string ().c_str ());
}

static frame_id
amdgpu_dummy_id (struct gdbarch *gdbarch, const frame_info_ptr &this_frame)
{
  return frame_id_build (0, get_frame_pc (this_frame));
}

static struct value *
amdgpu_frame_prev_register (const frame_info_ptr &this_frame, void **this_cache,
			    int regnum)
{
  return frame_unwind_got_register (this_frame, regnum, regnum);
}

static const frame_unwind_legacy amdgpu_frame_unwind (
  "amdgpu",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  default_frame_unwind_stop_reason,
  amdgpu_frame_this_id,
  amdgpu_frame_prev_register,
  nullptr,
  default_frame_sniffer,
  nullptr,
  nullptr
);

static int
print_insn_amdgpu (bfd_vma memaddr, struct disassemble_info *info)
{
  gdb_disassemble_info *di
    = static_cast<gdb_disassemble_info *> (info->application_data);

  /* Try to read at most INSTRUCTION_SIZE bytes.  */

  amd_dbgapi_size_t instruction_size = gdbarch_max_insn_length (di->arch ());
  gdb::byte_vector buffer (instruction_size);

  /* read_memory_func doesn't support partial reads, so if the read
     fails, try one byte less, on and on until we manage to read
     something.  A case where this would happen is if we're trying to
     read the last instruction at the end of a file section and that
     instruction is smaller than the largest instruction.  */
  while (instruction_size > 0)
    {
      int ret = info->read_memory_func (memaddr, buffer.data (),
					instruction_size, info);
      if (ret == 0)
	break;

      --instruction_size;
    }

  if (instruction_size == 0)
    {
      info->memory_error_func (-1, memaddr, info);
      return -1;
    }

  amd_dbgapi_architecture_id_t architecture_id;
  amd_dbgapi_status_t status
    = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (di->arch ())->mach,
				   &architecture_id);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    return -1;

  auto symbolizer = [] (amd_dbgapi_symbolizer_id_t symbolizer_id,
			amd_dbgapi_global_address_t address,
			char **symbol_text) -> amd_dbgapi_status_t
  {
    gdb_disassemble_info *disasm_info
      = reinterpret_cast<gdb_disassemble_info *> (symbolizer_id);
    gdb_printing_disassembler *disasm
      = dynamic_cast<gdb_printing_disassembler *> (disasm_info);
    gdb_assert (disasm != nullptr);

    string_file string (disasm->stream ()->can_emit_style_escape ());
    print_address (disasm->arch (), address, &string);
    *symbol_text = xstrdup (string.c_str ());

    return AMD_DBGAPI_STATUS_SUCCESS;
  };
  auto symbolizer_id = reinterpret_cast<amd_dbgapi_symbolizer_id_t> (di);
  char *instruction_text = nullptr;
  status = amd_dbgapi_disassemble_instruction (architecture_id, memaddr,
					       &instruction_size,
					       buffer.data (),
					       &instruction_text,
					       symbolizer_id,
					       symbolizer);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    {
      size_t alignment;
      status = amd_dbgapi_architecture_get_info
	(architecture_id,
	 AMD_DBGAPI_ARCHITECTURE_INFO_MINIMUM_INSTRUCTION_ALIGNMENT,
	 sizeof (alignment), &alignment);
      if (status != AMD_DBGAPI_STATUS_SUCCESS)
	error (_("amd_dbgapi_architecture_get_info failed"));

      info->fprintf_func (di, "<illegal instruction>");

      /* Skip to the next valid instruction address.  */
      return align_up (memaddr + 1, alignment) - memaddr;
    }

  /* Print the instruction.  */
  info->fprintf_func (di, "%s", instruction_text);

  /* Free the memory allocated by the amd-dbgapi.  */
  xfree (instruction_text);

  return static_cast<int> (instruction_size);
}

static CORE_ADDR
amdgpu_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_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 (start_pc, nullptr, &func_addr, nullptr))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr);

      /* Clang always emits a line note before the prologue and another
	 one after.  We trust clang to emit usable line notes.  */
      if (post_prologue_pc != 0
	  && cust != nullptr
	  && cust->producer () != nullptr
	  && producer_is_llvm (cust->producer ()))
	return std::max (start_pc, post_prologue_pc);
    }

  return start_pc;
}

static bool
amdgpu_supports_arch_info (const struct bfd_arch_info *info)
{
  amd_dbgapi_architecture_id_t architecture_id;
  amd_dbgapi_status_t status
    = amd_dbgapi_get_architecture (info->mach, &architecture_id);

  gdb_assert (status != AMD_DBGAPI_STATUS_ERROR_NOT_INITIALIZED);
  return status == AMD_DBGAPI_STATUS_SUCCESS;
}

static struct gdbarch *
amdgpu_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
{
  /* If there is already a candidate, use it.  */
  arches = gdbarch_list_lookup_by_info (arches, &info);
  if (arches != nullptr)
    return arches->gdbarch;

  /* Allocate space for the new architecture.  */
  gdbarch_up gdbarch_u
    (gdbarch_alloc (&info, gdbarch_tdep_up (new amdgpu_gdbarch_tdep)));
  gdbarch *gdbarch = gdbarch_u.get ();
  amdgpu_gdbarch_tdep *tdep = gdbarch_tdep<amdgpu_gdbarch_tdep> (gdbarch);

  /* Data types.  */
  set_gdbarch_char_signed (gdbarch, 0);
  set_gdbarch_ptr_bit (gdbarch, 64);
  set_gdbarch_addr_bit (gdbarch, 64);
  set_gdbarch_short_bit (gdbarch, 16);
  set_gdbarch_int_bit (gdbarch, 32);
  set_gdbarch_long_bit (gdbarch, 64);
  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_half_format (gdbarch, floatformats_ieee_half);
  set_gdbarch_float_format (gdbarch, floatformats_ieee_single);
  set_gdbarch_double_format (gdbarch, floatformats_ieee_double);
  set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double);

  /* Frame interpretation.  */
  set_gdbarch_skip_prologue (gdbarch, amdgpu_skip_prologue);
  set_gdbarch_inner_than (gdbarch, core_addr_greaterthan);
  dwarf2_append_unwinders (gdbarch);
  frame_unwind_append_unwinder (gdbarch, &amdgpu_frame_unwind);
  set_gdbarch_dummy_id (gdbarch, amdgpu_dummy_id);

  /* Registers and memory.  */
  amd_dbgapi_architecture_id_t architecture_id;
  amd_dbgapi_status_t status
    = amd_dbgapi_get_architecture (gdbarch_bfd_arch_info (gdbarch)->mach,
				   &architecture_id);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    {
      warning (_("Failed to get architecture from amd-dbgapi"));
      return nullptr;
    }


  /* Add register groups.  */
  size_t register_class_count;
  amd_dbgapi_register_class_id_t *register_class_ids;
  status = amd_dbgapi_architecture_register_class_list (architecture_id,
							&register_class_count,
							&register_class_ids);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    {
      warning (_("Failed to get register class list from amd-dbgapi"));
      return nullptr;
    }

  gdb::unique_xmalloc_ptr<amd_dbgapi_register_class_id_t>
    register_class_ids_holder (register_class_ids);

  for (size_t i = 0; i < register_class_count; ++i)
    {
      char *bytes;
      status = amd_dbgapi_architecture_register_class_get_info
	(register_class_ids[i], AMD_DBGAPI_REGISTER_CLASS_INFO_NAME,
	 sizeof (bytes), &bytes);
      if (status != AMD_DBGAPI_STATUS_SUCCESS)
	{
	  warning (_("Failed to get register class name from amd-dbgapi"));
	  return nullptr;
	}

      gdb::unique_xmalloc_ptr<char> name (bytes);

      auto inserted = tdep->register_class_map.emplace (name.get (),
							register_class_ids[i]);
      gdb_assert (inserted.second);

      /* Avoid creating a user reggroup with the same name as some built-in
	 reggroup, such as "general", "system", "vector", etc.  */
      if (reggroup_find (gdbarch, name.get ()) != nullptr)
	continue;

      /* Allocate the reggroup in the gdbarch.  */
      reggroup_add
	(gdbarch, reggroup_gdbarch_new (gdbarch, name.get (), USER_REGGROUP));
    }

  /* Add registers. */
  size_t register_count;
  amd_dbgapi_register_id_t *register_ids;
  status = amd_dbgapi_architecture_register_list (architecture_id,
						  &register_count,
						  &register_ids);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    {
      warning (_("Failed to get register list from amd-dbgapi"));
      return nullptr;
    }

  gdb::unique_xmalloc_ptr<amd_dbgapi_register_id_t> register_ids_holder
    (register_ids);

  tdep->register_ids.insert (tdep->register_ids.end (), &register_ids[0],
			     &register_ids[register_count]);

  tdep->register_properties.resize (register_count,
				    AMD_DBGAPI_REGISTER_PROPERTY_NONE);
  for (size_t regnum = 0; regnum < register_count; ++regnum)
    {
      auto &register_properties = tdep->register_properties[regnum];
      if (amd_dbgapi_register_get_info (register_ids[regnum],
					AMD_DBGAPI_REGISTER_INFO_PROPERTIES,
					sizeof (register_properties),
					&register_properties)
	  != AMD_DBGAPI_STATUS_SUCCESS)
	{
	  warning (_("Failed to get register properties from amd-dbgapi"));
	  return nullptr;
	}
    }

  set_gdbarch_num_regs (gdbarch, register_count);
  set_gdbarch_num_pseudo_regs (gdbarch, 0);

  tdep->register_names.resize (register_count);
  tdep->register_types.resize (register_count);
  for (size_t i = 0; i < register_count; ++i)
    {
      /* Set amd-dbgapi register id -> gdb regnum mapping.  */
      tdep->regnum_map.emplace (tdep->register_ids[i], i);

      /* Get register name.  */
      char *bytes;
      status = amd_dbgapi_register_get_info (tdep->register_ids[i],
					     AMD_DBGAPI_REGISTER_INFO_NAME,
					     sizeof (bytes), &bytes);
      if (status == AMD_DBGAPI_STATUS_SUCCESS)
	{
	  tdep->register_names[i] = bytes;
	  xfree (bytes);
	}

      /* Get register DWARF number.  */
      uint64_t dwarf_num;
      status = amd_dbgapi_register_get_info (tdep->register_ids[i],
					     AMD_DBGAPI_REGISTER_INFO_DWARF,
					     sizeof (dwarf_num), &dwarf_num);
      if (status == AMD_DBGAPI_STATUS_SUCCESS)
	{
	  if (dwarf_num >= tdep->dwarf_regnum_to_gdb_regnum.size ())
	    tdep->dwarf_regnum_to_gdb_regnum.resize (dwarf_num + 1, -1);

	  tdep->dwarf_regnum_to_gdb_regnum[dwarf_num] = i;
	}
    }

  amd_dbgapi_register_id_t pc_register_id;
  status = amd_dbgapi_architecture_get_info
    (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_PC_REGISTER,
     sizeof (pc_register_id), &pc_register_id);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    {
      warning (_("Failed to get PC register from amd-dbgapi"));
      return nullptr;
    }

  set_gdbarch_pc_regnum (gdbarch, tdep->regnum_map[pc_register_id]);
  set_gdbarch_ps_regnum (gdbarch, -1);
  set_gdbarch_sp_regnum (gdbarch, -1);
  set_gdbarch_fp0_regnum (gdbarch, -1);

  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, amdgpu_dwarf_reg_to_regnum);

  set_gdbarch_return_value_as_value (gdbarch, amdgpu_return_value_as_value);

  /* Register representation.  */
  set_gdbarch_register_name (gdbarch, amdgpu_register_name);
  set_gdbarch_register_type (gdbarch, amdgpu_register_type);
  set_gdbarch_register_reggroup_p (gdbarch, amdgpu_register_reggroup_p);

  /* Disassembly.  */
  set_gdbarch_print_insn (gdbarch, print_insn_amdgpu);

 /* Instructions.  */
  amd_dbgapi_size_t max_insn_length = 0;
  status = amd_dbgapi_architecture_get_info
    (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_LARGEST_INSTRUCTION_SIZE,
     sizeof (max_insn_length), &max_insn_length);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd_dbgapi_architecture_get_info failed"));

  set_gdbarch_max_insn_length (gdbarch, max_insn_length);

  status = amd_dbgapi_architecture_get_info
    (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_SIZE,
     sizeof (tdep->breakpoint_instruction_size),
     &tdep->breakpoint_instruction_size);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd_dbgapi_architecture_get_info failed"));

  gdb_byte *breakpoint_instruction_bytes;
  status = amd_dbgapi_architecture_get_info
    (architecture_id, AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION,
     sizeof (breakpoint_instruction_bytes), &breakpoint_instruction_bytes);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd_dbgapi_architecture_get_info failed"));

  tdep->breakpoint_instruction_bytes.reset (breakpoint_instruction_bytes);

  set_gdbarch_breakpoint_kind_from_pc (gdbarch,
				       amdgpu_breakpoint_kind_from_pc);
  set_gdbarch_sw_breakpoint_from_kind (gdbarch,
				       amdgpu_sw_breakpoint_from_kind);

  amd_dbgapi_size_t pc_adjust;
  status = amd_dbgapi_architecture_get_info
    (architecture_id,
     AMD_DBGAPI_ARCHITECTURE_INFO_BREAKPOINT_INSTRUCTION_PC_ADJUST,
     sizeof (pc_adjust), &pc_adjust);
  if (status != AMD_DBGAPI_STATUS_SUCCESS)
    error (_("amd_dbgapi_architecture_get_info failed"));

  set_gdbarch_decr_pc_after_break (gdbarch, pc_adjust);

  return gdbarch_u.release ();
}

#if defined GDB_SELF_TEST

static void
amdgpu_register_type_parse_test ()
{
  {
    /* A type that exercises flags and enums, in particular looking up an
       existing enum type by name. */
    const char *flags_type_str =
      "flags32_t mode { \
	 enum fp_round { \
	   NEAREST_EVEN = 0, \
	   PLUS_INF  = 1, \
	   MINUS_INF = 2, \
	   ZERO      = 3 \
	 } FP_ROUND.32 @0-1; \
	 enum fp_round FP_ROUND.64_16 @2-3; \
	 enum fp_denorm { \
	   FLUSH_SRC_DST = 0, \
	   FLUSH_DST     = 1, \
	   FLUSH_SRC     = 2, \
	   FLUSH_NONE    = 3 \
	 } FP_DENORM.32 @4-5; \
	 enum fp_denorm FP_DENORM.64_16 @6-7; \
	 bool DX10_CLAMP @8; \
	 bool IEEE @9; \
	 bool LOD_CLAMPED @10; \
	 bool DEBUG_EN @11; \
	 bool EXCP_EN.INVALID @12; \
	 bool EXCP_EN.DENORM @13; \
	 bool EXCP_EN.DIV0 @14; \
	 bool EXCP_EN.OVERFLOW @15; \
	 bool EXCP_EN.UNDERFLOW @16; \
	 bool EXCP_EN.INEXACT @17; \
	 bool EXCP_EN.INT_DIV0 @18; \
	 bool EXCP_EN.ADDR_WATCH @19; \
	 bool FP16_OVFL @23; \
	 bool POPS_PACKER0 @24; \
	 bool POPS_PACKER1 @25; \
	 bool DISABLE_PERF @26; \
	 bool GPR_IDX_EN @27; \
	 bool VSKIP @28; \
	 uint32_t CSP @29-31; \
       }";
    amd_dbgapi_register_type_map type_map;
    const amd_dbgapi_register_type &type
      = parse_amd_dbgapi_register_type (flags_type_str, type_map);

    gdb_assert (type.kind () == amd_dbgapi_register_type::kind::FLAGS);

    const auto &f
      = gdb::checked_static_cast<const amd_dbgapi_register_type_flags &> (type);
    gdb_assert (f.size () == 23);

    /* Check the two "FP_ROUND" fields.  */
    auto check_fp_round_field
      = [] (const char *name, const amd_dbgapi_register_type_flags::field &field)
	{
	  gdb_assert (field.name == name);
	  gdb_assert (field.type->kind ()
		      == amd_dbgapi_register_type::kind::ENUM);

	  const auto &e
	    = gdb::checked_static_cast<const amd_dbgapi_register_type_enum &>
	      (*field.type);
	  gdb_assert (e.size () == 4);
	  gdb_assert (e[0].name == "NEAREST_EVEN");
	  gdb_assert (e[0].value == 0);
	  gdb_assert (e[3].name == "ZERO");
	  gdb_assert (e[3].value == 3);
	};

    check_fp_round_field ("FP_ROUND.32", f[0]);
    check_fp_round_field ("FP_ROUND.64_16", f[1]);

    /* Check the "CSP" field.  */
    gdb_assert (f[22].name == "CSP");
    gdb_assert (f[22].type->kind () == amd_dbgapi_register_type::kind::INTEGER);

    const auto &i
      = gdb::checked_static_cast<const amd_dbgapi_register_type_integer &>
	  (*f[22].type);
    gdb_assert (i.bit_size () == 32);
    gdb_assert (i.is_unsigned ());
  }

  {
    /* Test the vector type.  */
    const char *vector_type_str = "int32_t[64]";
    amd_dbgapi_register_type_map type_map;
    const amd_dbgapi_register_type &type
      = parse_amd_dbgapi_register_type (vector_type_str, type_map);

    gdb_assert (type.kind () == amd_dbgapi_register_type::kind::VECTOR);

    const auto &v
      = gdb::checked_static_cast<const amd_dbgapi_register_type_vector &>
	  (type);
    gdb_assert (v.count () == 64);

    const auto &et = v.element_type ();
    gdb_assert (et.kind () == amd_dbgapi_register_type::kind::INTEGER);

    const auto &i
      = gdb::checked_static_cast<const amd_dbgapi_register_type_integer &> (et);
    gdb_assert (i.bit_size () == 32);
    gdb_assert (!i.is_unsigned ());
  }
}

#endif

void _initialize_amdgpu_tdep ();

void
_initialize_amdgpu_tdep ()
{
  gdbarch_register (bfd_arch_amdgcn, amdgpu_gdbarch_init, NULL,
		    amdgpu_supports_arch_info);
#if defined GDB_SELF_TEST
  selftests::register_test ("amdgpu-register-type-parse-flags-fields",
			    amdgpu_register_type_parse_test);
#endif
}
