/* Target-dependent code for the AMDGPU architectures.

   Copyright (C) 2019-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 "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 "objfiles.h"
#include "observable.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, gdb::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, gdb::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 (gdb::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 (gdb::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 (gdb::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 (gdb::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, gdb::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); };

      gdb::string_view name = sv_from_match (matches[1]);
      gdb::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 (gdb::to_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, gdb::string_view name, gdb::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); };

      gdb::string_view field_type_str = sv_from_match (matches[1]);
      gdb::string_view field_name = sv_from_match (matches[3]);
      gdb::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 (gdb::to_string (field_name), pos_begin, pos_begin,
			      nullptr);
      else
	{
	  if (matches[5].rm_so == -1)
	    error (_("Missing end bit position"));

	  gdb::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 (gdb::to_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 (gdb::string_view name,
				       amd_dbgapi_register_type_map &type_map)
{
  std::string name_str = gdb::to_string (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 (gdb::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 != gdb::string_view::npos)
    {
      /* Vector types.  */
      gdb::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 != gdb::string_view::npos);
      gdb::string_view count_str_view
	= type_str.substr (pos_open_bracket + 1,
			    pos_close_bracket - pos_open_bracket);
      std::string count_str = gdb::to_string (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"));

      gdb::string_view flags_keyword = sv_from_match (matches[1]);
      unsigned int bit_size = flags_keyword == "flags32_t" ? 32 : 64;
      gdb::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."),
		   gdb::to_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."),
		   gdb::to_string (name).c_str ());

	  amd_dbgapi_register_type_flags_up flags_type
	    (new amd_dbgapi_register_type_flags (bit_size, name));
	  gdb::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"));

      gdb::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"),
		   gdb::to_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"),
		   gdb::to_string (name).c_str ());

	  amd_dbgapi_register_type_enum_up enum_type
	    (new amd_dbgapi_register_type_enum (name));
	  gdb::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->set_num_fields (enum_type.size ());
	gdb_type->set_fields
	  ((struct field *) TYPE_ZALLOC (gdb_type, (sizeof (struct field)
						    * 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 (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 (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, frame_info_ptr this_frame)
{
  return frame_id_build (0, get_frame_pc (this_frame));
}

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

static const frame_unwind amdgpu_frame_unwind = {
  "amdgpu",
  NORMAL_FRAME,
  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
}
