/* Target-dependent code for AMD64.

   Copyright (C) 2001-2025 Free Software Foundation, Inc.

   Contributed by Jiri Smid, SuSE Labs.

   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 "extract-store-integer.h"
#include "language.h"
#include "opcode/i386.h"
#include "dis-asm.h"
#include "arch-utils.h"
#include "dummy-frame.h"
#include "frame.h"
#include "frame-base.h"
#include "frame-unwind.h"
#include "inferior.h"
#include "infrun.h"
#include "cli/cli-cmds.h"
#include "gdbcore.h"
#include "objfiles.h"
#include "regcache.h"
#include "regset.h"
#include "symfile.h"
#include "disasm.h"
#include "amd64-tdep.h"
#include "i387-tdep.h"
#include "gdbsupport/x86-xstate.h"
#include <algorithm>
#include "target-descriptions.h"
#include "arch/amd64.h"
#include "producer.h"
#include "ax.h"
#include "ax-gdb.h"
#include "gdbsupport/byte-vector.h"
#include "osabi.h"
#include "x86-tdep.h"
#include "amd64-ravenscar-thread.h"
#include "gdbsupport/selftest.h"

/* Note that the AMD64 architecture was previously known as x86-64.
   The latter is (forever) engraved into the canonical system name as
   returned by config.guess, and used as the name for the AMD64 port
   of GNU/Linux.  The BSD's have renamed their ports to amd64; they
   don't like to shout.  For GDB we prefer the amd64_-prefix over the
   x86_64_-prefix since it's so much easier to type.  */

/* Register information.  */

static const char * const amd64_register_names[] = 
{
  "rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp",

  /* %r8 is indeed register number 8.  */
  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
  "rip", "eflags", "cs", "ss", "ds", "es", "fs", "gs",

  /* %st0 is register number 24.  */
  "st0", "st1", "st2", "st3", "st4", "st5", "st6", "st7",
  "fctrl", "fstat", "ftag", "fiseg", "fioff", "foseg", "fooff", "fop",

  /* %xmm0 is register number 40.  */
  "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
  "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
  "mxcsr",
};

static const char * const amd64_ymm_names[] = 
{
  "ymm0", "ymm1", "ymm2", "ymm3",
  "ymm4", "ymm5", "ymm6", "ymm7",
  "ymm8", "ymm9", "ymm10", "ymm11",
  "ymm12", "ymm13", "ymm14", "ymm15"
};

static const char * const amd64_ymm_avx512_names[] =
{
  "ymm16", "ymm17", "ymm18", "ymm19",
  "ymm20", "ymm21", "ymm22", "ymm23",
  "ymm24", "ymm25", "ymm26", "ymm27",
  "ymm28", "ymm29", "ymm30", "ymm31"
};

static const char * const amd64_ymmh_names[] = 
{
  "ymm0h", "ymm1h", "ymm2h", "ymm3h",
  "ymm4h", "ymm5h", "ymm6h", "ymm7h",
  "ymm8h", "ymm9h", "ymm10h", "ymm11h",
  "ymm12h", "ymm13h", "ymm14h", "ymm15h"
};

static const char * const amd64_ymmh_avx512_names[] =
{
  "ymm16h", "ymm17h", "ymm18h", "ymm19h",
  "ymm20h", "ymm21h", "ymm22h", "ymm23h",
  "ymm24h", "ymm25h", "ymm26h", "ymm27h",
  "ymm28h", "ymm29h", "ymm30h", "ymm31h"
};

static const char * const amd64_k_names[] =
{
  "k0", "k1", "k2", "k3",
  "k4", "k5", "k6", "k7"
};

static const char * const amd64_zmmh_names[] =
{
  "zmm0h", "zmm1h", "zmm2h", "zmm3h",
  "zmm4h", "zmm5h", "zmm6h", "zmm7h",
  "zmm8h", "zmm9h", "zmm10h", "zmm11h",
  "zmm12h", "zmm13h", "zmm14h", "zmm15h",
  "zmm16h", "zmm17h", "zmm18h", "zmm19h",
  "zmm20h", "zmm21h", "zmm22h", "zmm23h",
  "zmm24h", "zmm25h", "zmm26h", "zmm27h",
  "zmm28h", "zmm29h", "zmm30h", "zmm31h"
};

static const char * const amd64_zmm_names[] =
{
  "zmm0", "zmm1", "zmm2", "zmm3",
  "zmm4", "zmm5", "zmm6", "zmm7",
  "zmm8", "zmm9", "zmm10", "zmm11",
  "zmm12", "zmm13", "zmm14", "zmm15",
  "zmm16", "zmm17", "zmm18", "zmm19",
  "zmm20", "zmm21", "zmm22", "zmm23",
  "zmm24", "zmm25", "zmm26", "zmm27",
  "zmm28", "zmm29", "zmm30", "zmm31"
};

static const char * const amd64_xmm_avx512_names[] = {
    "xmm16",  "xmm17",  "xmm18",  "xmm19",
    "xmm20",  "xmm21",  "xmm22",  "xmm23",
    "xmm24",  "xmm25",  "xmm26",  "xmm27",
    "xmm28",  "xmm29",  "xmm30",  "xmm31"
};

static const char * const amd64_pkeys_names[] = {
    "pkru"
};

/* DWARF Register Number Mapping as defined in the System V psABI,
   section 3.6.  */

static int amd64_dwarf_regmap[] =
{
  /* General Purpose Registers RAX, RDX, RCX, RBX, RSI, RDI.  */
  AMD64_RAX_REGNUM, AMD64_RDX_REGNUM,
  AMD64_RCX_REGNUM, AMD64_RBX_REGNUM,
  AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,

  /* Frame Pointer Register RBP.  */
  AMD64_RBP_REGNUM,

  /* Stack Pointer Register RSP.  */
  AMD64_RSP_REGNUM,

  /* Extended Integer Registers 8 - 15.  */
  AMD64_R8_REGNUM,		/* %r8 */
  AMD64_R9_REGNUM,		/* %r9 */
  AMD64_R10_REGNUM,		/* %r10 */
  AMD64_R11_REGNUM,		/* %r11 */
  AMD64_R12_REGNUM,		/* %r12 */
  AMD64_R13_REGNUM,		/* %r13 */
  AMD64_R14_REGNUM,		/* %r14 */
  AMD64_R15_REGNUM,		/* %r15 */

  /* Return Address RA.  Mapped to RIP.  */
  AMD64_RIP_REGNUM,

  /* SSE Registers 0 - 7.  */
  AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM,
  AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3,
  AMD64_XMM0_REGNUM + 4, AMD64_XMM0_REGNUM + 5,
  AMD64_XMM0_REGNUM + 6, AMD64_XMM0_REGNUM + 7,

  /* Extended SSE Registers 8 - 15.  */
  AMD64_XMM0_REGNUM + 8, AMD64_XMM0_REGNUM + 9,
  AMD64_XMM0_REGNUM + 10, AMD64_XMM0_REGNUM + 11,
  AMD64_XMM0_REGNUM + 12, AMD64_XMM0_REGNUM + 13,
  AMD64_XMM0_REGNUM + 14, AMD64_XMM0_REGNUM + 15,

  /* Floating Point Registers 0-7.  */
  AMD64_ST0_REGNUM + 0, AMD64_ST0_REGNUM + 1,
  AMD64_ST0_REGNUM + 2, AMD64_ST0_REGNUM + 3,
  AMD64_ST0_REGNUM + 4, AMD64_ST0_REGNUM + 5,
  AMD64_ST0_REGNUM + 6, AMD64_ST0_REGNUM + 7,

  /* MMX Registers 0 - 7.
     We have to handle those registers specifically, as their register
     number within GDB depends on the target (or they may even not be
     available at all).  */
  -1, -1, -1, -1, -1, -1, -1, -1,

  /* Control and Status Flags Register.  */
  AMD64_EFLAGS_REGNUM,

  /* Selector Registers.  */
  AMD64_ES_REGNUM,
  AMD64_CS_REGNUM,
  AMD64_SS_REGNUM,
  AMD64_DS_REGNUM,
  AMD64_FS_REGNUM,
  AMD64_GS_REGNUM,
  -1,
  -1,

  /* Segment Base Address Registers.  */
  -1,
  -1,
  -1,
  -1,

  /* Special Selector Registers.  */
  -1,
  -1,

  /* Floating Point Control Registers.  */
  AMD64_MXCSR_REGNUM,
  AMD64_FCTRL_REGNUM,
  AMD64_FSTAT_REGNUM,

  /* XMM16-XMM31.  */
  AMD64_XMM16_REGNUM + 0, AMD64_XMM16_REGNUM + 1,
  AMD64_XMM16_REGNUM + 2, AMD64_XMM16_REGNUM + 3,
  AMD64_XMM16_REGNUM + 4, AMD64_XMM16_REGNUM + 5,
  AMD64_XMM16_REGNUM + 6, AMD64_XMM16_REGNUM + 7,
  AMD64_XMM16_REGNUM + 8, AMD64_XMM16_REGNUM + 9,
  AMD64_XMM16_REGNUM + 10, AMD64_XMM16_REGNUM + 11,
  AMD64_XMM16_REGNUM + 12, AMD64_XMM16_REGNUM + 13,
  AMD64_XMM16_REGNUM + 14, AMD64_XMM16_REGNUM + 15,

  /* Reserved.  */
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,

  /* Mask Registers.  */
  AMD64_K0_REGNUM + 0, AMD64_K0_REGNUM + 1,
  AMD64_K0_REGNUM + 2, AMD64_K0_REGNUM + 3,
  AMD64_K0_REGNUM + 4, AMD64_K0_REGNUM + 5,
  AMD64_K0_REGNUM + 6, AMD64_K0_REGNUM + 7
};

static const int amd64_dwarf_regmap_len =
  (sizeof (amd64_dwarf_regmap) / sizeof (amd64_dwarf_regmap[0]));

/* Convert DWARF register number REG to the appropriate register
   number used by GDB.  */

static int
amd64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
{
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
  int ymm0_regnum = tdep->ymm0_regnum;
  int regnum = -1;

  if (reg >= 0 && reg < amd64_dwarf_regmap_len)
    regnum = amd64_dwarf_regmap[reg];

  if (ymm0_regnum >= 0 && i386_xmm_regnum_p (gdbarch, regnum))
    regnum += ymm0_regnum - I387_XMM0_REGNUM (tdep);

  return regnum;
}

/* Map architectural register numbers to gdb register numbers.  */

static const int amd64_arch_regmap[16] =
{
  AMD64_RAX_REGNUM,	/* %rax */
  AMD64_RCX_REGNUM,	/* %rcx */
  AMD64_RDX_REGNUM,	/* %rdx */
  AMD64_RBX_REGNUM,	/* %rbx */
  AMD64_RSP_REGNUM,	/* %rsp */
  AMD64_RBP_REGNUM,	/* %rbp */
  AMD64_RSI_REGNUM,	/* %rsi */
  AMD64_RDI_REGNUM,	/* %rdi */
  AMD64_R8_REGNUM,	/* %r8 */
  AMD64_R9_REGNUM,	/* %r9 */
  AMD64_R10_REGNUM,	/* %r10 */
  AMD64_R11_REGNUM,	/* %r11 */
  AMD64_R12_REGNUM,	/* %r12 */
  AMD64_R13_REGNUM,	/* %r13 */
  AMD64_R14_REGNUM,	/* %r14 */
  AMD64_R15_REGNUM	/* %r15 */
};

static const int amd64_arch_regmap_len =
  (sizeof (amd64_arch_regmap) / sizeof (amd64_arch_regmap[0]));

/* Convert architectural register number REG to the appropriate register
   number used by GDB.  */

static int
amd64_arch_reg_to_regnum (int reg)
{
  gdb_assert (reg >= 0 && reg < amd64_arch_regmap_len);

  return amd64_arch_regmap[reg];
}

/* Register names for byte pseudo-registers.  */

static const char * const amd64_byte_names[] =
{
  "al", "bl", "cl", "dl", "sil", "dil", "bpl", "spl",
  "r8l", "r9l", "r10l", "r11l", "r12l", "r13l", "r14l", "r15l",
  "ah", "bh", "ch", "dh"
};

/* Number of lower byte registers.  */
#define AMD64_NUM_LOWER_BYTE_REGS 16

/* Register names for word pseudo-registers.  */

static const char * const amd64_word_names[] =
{
  "ax", "bx", "cx", "dx", "si", "di", "bp", "", 
  "r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"
};

/* Register names for dword pseudo-registers.  */

static const char * const amd64_dword_names[] =
{
  "eax", "ebx", "ecx", "edx", "esi", "edi", "ebp", "esp", 
  "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d",
  "eip"
};

/* Return the name of register REGNUM.  */

static const char *
amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum)
{
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
  if (i386_byte_regnum_p (gdbarch, regnum))
    return amd64_byte_names[regnum - tdep->al_regnum];
  else if (i386_zmm_regnum_p (gdbarch, regnum))
    return amd64_zmm_names[regnum - tdep->zmm0_regnum];
  else if (i386_ymm_regnum_p (gdbarch, regnum))
    return amd64_ymm_names[regnum - tdep->ymm0_regnum];
  else if (i386_ymm_avx512_regnum_p (gdbarch, regnum))
    return amd64_ymm_avx512_names[regnum - tdep->ymm16_regnum];
  else if (i386_word_regnum_p (gdbarch, regnum))
    return amd64_word_names[regnum - tdep->ax_regnum];
  else if (i386_dword_regnum_p (gdbarch, regnum))
    return amd64_dword_names[regnum - tdep->eax_regnum];
  else
    return i386_pseudo_register_name (gdbarch, regnum);
}

static value *
amd64_pseudo_register_read_value (gdbarch *gdbarch, const frame_info_ptr &next_frame,
				  int regnum)
{
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  if (i386_byte_regnum_p (gdbarch, regnum))
    {
      int gpnum = regnum - tdep->al_regnum;

      /* Extract (always little endian).  */
      if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
	{
	  gpnum -= AMD64_NUM_LOWER_BYTE_REGS;

	  /* Special handling for AH, BH, CH, DH.  */
	  return pseudo_from_raw_part (next_frame, regnum, gpnum, 1);
	}
      else
	return pseudo_from_raw_part (next_frame, regnum, gpnum, 0);
    }
  else if (i386_dword_regnum_p (gdbarch, regnum))
    {
      int gpnum = regnum - tdep->eax_regnum;

      return pseudo_from_raw_part (next_frame, regnum, gpnum, 0);
    }
  else
    return i386_pseudo_register_read_value (gdbarch, next_frame, regnum);
}

static void
amd64_pseudo_register_write (gdbarch *gdbarch, const frame_info_ptr &next_frame,
			     int regnum, gdb::array_view<const gdb_byte> buf)
{
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  if (i386_byte_regnum_p (gdbarch, regnum))
    {
      int gpnum = regnum - tdep->al_regnum;

      if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
	{
	  gpnum -= AMD64_NUM_LOWER_BYTE_REGS;
	  pseudo_to_raw_part (next_frame, buf, gpnum, 1);
	}
      else
	pseudo_to_raw_part (next_frame, buf, gpnum, 0);
    }
  else if (i386_dword_regnum_p (gdbarch, regnum))
    {
      int gpnum = regnum - tdep->eax_regnum;
      pseudo_to_raw_part (next_frame, buf, gpnum, 0);
    }
  else
    i386_pseudo_register_write (gdbarch, next_frame, regnum, buf);
}

/* Implement the 'ax_pseudo_register_collect' gdbarch method.  */

static int
amd64_ax_pseudo_register_collect (struct gdbarch *gdbarch,
				  struct agent_expr *ax, int regnum)
{
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  if (i386_byte_regnum_p (gdbarch, regnum))
    {
      int gpnum = regnum - tdep->al_regnum;

      if (gpnum >= AMD64_NUM_LOWER_BYTE_REGS)
	ax_reg_mask (ax, gpnum - AMD64_NUM_LOWER_BYTE_REGS);
      else
	ax_reg_mask (ax, gpnum);
      return 0;
    }
  else if (i386_dword_regnum_p (gdbarch, regnum))
    {
      int gpnum = regnum - tdep->eax_regnum;

      ax_reg_mask (ax, gpnum);
      return 0;
    }
  else
    return i386_ax_pseudo_register_collect (gdbarch, ax, regnum);
}



/* Register classes as defined in the psABI.  */

enum amd64_reg_class
{
  AMD64_INTEGER,
  AMD64_SSE,
  AMD64_SSEUP,
  AMD64_X87,
  AMD64_X87UP,
  AMD64_COMPLEX_X87,
  AMD64_NO_CLASS,
  AMD64_MEMORY
};

/* Return the union class of CLASS1 and CLASS2.  See the psABI for
   details.  */

static enum amd64_reg_class
amd64_merge_classes (enum amd64_reg_class class1, enum amd64_reg_class class2)
{
  /* Rule (a): If both classes are equal, this is the resulting class.  */
  if (class1 == class2)
    return class1;

  /* Rule (b): If one of the classes is NO_CLASS, the resulting class
     is the other class.  */
  if (class1 == AMD64_NO_CLASS)
    return class2;
  if (class2 == AMD64_NO_CLASS)
    return class1;

  /* Rule (c): If one of the classes is MEMORY, the result is MEMORY.  */
  if (class1 == AMD64_MEMORY || class2 == AMD64_MEMORY)
    return AMD64_MEMORY;

  /* Rule (d): If one of the classes is INTEGER, the result is INTEGER.  */
  if (class1 == AMD64_INTEGER || class2 == AMD64_INTEGER)
    return AMD64_INTEGER;

  /* Rule (e): If one of the classes is X87, X87UP, COMPLEX_X87 class,
     MEMORY is used as class.  */
  if (class1 == AMD64_X87 || class1 == AMD64_X87UP
      || class1 == AMD64_COMPLEX_X87 || class2 == AMD64_X87
      || class2 == AMD64_X87UP || class2 == AMD64_COMPLEX_X87)
    return AMD64_MEMORY;

  /* Rule (f): Otherwise class SSE is used.  */
  return AMD64_SSE;
}

static void amd64_classify (struct type *type, enum amd64_reg_class theclass[2]);

/* Return true if TYPE is a structure or union with unaligned fields.  */

static bool
amd64_has_unaligned_fields (struct type *type)
{
  if (type->code () == TYPE_CODE_STRUCT
      || type->code () == TYPE_CODE_UNION)
    {
      for (int i = 0; i < type->num_fields (); i++)
	{
	  struct type *subtype = check_typedef (type->field (i).type ());

	  /* Ignore static fields, empty fields (for example nested
	     empty structures), and bitfields (these are handled by
	     the caller).  */
	  if (type->field (i).is_static ()
	      || (type->field (i).bitsize () == 0
		  && subtype->length () == 0)
	      || type->field (i).is_packed ())
	    continue;

	  int bitpos = type->field (i).loc_bitpos ();

	  if (bitpos % 8 != 0)
	    return true;

	  int align = type_align (subtype);
	  if (align == 0)
	    error (_("could not determine alignment of type"));

	  int bytepos = bitpos / 8;
	  if (bytepos % align != 0)
	    return true;

	  if (amd64_has_unaligned_fields (subtype))
	    return true;
	}
    }

  return false;
}

/* Classify field I of TYPE starting at BITOFFSET according to the rules for
   structures and union types, and store the result in THECLASS.  */

static void
amd64_classify_aggregate_field (struct type *type, int i,
				enum amd64_reg_class theclass[2],
				unsigned int bitoffset)
{
  struct type *subtype = check_typedef (type->field (i).type ());
  enum amd64_reg_class subclass[2];
  int bitsize = type->field (i).bitsize ();

  if (bitsize == 0)
    bitsize = subtype->length () * 8;

  /* Ignore static fields, or empty fields, for example nested
     empty structures.*/
  if (type->field (i).is_static () || bitsize == 0)
    return;

  int bitpos = bitoffset + type->field (i).loc_bitpos ();
  int pos = bitpos / 64;
  int endpos = (bitpos + bitsize - 1) / 64;

  if (subtype->code () == TYPE_CODE_STRUCT
      || subtype->code () == TYPE_CODE_UNION)
    {
      /* Each field of an object is classified recursively.  */
      int j;
      for (j = 0; j < subtype->num_fields (); j++)
	amd64_classify_aggregate_field (subtype, j, theclass, bitpos);
      return;
    }

  gdb_assert (pos == 0 || pos == 1);

  amd64_classify (subtype, subclass);
  theclass[pos] = amd64_merge_classes (theclass[pos], subclass[0]);
  if (bitsize <= 64 && pos == 0 && endpos == 1)
    /* This is a bit of an odd case:  We have a field that would
       normally fit in one of the two eightbytes, except that
       it is placed in a way that this field straddles them.
       This has been seen with a structure containing an array.

       The ABI is a bit unclear in this case, but we assume that
       this field's class (stored in subclass[0]) must also be merged
       into class[1].  In other words, our field has a piece stored
       in the second eight-byte, and thus its class applies to
       the second eight-byte as well.

       In the case where the field length exceeds 8 bytes,
       it should not be necessary to merge the field class
       into class[1].  As LEN > 8, subclass[1] is necessarily
       different from AMD64_NO_CLASS.  If subclass[1] is equal
       to subclass[0], then the normal class[1]/subclass[1]
       merging will take care of everything.  For subclass[1]
       to be different from subclass[0], I can only see the case
       where we have a SSE/SSEUP or X87/X87UP pair, which both
       use up all 16 bytes of the aggregate, and are already
       handled just fine (because each portion sits on its own
       8-byte).  */
    theclass[1] = amd64_merge_classes (theclass[1], subclass[0]);
  if (pos == 0)
    theclass[1] = amd64_merge_classes (theclass[1], subclass[1]);
}

/* Classify TYPE according to the rules for aggregate (structures and
   arrays) and union types, and store the result in CLASS.  */

static void
amd64_classify_aggregate (struct type *type, enum amd64_reg_class theclass[2])
{
  /* 1. If the size of an object is larger than two times eight bytes, or
	it is a non-trivial C++ object, or it has unaligned fields, then it
	has class memory.

	It is important that the trivially_copyable check is before the
	unaligned fields check, as C++ classes with virtual base classes
	will have fields (for the virtual base classes) with non-constant
	loc_bitpos attributes, which will cause an assert to trigger within
	the unaligned field check.  As classes with virtual bases are not
	trivially copyable, checking that first avoids this problem.  */
  if (TYPE_HAS_DYNAMIC_LENGTH (type)
      || type->length () > 16
      || !language_pass_by_reference (type).trivially_copyable
      || amd64_has_unaligned_fields (type))
    {
      theclass[0] = theclass[1] = AMD64_MEMORY;
      return;
    }

  /* 2. Both eightbytes get initialized to class NO_CLASS.  */
  theclass[0] = theclass[1] = AMD64_NO_CLASS;

  /* 3. Each field of an object is classified recursively so that
	always two fields are considered. The resulting class is
	calculated according to the classes of the fields in the
	eightbyte: */

  if (type->code () == TYPE_CODE_ARRAY)
    {
      struct type *subtype = check_typedef (type->target_type ());

      /* All fields in an array have the same type.  */
      amd64_classify (subtype, theclass);
      if (type->length () > 8 && theclass[1] == AMD64_NO_CLASS)
	theclass[1] = theclass[0];
    }
  else
    {
      int i;

      /* Structure or union.  */
      gdb_assert (type->code () == TYPE_CODE_STRUCT
		  || type->code () == TYPE_CODE_UNION);

      for (i = 0; i < type->num_fields (); i++)
	amd64_classify_aggregate_field (type, i, theclass, 0);
    }

  /* 4. Then a post merger cleanup is done:  */

  /* Rule (a): If one of the classes is MEMORY, the whole argument is
     passed in memory.  */
  if (theclass[0] == AMD64_MEMORY || theclass[1] == AMD64_MEMORY)
    theclass[0] = theclass[1] = AMD64_MEMORY;

  /* Rule (b): If SSEUP is not preceded by SSE, it is converted to
     SSE.  */
  if (theclass[0] == AMD64_SSEUP)
    theclass[0] = AMD64_SSE;
  if (theclass[1] == AMD64_SSEUP && theclass[0] != AMD64_SSE)
    theclass[1] = AMD64_SSE;
}

/* Classify TYPE, and store the result in CLASS.  */

static void
amd64_classify (struct type *type, enum amd64_reg_class theclass[2])
{
  enum type_code code = type->code ();
  int len = type->length ();

  theclass[0] = theclass[1] = AMD64_NO_CLASS;

  /* Arguments of types (signed and unsigned) _Bool, char, short, int,
     long, long long, and pointers are in the INTEGER class.  Similarly,
     range types, used by languages such as Ada, are also in the INTEGER
     class.  */
  if ((code == TYPE_CODE_INT || code == TYPE_CODE_ENUM
       || code == TYPE_CODE_BOOL || code == TYPE_CODE_RANGE
       || code == TYPE_CODE_CHAR
       || code == TYPE_CODE_PTR || TYPE_IS_REFERENCE (type))
      && (len == 1 || len == 2 || len == 4 || len == 8))
    theclass[0] = AMD64_INTEGER;

  /* Arguments of types _Float16, float, double, _Decimal32, _Decimal64 and
     __m64 are in class SSE.  */
  else if ((code == TYPE_CODE_FLT || code == TYPE_CODE_DECFLOAT)
	   && (len == 2 || len == 4 || len == 8))
    /* FIXME: __m64 .  */
    theclass[0] = AMD64_SSE;

  /* Arguments of types __float128, _Decimal128 and __m128 are split into
     two halves.  The least significant ones belong to class SSE, the most
     significant one to class SSEUP.  */
  else if (code == TYPE_CODE_DECFLOAT && len == 16)
    /* FIXME: __float128, __m128.  */
    theclass[0] = AMD64_SSE, theclass[1] = AMD64_SSEUP;

  /* The 64-bit mantissa of arguments of type long double belongs to
     class X87, the 16-bit exponent plus 6 bytes of padding belongs to
     class X87UP.  */
  else if (code == TYPE_CODE_FLT && len == 16)
    /* Class X87 and X87UP.  */
    theclass[0] = AMD64_X87, theclass[1] = AMD64_X87UP;

  /* Arguments of complex T - where T is one of the types _Float16, float or
     double - get treated as if they are implemented as:

     struct complexT {
       T real;
       T imag;
     };

  */
  else if (code == TYPE_CODE_COMPLEX && (len == 8 || len == 4))
    theclass[0] = AMD64_SSE;
  else if (code == TYPE_CODE_COMPLEX && len == 16)
    theclass[0] = theclass[1] = AMD64_SSE;

  /* A variable of type complex long double is classified as type
     COMPLEX_X87.  */
  else if (code == TYPE_CODE_COMPLEX && len == 32)
    theclass[0] = AMD64_COMPLEX_X87;

  /* Aggregates.  */
  else if (code == TYPE_CODE_ARRAY || code == TYPE_CODE_STRUCT
	   || code == TYPE_CODE_UNION)
    amd64_classify_aggregate (type, theclass);
}

static enum return_value_convention
amd64_return_value (struct gdbarch *gdbarch, struct value *function,
		    struct type *type, struct regcache *regcache,
		    struct value **read_value, const gdb_byte *writebuf)
{
  enum amd64_reg_class theclass[2];
  int len = type->length ();
  static int integer_regnum[] = { AMD64_RAX_REGNUM, AMD64_RDX_REGNUM };
  static int sse_regnum[] = { AMD64_XMM0_REGNUM, AMD64_XMM1_REGNUM };
  int integer_reg = 0;
  int sse_reg = 0;
  int i;

  gdb_assert (!(read_value && writebuf));

  /* 1. Classify the return type with the classification algorithm.  */
  amd64_classify (type, theclass);

  /* 2. If the type has class MEMORY, then the caller provides space
     for the return value and passes the address of this storage in
     %rdi as if it were the first argument to the function.  In effect,
     this address becomes a hidden first argument.

     On return %rax will contain the address that has been passed in
     by the caller in %rdi.  */
  if (theclass[0] == AMD64_MEMORY)
    {
      /* As indicated by the comment above, the ABI guarantees that we
	 can always find the return value just after the function has
	 returned.  */

      if (read_value != nullptr)
	{
	  ULONGEST addr;

	  regcache_raw_read_unsigned (regcache, AMD64_RAX_REGNUM, &addr);
	  *read_value = value_at_non_lval (type, addr);
	}

      return RETURN_VALUE_ABI_RETURNS_ADDRESS;
    }

  gdb_byte *readbuf = nullptr;
  if (read_value != nullptr)
    {
      *read_value = value::allocate (type);
      readbuf = (*read_value)->contents_raw ().data ();
    }

  /* 8. If the class is COMPLEX_X87, the real part of the value is
	returned in %st0 and the imaginary part in %st1.  */
  if (theclass[0] == AMD64_COMPLEX_X87)
    {
      if (readbuf)
	{
	  regcache->raw_read (AMD64_ST0_REGNUM, readbuf);
	  regcache->raw_read (AMD64_ST1_REGNUM, readbuf + 16);
	}

      if (writebuf)
	{
	  i387_return_value (gdbarch, regcache);
	  regcache->raw_write (AMD64_ST0_REGNUM, writebuf);
	  regcache->raw_write (AMD64_ST1_REGNUM, writebuf + 16);

	  /* Fix up the tag word such that both %st(0) and %st(1) are
	     marked as valid.  */
	  regcache_raw_write_unsigned (regcache, AMD64_FTAG_REGNUM, 0xfff);
	}

      return RETURN_VALUE_REGISTER_CONVENTION;
    }

  gdb_assert (theclass[1] != AMD64_MEMORY);
  gdb_assert (len <= 16);

  for (i = 0; len > 0; i++, len -= 8)
    {
      int regnum = -1;
      int offset = 0;

      switch (theclass[i])
	{
	case AMD64_INTEGER:
	  /* 3. If the class is INTEGER, the next available register
	     of the sequence %rax, %rdx is used.  */
	  regnum = integer_regnum[integer_reg++];
	  break;

	case AMD64_SSE:
	  /* 4. If the class is SSE, the next available SSE register
	     of the sequence %xmm0, %xmm1 is used.  */
	  regnum = sse_regnum[sse_reg++];
	  break;

	case AMD64_SSEUP:
	  /* 5. If the class is SSEUP, the eightbyte is passed in the
	     upper half of the last used SSE register.  */
	  gdb_assert (sse_reg > 0);
	  regnum = sse_regnum[sse_reg - 1];
	  offset = 8;
	  break;

	case AMD64_X87:
	  /* 6. If the class is X87, the value is returned on the X87
	     stack in %st0 as 80-bit x87 number.  */
	  regnum = AMD64_ST0_REGNUM;
	  if (writebuf)
	    i387_return_value (gdbarch, regcache);
	  break;

	case AMD64_X87UP:
	  /* 7. If the class is X87UP, the value is returned together
	     with the previous X87 value in %st0.  */
	  gdb_assert (i > 0 && theclass[0] == AMD64_X87);
	  regnum = AMD64_ST0_REGNUM;
	  offset = 8;
	  len = 2;
	  break;

	case AMD64_NO_CLASS:
	  continue;

	default:
	  gdb_assert (!"Unexpected register class.");
	}

      gdb_assert (regnum != -1);

      if (readbuf)
	regcache->raw_read_part (regnum, offset, std::min (len, 8),
				 readbuf + i * 8);
      if (writebuf)
	regcache->raw_write_part (regnum, offset, std::min (len, 8),
				  writebuf + i * 8);
    }

  return RETURN_VALUE_REGISTER_CONVENTION;
}


static CORE_ADDR
amd64_push_arguments (struct regcache *regcache, int nargs, struct value **args,
		      CORE_ADDR sp, function_call_return_method return_method)
{
  static int integer_regnum[] =
  {
    AMD64_RDI_REGNUM,		/* %rdi */
    AMD64_RSI_REGNUM,		/* %rsi */
    AMD64_RDX_REGNUM,		/* %rdx */
    AMD64_RCX_REGNUM,		/* %rcx */
    AMD64_R8_REGNUM,		/* %r8 */
    AMD64_R9_REGNUM		/* %r9 */
  };
  static int sse_regnum[] =
  {
    /* %xmm0 ... %xmm7 */
    AMD64_XMM0_REGNUM + 0, AMD64_XMM1_REGNUM,
    AMD64_XMM0_REGNUM + 2, AMD64_XMM0_REGNUM + 3,
    AMD64_XMM0_REGNUM + 4, AMD64_XMM0_REGNUM + 5,
    AMD64_XMM0_REGNUM + 6, AMD64_XMM0_REGNUM + 7,
  };
  struct value **stack_args = XALLOCAVEC (struct value *, nargs);
  int num_stack_args = 0;
  int num_elements = 0;
  int element = 0;
  int integer_reg = 0;
  int sse_reg = 0;
  int i;

  /* Reserve a register for the "hidden" argument.  */
if (return_method == return_method_struct)
    integer_reg++;

  for (i = 0; i < nargs; i++)
    {
      struct type *type = args[i]->type ();
      int len = type->length ();
      enum amd64_reg_class theclass[2];
      int needed_integer_regs = 0;
      int needed_sse_regs = 0;
      int j;

      /* Classify argument.  */
      amd64_classify (type, theclass);

      /* Calculate the number of integer and SSE registers needed for
	 this argument.  */
      for (j = 0; j < 2; j++)
	{
	  if (theclass[j] == AMD64_INTEGER)
	    needed_integer_regs++;
	  else if (theclass[j] == AMD64_SSE)
	    needed_sse_regs++;
	}

      /* Check whether enough registers are available, and if the
	 argument should be passed in registers at all.  */
      if (integer_reg + needed_integer_regs > ARRAY_SIZE (integer_regnum)
	  || sse_reg + needed_sse_regs > ARRAY_SIZE (sse_regnum)
	  || (needed_integer_regs == 0 && needed_sse_regs == 0))
	{
	  /* The argument will be passed on the stack.  */
	  num_elements += ((len + 7) / 8);
	  stack_args[num_stack_args++] = args[i];
	}
      else
	{
	  /* The argument will be passed in registers.  */
	  const gdb_byte *valbuf = args[i]->contents ().data ();
	  gdb_byte buf[8];

	  gdb_assert (len <= 16);

	  for (j = 0; len > 0; j++, len -= 8)
	    {
	      int regnum = -1;
	      int offset = 0;

	      switch (theclass[j])
		{
		case AMD64_INTEGER:
		  regnum = integer_regnum[integer_reg++];
		  break;

		case AMD64_SSE:
		  regnum = sse_regnum[sse_reg++];
		  break;

		case AMD64_SSEUP:
		  gdb_assert (sse_reg > 0);
		  regnum = sse_regnum[sse_reg - 1];
		  offset = 8;
		  break;

		case AMD64_NO_CLASS:
		  continue;

		default:
		  gdb_assert (!"Unexpected register class.");
		}

	      gdb_assert (regnum != -1);
	      memset (buf, 0, sizeof buf);
	      memcpy (buf, valbuf + j * 8, std::min (len, 8));
	      regcache->raw_write_part (regnum, offset, 8, buf);
	    }
	}
    }

  /* Allocate space for the arguments on the stack.  */
  sp -= num_elements * 8;

  /* The psABI says that "The end of the input argument area shall be
     aligned on a 16 byte boundary."  */
  sp &= ~0xf;

  /* Write out the arguments to the stack.  */
  for (i = 0; i < num_stack_args; i++)
    {
      struct type *type = stack_args[i]->type ();
      const gdb_byte *valbuf = stack_args[i]->contents ().data ();
      int len = type->length ();

      write_memory (sp + element * 8, valbuf, len);
      element += ((len + 7) / 8);
    }

  /* The psABI says that "For calls that may call functions that use
     varargs or stdargs (prototype-less calls or calls to functions
     containing ellipsis (...) in the declaration) %al is used as
     hidden argument to specify the number of SSE registers used.  */
  regcache_raw_write_unsigned (regcache, AMD64_RAX_REGNUM, sse_reg);
  return sp; 
}

static CORE_ADDR
amd64_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)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[8];

  /* Pass arguments.  */
  sp = amd64_push_arguments (regcache, nargs, args, sp, return_method);

  /* Pass "hidden" argument".  */
  if (return_method == return_method_struct)
    {
      store_unsigned_integer (buf, 8, byte_order, struct_addr);
      regcache->cooked_write (AMD64_RDI_REGNUM, buf);
    }

  /* Store return address.  */
  sp -= 8;
  store_unsigned_integer (buf, 8, byte_order, bp_addr);
  write_memory (sp, buf, 8);

  /* Finally, update the stack pointer...  */
  store_unsigned_integer (buf, 8, byte_order, sp);
  regcache->cooked_write (AMD64_RSP_REGNUM, buf);

  /* ...and fake a frame pointer.  */
  regcache->cooked_write (AMD64_RBP_REGNUM, buf);

  return sp + 16;
}

/* Displaced instruction handling.  */

/* A partially decoded instruction.
   This contains enough details for displaced stepping purposes.  */

struct amd64_insn
{
  /* The number of opcode bytes.  */
  int opcode_len;
  /* The offset of the REX/VEX instruction encoding prefix or -1 if
     not present.  */
  int enc_prefix_offset;
  /* The offset to the first opcode byte.  */
  int opcode_offset;
  /* The offset to the modrm byte or -1 if not present.  */
  int modrm_offset;

  /* The raw instruction.  */
  gdb_byte *raw_insn;
};

struct amd64_displaced_step_copy_insn_closure
  : public displaced_step_copy_insn_closure
{
  amd64_displaced_step_copy_insn_closure (int insn_buf_len)
  : insn_buf (insn_buf_len, 0)
  {}

  /* For rip-relative insns, saved copy of the reg we use instead of %rip.  */
  int tmp_used = 0;
  int tmp_regno;
  ULONGEST tmp_save;

  /* Details of the instruction.  */
  struct amd64_insn insn_details;

  /* The possibly modified insn.  */
  gdb::byte_vector insn_buf;
};

/* WARNING: Keep onebyte_has_modrm, twobyte_has_modrm in sync with
   ../opcodes/i386-dis.c (until libopcodes exports them, or an alternative,
   at which point delete these in favor of libopcodes' versions).  */

static const unsigned char onebyte_has_modrm[256] = {
  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
  /*	   -------------------------------	  */
  /* 00 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 00 */
  /* 10 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 10 */
  /* 20 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 20 */
  /* 30 */ 1,1,1,1,0,0,0,0,1,1,1,1,0,0,0,0, /* 30 */
  /* 40 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 40 */
  /* 50 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 50 */
  /* 60 */ 0,0,1,1,0,0,0,0,0,1,0,1,0,0,0,0, /* 60 */
  /* 70 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 70 */
  /* 80 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 80 */
  /* 90 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 */
  /* a0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* a0 */
  /* b0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* b0 */
  /* c0 */ 1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0, /* c0 */
  /* d0 */ 1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1, /* d0 */
  /* e0 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* e0 */
  /* f0 */ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1  /* f0 */
  /*	   -------------------------------	  */
  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
};

static const unsigned char twobyte_has_modrm[256] = {
  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
  /*	   -------------------------------	  */
  /* 00 */ 1,1,1,1,0,0,0,0,0,0,0,0,0,1,0,1, /* 0f */
  /* 10 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 1f */
  /* 20 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 2f */
  /* 30 */ 0,0,0,0,0,0,0,0,1,0,1,0,0,0,0,0, /* 3f */
  /* 40 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 4f */
  /* 50 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 5f */
  /* 60 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 6f */
  /* 70 */ 1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1, /* 7f */
  /* 80 */ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 8f */
  /* 90 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* 9f */
  /* a0 */ 0,0,0,1,1,1,1,1,0,0,0,1,1,1,1,1, /* af */
  /* b0 */ 1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1, /* bf */
  /* c0 */ 1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0, /* cf */
  /* d0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* df */
  /* e0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, /* ef */
  /* f0 */ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0  /* ff */
  /*	   -------------------------------	  */
  /*	   0 1 2 3 4 5 6 7 8 9 a b c d e f	  */
};

static int amd64_syscall_p (const struct amd64_insn *insn, int *lengthp);

static int
rex_prefix_p (gdb_byte pfx)
{
  return REX_PREFIX_P (pfx);
}

/* True if PFX is the start of the 2-byte REX2 prefix.  */

static bool
rex2_prefix_p (gdb_byte pfx)
{
  return pfx == REX2_OPCODE;
}

/* True if PFX is the start of the 2-byte VEX prefix.  */

static bool
vex2_prefix_p (gdb_byte pfx)
{
  return pfx == 0xc5;
}

/* True if PFX is the start of the 3-byte VEX prefix.  */

static bool
vex3_prefix_p (gdb_byte pfx)
{
  return pfx == 0xc4;
}

/* Return true if PFX is the start of the 4-byte EVEX prefix.  */

static bool
evex_prefix_p (gdb_byte pfx)
{
  return pfx == 0x62;
}

/* Skip the legacy instruction prefixes in INSN.
   We assume INSN is properly sentineled so we don't have to worry
   about falling off the end of the buffer.  */

static gdb_byte *
amd64_skip_prefixes (gdb_byte *insn)
{
  while (1)
    {
      switch (*insn)
	{
	case DATA_PREFIX_OPCODE:
	case ADDR_PREFIX_OPCODE:
	case CS_PREFIX_OPCODE:
	case DS_PREFIX_OPCODE:
	case ES_PREFIX_OPCODE:
	case FS_PREFIX_OPCODE:
	case GS_PREFIX_OPCODE:
	case SS_PREFIX_OPCODE:
	case LOCK_PREFIX_OPCODE:
	case REPE_PREFIX_OPCODE:
	case REPNE_PREFIX_OPCODE:
	  ++insn;
	  continue;
	default:
	  break;
	}
      break;
    }

  return insn;
}

/* Return true if the MODRM byte of an insn indicates that the insn is
   rip-relative.  */

static bool
rip_relative_p (gdb_byte modrm)
{
  gdb_byte mod = MODRM_MOD_FIELD (modrm);
  gdb_byte rm = MODRM_RM_FIELD (modrm);

  return mod == 0 && rm == 0x05;
}

/* Return a register mask for the integer registers that are used as an input
   operand in INSN.  If !ASSUMPTIONS, only return the registers we actually
   found, for the benefit of self tests.  */

static uint32_t
amd64_get_used_input_int_regs (const struct amd64_insn *details,
			       bool assumptions = true)
{
  /* 1 bit for each reg */
  uint32_t used_regs_mask = 0;

  if (assumptions)
    {
      /* Assume RAX is used.  If not, we'd have to detect opcodes that implicitly
	 use RAX.  */
      used_regs_mask |= 1 << EAX_REG_NUM;
      /* Assume RDX is used.  If not, we'd have to detect opcodes that implicitly
	 use RDX, like divides.  */
      used_regs_mask |= 1 << EDX_REG_NUM;
    }

  /* If the opcode is one byte long and there's no ModRM byte,
     assume the opcode specifies a register.  */
  if (details->opcode_len == 1 && details->modrm_offset == -1)
    used_regs_mask |= 1 << (details->raw_insn[details->opcode_offset] & 7);

  /* Mark used regs in the modrm/sib bytes.  */
  if (details->modrm_offset != -1)
    {
      int modrm = details->raw_insn[details->modrm_offset];
      int mod = MODRM_MOD_FIELD (modrm);
      int reg = MODRM_REG_FIELD (modrm);
      int rm = MODRM_RM_FIELD (modrm);
      int have_sib = mod != 3 && rm == 4;

      /* Assume the reg field of the modrm byte specifies a register.  */
      used_regs_mask |= 1 << reg;

      if (have_sib)
	{
	  int base = SIB_BASE_FIELD (details->raw_insn[details->modrm_offset + 1]);
	  int idx = SIB_INDEX_FIELD (details->raw_insn[details->modrm_offset + 1]);
	  used_regs_mask |= 1 << base;
	  used_regs_mask |= 1 << idx;
	}
      else if (!rip_relative_p (modrm))
	{
	  used_regs_mask |= 1 << rm;
	}
    }

  gdb_assert (used_regs_mask < 256);
  return used_regs_mask;
}

/* Return an integer register in ALLOWED_REGS_MASK that is unused as an input
   operand in INSN.  The register numbering of the result follows architecture
   ordering, e.g. RDI = 7.  Return -1 if no register can be found.  */

static int
amd64_get_unused_input_int_reg (const struct amd64_insn *details,
				uint32_t allowed_regs_mask)
{
  /* 1 bit for each reg */
  uint32_t used_regs_mask = amd64_get_used_input_int_regs (details);

  /* Finally, find a free reg.  */
  {
    int i;

    for (i = 0; i < 32; ++i)
      {
	if (! (allowed_regs_mask & (1 << i)))
	  continue;

	if (! (used_regs_mask & (1 << i)))
	  return i;
      }
  }

  return -1;
}

/* Extract the details of INSN that we need.  */

static void
amd64_get_insn_details (gdb_byte *insn, struct amd64_insn *details)
{
  gdb_byte *start = insn;
  int need_modrm;

  details->raw_insn = insn;

  details->opcode_len = -1;
  details->enc_prefix_offset = -1;
  details->opcode_offset = -1;
  details->modrm_offset = -1;

  /* Skip legacy instruction prefixes.  */
  insn = amd64_skip_prefixes (insn);

  /* Skip REX/VEX instruction encoding prefixes.  */
  if (rex_prefix_p (*insn))
    {
      details->enc_prefix_offset = insn - start;
      ++insn;
    }
  else if (rex2_prefix_p (*insn))
    {
      details->enc_prefix_offset = insn - start;
      insn += 2;
    }
  else if (vex2_prefix_p (*insn))
    {
      details->enc_prefix_offset = insn - start;
      insn += 2;
    }
  else if (vex3_prefix_p (*insn))
    {
      details->enc_prefix_offset = insn - start;
      insn += 3;
    }
  else if (evex_prefix_p (*insn))
    {
      details->enc_prefix_offset = insn - start;
      insn += 4;
    }
  gdb_byte *prefix = (details->enc_prefix_offset == -1
		      ? nullptr
		      : &start[details->enc_prefix_offset]);

  details->opcode_offset = insn - start;

  if (prefix != nullptr && rex2_prefix_p (*prefix))
    {
      bool m = (prefix[1] & (REX2_M << 4)) != 0;
      if (!m)
	{
	  need_modrm = onebyte_has_modrm[*insn];
	  details->opcode_len = 1;
	}
      else
	{
	  need_modrm = twobyte_has_modrm[*insn];
	  details->opcode_len = 2;
	}
    }
  else if (prefix != nullptr && vex2_prefix_p (*prefix))
    {
      need_modrm = twobyte_has_modrm[*insn];
      details->opcode_len = 2;
    }
  else if (prefix != nullptr && vex3_prefix_p (*prefix))
    {
      need_modrm = twobyte_has_modrm[*insn];

      gdb_byte m = prefix[1] & 0x1f;
      if (m == 0)
	{
	  /* Todo: Xeon Phi-specific JKZD/JKNZD.  */
	  return;
	}
      else if (m == 1)
	{
	  /* Escape 0x0f.  */
	  details->opcode_len = 2;
	}
      else if (m == 2 || m == 3)
	{
	  /* Escape 0x0f 0x38 or 0x0f 0x3a.  */
	  details->opcode_len = 3;
	}
      else if (m == 7)
	{
	  /* Todo: URDMSR/UWRMSR instructions.  */
	  return;
	}
      else
	{
	  /* Unknown opcode map.  */
	  return;
	}
    }
  else if (prefix != nullptr && evex_prefix_p (*prefix))
    {
      need_modrm = twobyte_has_modrm[*insn];

      gdb_byte m = prefix[1] & 0x7;
      if (m == 1)
	{
	  /* Escape 0x0f.  */
	  details->opcode_len = 2;
	}
      else if (m == 2 || m == 3)
	{
	  /* Escape 0x0f 0x38 or 0x0f 0x3a.  */
	  details->opcode_len = 3;
	}
      else
	{
	  /* Unknown opcode map.  */
	  return;
	}
    }
  else if (*insn == TWO_BYTE_OPCODE_ESCAPE)
    {
      /* Two or three-byte opcode.  */
      ++insn;
      need_modrm = twobyte_has_modrm[*insn];

      /* Check for three-byte opcode.  */
      switch (*insn)
	{
	case 0x24:
	case 0x25:
	case 0x38:
	case 0x3a:
	case 0x7a:
	case 0x7b:
	  ++insn;
	  details->opcode_len = 3;
	  break;
	default:
	  details->opcode_len = 2;
	  break;
	}
    }
  else
    {
      /* One-byte opcode.  */
      need_modrm = onebyte_has_modrm[*insn];
      details->opcode_len = 1;
    }

  if (need_modrm)
    {
      ++insn;
      details->modrm_offset = insn - start;
    }
}

/* Convert a %rip-relative INSN to use BASEREG+disp addressing, leaving
   displacement unchanged.  */

static void
fixup_riprel (const struct amd64_insn &details, gdb_byte *insn,
	      int basereg)
{
  /* Position of the not-B bit in the 3-byte VEX prefix (in byte 1).  */
  static constexpr gdb_byte VEX3_NOT_B = 0x20;

  /* Position of the B3 and B4 bits in the REX2 prefix (in byte 1).  */
  static constexpr gdb_byte REX2_B = 0x11;

  /* Position of the not-B3 bit in the EVEX prefix (in byte 1).  */
  static constexpr gdb_byte EVEX_NOT_B = VEX3_NOT_B;

  /* Position of the B4 bit in the EVEX prefix (in byte 1).  */
  static constexpr gdb_byte EVEX_B = 0x08;

  /* REX.B should be unset (VEX.!B set) as we were using rip-relative
     addressing, but ensure it's unset (set for VEX) anyway, tmp_regno
     is not r8-r15.  */
  if (details.enc_prefix_offset != -1)
    {
      gdb_byte *pfx = &insn[details.enc_prefix_offset];
      if (rex_prefix_p (pfx[0]))
	pfx[0] &= ~REX_B;
      else if (rex2_prefix_p (pfx[0]))
	pfx[1] &= ~REX2_B;
      else if (vex2_prefix_p (pfx[0]))
	{
	  /* VEX.!B is set implicitly.  */
	}
      else if (vex3_prefix_p (pfx[0]))
	pfx[1] |= VEX3_NOT_B;
      else if (evex_prefix_p (pfx[0]))
	{
	  pfx[1] |= EVEX_NOT_B;
	  pfx[1] &= ~EVEX_B;
	}
      else
	gdb_assert_not_reached ("unhandled prefix");
    }

  int modrm_offset = details.modrm_offset;
  /* Convert the ModRM field to be base+disp.  */
  insn[modrm_offset] &= ~0xc7;
  insn[modrm_offset] |= 0x80 + basereg;
}

/* Update %rip-relative addressing in INSN.

   %rip-relative addressing only uses a 32-bit displacement.
   32 bits is not enough to be guaranteed to cover the distance between where
   the real instruction is and where its copy is.
   Convert the insn to use base+disp addressing.
   We set base = pc + insn_length so we can leave disp unchanged.
   Return true if successful, false otherwise.  */

static bool
fixup_riprel (struct gdbarch *gdbarch,
	      amd64_displaced_step_copy_insn_closure *dsc,
	      CORE_ADDR from, CORE_ADDR to, struct regcache *regs)
{
  const struct amd64_insn *insn_details = &dsc->insn_details;
  CORE_ADDR rip_base;
  int insn_length;
  int arch_tmp_regno, tmp_regno;
  ULONGEST orig_value;

  /* Compute the rip-relative address.	*/
  insn_length = gdb_buffered_insn_length (gdbarch, dsc->insn_buf.data (),
					  dsc->insn_buf.size (), from);
  rip_base = from + insn_length;

  /* We need a register to hold the address.  Pick one not used in the insn.
     In order to not require adding a rex prefix if the insn doesn't already
     have one, the range is restricted to RAX ... RDI, without RSP.
     We avoid RSP, because when patched into in the modrm byte, it doesn't
     indicate the use of the register, but instead the use of a SIB byte.  */
  uint32_t allowed_regs_mask = 0xff & ~(1 << ESP_REG_NUM);
  arch_tmp_regno
    = amd64_get_unused_input_int_reg (insn_details, allowed_regs_mask);
  if (arch_tmp_regno == -1)
    return false;

  fixup_riprel (dsc->insn_details, dsc->insn_buf.data (), arch_tmp_regno);

  /* Convert arch_tmp_regno, which uses architecture ordering (e.g. RDI = 7),
     to GDB regnum.  */
  tmp_regno = amd64_arch_reg_to_regnum (arch_tmp_regno);

  regcache_cooked_read_unsigned (regs, tmp_regno, &orig_value);
  dsc->tmp_regno = tmp_regno;
  dsc->tmp_save = orig_value;
  dsc->tmp_used = 1;

  regcache_cooked_write_unsigned (regs, tmp_regno, rip_base);

  displaced_debug_printf ("%%rip-relative addressing used.");
  displaced_debug_printf ("using temp reg %d, old value %s, new value %s",
			  dsc->tmp_regno, paddress (gdbarch, dsc->tmp_save),
			  paddress (gdbarch, rip_base));
  return true;
}

/* Fixup the insn in DSC->insn_buf, which was copied from address FROM to TO.
   Return true if successful, false otherwise.  */

static bool
fixup_displaced_copy (struct gdbarch *gdbarch,
		      amd64_displaced_step_copy_insn_closure *dsc,
		      CORE_ADDR from, CORE_ADDR to, struct regcache *regs)
{
  const struct amd64_insn *details = &dsc->insn_details;

  if (details->modrm_offset != -1)
    {
      gdb_byte modrm = details->raw_insn[details->modrm_offset];

      if (rip_relative_p (modrm))
	{
	  /* The insn uses rip-relative addressing.
	     Deal with it.  */
	  return fixup_riprel (gdbarch, dsc, from, to, regs);
	}
    }

  return true;
}

displaced_step_copy_insn_closure_up
amd64_displaced_step_copy_insn (struct gdbarch *gdbarch,
				CORE_ADDR from, CORE_ADDR to,
				struct regcache *regs)
{
  int len = gdbarch_max_insn_length (gdbarch);
  /* Extra space for sentinels so fixup_{riprel,displaced_copy} don't have to
     continually watch for running off the end of the buffer.  */
  int fixup_sentinel_space = len;
  std::unique_ptr<amd64_displaced_step_copy_insn_closure> dsc
    (new amd64_displaced_step_copy_insn_closure (len + fixup_sentinel_space));
  gdb_byte *buf = &dsc->insn_buf[0];
  struct amd64_insn *details = &dsc->insn_details;

  read_memory (from, buf, len);

  /* Set up the sentinel space so we don't have to worry about running
     off the end of the buffer.  An excessive number of leading prefixes
     could otherwise cause this.  */
  memset (buf + len, 0, fixup_sentinel_space);

  amd64_get_insn_details (buf, details);
  if (details->opcode_len == -1)
    return nullptr;

  /* GDB may get control back after the insn after the syscall.
     Presumably this is a kernel bug.
     If this is a syscall, make sure there's a nop afterwards.  */
  {
    int syscall_length;

    if (amd64_syscall_p (details, &syscall_length))
      buf[details->opcode_offset + syscall_length] = NOP_OPCODE;
  }

  /* Modify the insn to cope with the address where it will be executed from.
     In particular, handle any rip-relative addressing.	 */
  if (!fixup_displaced_copy (gdbarch, dsc.get (), from, to, regs))
    return nullptr;

  write_memory (to, buf, len);

  displaced_debug_printf ("copy %s->%s: %s",
			  paddress (gdbarch, from), paddress (gdbarch, to),
			  bytes_to_string (buf, len).c_str ());

  /* This is a work around for a problem with g++ 4.8.  */
  return displaced_step_copy_insn_closure_up (dsc.release ());
}

static int
amd64_absolute_jmp_p (const struct amd64_insn *details)
{
  const gdb_byte *insn = &details->raw_insn[details->opcode_offset];

  if (insn[0] == 0xff)
    {
      /* jump near, absolute indirect (/4) */
      if ((insn[1] & 0x38) == 0x20)
	return 1;

      /* jump far, absolute indirect (/5) */
      if ((insn[1] & 0x38) == 0x28)
	return 1;
    }

  return 0;
}

/* Return non-zero if the instruction DETAILS is a jump, zero otherwise.  */

static int
amd64_jmp_p (const struct amd64_insn *details)
{
  const gdb_byte *insn = &details->raw_insn[details->opcode_offset];

  /* jump short, relative.  */
  if (insn[0] == 0xeb)
    return 1;

  /* jump near, relative.  */
  if (insn[0] == 0xe9)
    return 1;

  return amd64_absolute_jmp_p (details);
}

static int
amd64_absolute_call_p (const struct amd64_insn *details)
{
  const gdb_byte *insn = &details->raw_insn[details->opcode_offset];

  if (insn[0] == 0xff)
    {
      /* Call near, absolute indirect (/2) */
      if ((insn[1] & 0x38) == 0x10)
	return 1;

      /* Call far, absolute indirect (/3) */
      if ((insn[1] & 0x38) == 0x18)
	return 1;
    }

  return 0;
}

static int
amd64_ret_p (const struct amd64_insn *details)
{
  /* NOTE: gcc can emit "repz ; ret".  */
  const gdb_byte *insn = &details->raw_insn[details->opcode_offset];

  switch (insn[0])
    {
    case 0xc2: /* ret near, pop N bytes */
    case 0xc3: /* ret near */
    case 0xca: /* ret far, pop N bytes */
    case 0xcb: /* ret far */
    case 0xcf: /* iret */
      return 1;

    default:
      return 0;
    }
}

static int
amd64_call_p (const struct amd64_insn *details)
{
  const gdb_byte *insn = &details->raw_insn[details->opcode_offset];

  if (amd64_absolute_call_p (details))
    return 1;

  /* call near, relative */
  if (insn[0] == 0xe8)
    return 1;

  return 0;
}

/* Return non-zero if INSN is a system call, and set *LENGTHP to its
   length in bytes.  Otherwise, return zero.  */

static int
amd64_syscall_p (const struct amd64_insn *details, int *lengthp)
{
  const gdb_byte *insn = &details->raw_insn[details->opcode_offset];

  if (insn[0] == 0x0f && insn[1] == 0x05)
    {
      *lengthp = 2;
      return 1;
    }

  return 0;
}

/* Classify the instruction at ADDR using PRED.
   Throw an error if the memory can't be read.  */

static int
amd64_classify_insn_at (struct gdbarch *gdbarch, CORE_ADDR addr,
			int (*pred) (const struct amd64_insn *))
{
  struct amd64_insn details;

  gdb::byte_vector buf (gdbarch_max_insn_length (gdbarch));

  read_code (addr, buf.data (), buf.size ());
  amd64_get_insn_details (buf.data (), &details);

  int classification = pred (&details);

  return classification;
}

/* The gdbarch insn_is_call method.  */

static int
amd64_insn_is_call (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return amd64_classify_insn_at (gdbarch, addr, amd64_call_p);
}

/* The gdbarch insn_is_ret method.  */

static int
amd64_insn_is_ret (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return amd64_classify_insn_at (gdbarch, addr, amd64_ret_p);
}

/* The gdbarch insn_is_jump method.  */

static int
amd64_insn_is_jump (struct gdbarch *gdbarch, CORE_ADDR addr)
{
  return amd64_classify_insn_at (gdbarch, addr, amd64_jmp_p);
}

/* Fix up the state of registers and memory after having single-stepped
   a displaced instruction.  */

void
amd64_displaced_step_fixup (struct gdbarch *gdbarch,
			    struct displaced_step_copy_insn_closure *dsc_,
			    CORE_ADDR from, CORE_ADDR to,
			    struct regcache *regs, bool completed_p)
{
  amd64_displaced_step_copy_insn_closure *dsc
    = (amd64_displaced_step_copy_insn_closure *) dsc_;
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  /* The offset we applied to the instruction's address.  */
  ULONGEST insn_offset = to - from;
  gdb_byte *insn = dsc->insn_buf.data ();
  const struct amd64_insn *insn_details = &dsc->insn_details;

  displaced_debug_printf ("fixup (%s, %s), insn = 0x%02x 0x%02x ...",
			  paddress (gdbarch, from), paddress (gdbarch, to),
			  insn[0], insn[1]);

  /* If we used a tmp reg, restore it.	*/

  if (dsc->tmp_used)
    {
      displaced_debug_printf ("restoring reg %d to %s",
			      dsc->tmp_regno, paddress (gdbarch, dsc->tmp_save));
      regcache_cooked_write_unsigned (regs, dsc->tmp_regno, dsc->tmp_save);
    }

  /* The list of issues to contend with here is taken from
     resume_execution in arch/x86/kernel/kprobes.c, Linux 2.6.28.
     Yay for Free Software!  */

  /* Relocate the %rip back to the program's instruction stream,
     if necessary.  */

  /* Except in the case of absolute or indirect jump or call
     instructions, or a return instruction, the new rip is relative to
     the displaced instruction; make it relative to the original insn.
     Well, signal handler returns don't need relocation either, but we use the
     value of %rip to recognize those; see below.  */
  if (!completed_p
      || (!amd64_absolute_jmp_p (insn_details)
	  && !amd64_absolute_call_p (insn_details)
	  && !amd64_ret_p (insn_details)))
    {
      int insn_len;

      CORE_ADDR pc = regcache_read_pc (regs);

      /* A signal trampoline system call changes the %rip, resuming
	 execution of the main program after the signal handler has
	 returned.  That makes them like 'return' instructions; we
	 shouldn't relocate %rip.

	 But most system calls don't, and we do need to relocate %rip.

	 Our heuristic for distinguishing these cases: if stepping
	 over the system call instruction left control directly after
	 the instruction, the we relocate --- control almost certainly
	 doesn't belong in the displaced copy.	Otherwise, we assume
	 the instruction has put control where it belongs, and leave
	 it unrelocated.  Goodness help us if there are PC-relative
	 system calls.	*/
      if (amd64_syscall_p (insn_details, &insn_len)
	  /* GDB can get control back after the insn after the syscall.
	     Presumably this is a kernel bug.  Fixup ensures it's a nop, we
	     add one to the length for it.  */
	  && (pc < to || pc > (to + insn_len + 1)))
	displaced_debug_printf ("syscall changed %%rip; not relocating");
      else
	{
	  CORE_ADDR rip = pc - insn_offset;

	  /* If we just stepped over a breakpoint insn, we don't backup
	     the pc on purpose; this is to match behavior without
	     stepping.  */

	  regcache_write_pc (regs, rip);

	  displaced_debug_printf ("relocated %%rip from %s to %s",
				  paddress (gdbarch, pc),
				  paddress (gdbarch, rip));
	}
    }

  /* If the instruction was PUSHFL, then the TF bit will be set in the
     pushed value, and should be cleared.  We'll leave this for later,
     since GDB already messes up the TF flag when stepping over a
     pushfl.  */

  /* If the instruction was a call, the return address now atop the
     stack is the address following the copied instruction.  We need
     to make it the address following the original instruction.	 */
  if (completed_p && amd64_call_p (insn_details))
    {
      ULONGEST rsp;
      ULONGEST retaddr;
      const ULONGEST retaddr_len = 8;

      regcache_cooked_read_unsigned (regs, AMD64_RSP_REGNUM, &rsp);
      retaddr = read_memory_unsigned_integer (rsp, retaddr_len, byte_order);
      retaddr = (retaddr - insn_offset) & 0xffffffffffffffffULL;
      write_memory_unsigned_integer (rsp, retaddr_len, byte_order, retaddr);

      displaced_debug_printf ("relocated return addr at %s to %s",
			      paddress (gdbarch, rsp),
			      paddress (gdbarch, retaddr));
    }
}

/* If the instruction INSN uses RIP-relative addressing, return the
   offset into the raw INSN where the displacement to be adjusted is
   found.  Returns 0 if the instruction doesn't use RIP-relative
   addressing.  */

static int
rip_relative_offset (struct amd64_insn *insn)
{
  if (insn->modrm_offset != -1)
    {
      gdb_byte modrm = insn->raw_insn[insn->modrm_offset];

      if (rip_relative_p (modrm))
	{
	  /* The displacement is found right after the ModRM byte.  */
	  return insn->modrm_offset + 1;
	}
    }

  return 0;
}

static void
append_insns (CORE_ADDR *to, ULONGEST len, const gdb_byte *buf)
{
  target_write_memory (*to, buf, len);
  *to += len;
}

static void
amd64_relocate_instruction (struct gdbarch *gdbarch,
			    CORE_ADDR *to, CORE_ADDR oldloc)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  int len = gdbarch_max_insn_length (gdbarch);
  /* Extra space for sentinels.  */
  int fixup_sentinel_space = len;
  gdb::byte_vector buf (len + fixup_sentinel_space);
  struct amd64_insn insn_details;
  int offset = 0;
  LONGEST rel32, newrel;
  gdb_byte *insn;
  int insn_length;

  read_memory (oldloc, buf.data (), len);

  /* Set up the sentinel space so we don't have to worry about running
     off the end of the buffer.  An excessive number of leading prefixes
     could otherwise cause this.  */
  memset (buf.data () + len, 0, fixup_sentinel_space);

  insn = buf.data ();
  amd64_get_insn_details (insn, &insn_details);

  insn_length = gdb_buffered_insn_length (gdbarch, insn, len, oldloc);

  /* Skip legacy instruction prefixes.  */
  insn = amd64_skip_prefixes (insn);

  /* Adjust calls with 32-bit relative addresses as push/jump, with
     the address pushed being the location where the original call in
     the user program would return to.  */
  if (insn[0] == 0xe8)
    {
      gdb_byte push_buf[32];
      CORE_ADDR ret_addr;
      int i = 0;

      /* Where "ret" in the original code will return to.  */
      ret_addr = oldloc + insn_length;

      /* If pushing an address higher than or equal to 0x80000000,
	 avoid 'pushq', as that sign extends its 32-bit operand, which
	 would be incorrect.  */
      if (ret_addr <= 0x7fffffff)
	{
	  push_buf[0] = 0x68; /* pushq $...  */
	  store_unsigned_integer (&push_buf[1], 4, byte_order, ret_addr);
	  i = 5;
	}
      else
	{
	  push_buf[i++] = 0x48; /* sub    $0x8,%rsp */
	  push_buf[i++] = 0x83;
	  push_buf[i++] = 0xec;
	  push_buf[i++] = 0x08;

	  push_buf[i++] = 0xc7; /* movl    $imm,(%rsp) */
	  push_buf[i++] = 0x04;
	  push_buf[i++] = 0x24;
	  store_unsigned_integer (&push_buf[i], 4, byte_order,
				  ret_addr & 0xffffffff);
	  i += 4;

	  push_buf[i++] = 0xc7; /* movl    $imm,4(%rsp) */
	  push_buf[i++] = 0x44;
	  push_buf[i++] = 0x24;
	  push_buf[i++] = 0x04;
	  store_unsigned_integer (&push_buf[i], 4, byte_order,
				  ret_addr >> 32);
	  i += 4;
	}
      gdb_assert (i <= sizeof (push_buf));
      /* Push the push.  */
      append_insns (to, i, push_buf);

      /* Convert the relative call to a relative jump.  */
      insn[0] = 0xe9;

      /* Adjust the destination offset.  */
      rel32 = extract_signed_integer (insn + 1, 4, byte_order);
      newrel = (oldloc - *to) + rel32;
      store_signed_integer (insn + 1, 4, byte_order, newrel);

      displaced_debug_printf ("adjusted insn rel32=%s at %s to rel32=%s at %s",
			      hex_string (rel32), paddress (gdbarch, oldloc),
			      hex_string (newrel), paddress (gdbarch, *to));

      /* Write the adjusted jump into its displaced location.  */
      append_insns (to, 5, insn);
      return;
    }

  offset = rip_relative_offset (&insn_details);
  if (!offset)
    {
      /* Adjust jumps with 32-bit relative addresses.  Calls are
	 already handled above.  */
      if (insn[0] == 0xe9)
	offset = 1;
      /* Adjust conditional jumps.  */
      else if (insn[0] == 0x0f && (insn[1] & 0xf0) == 0x80)
	offset = 2;
    }

  if (offset)
    {
      rel32 = extract_signed_integer (insn + offset, 4, byte_order);
      newrel = (oldloc - *to) + rel32;
      store_signed_integer (insn + offset, 4, byte_order, newrel);
      displaced_debug_printf ("adjusted insn rel32=%s at %s to rel32=%s at %s",
			      hex_string (rel32), paddress (gdbarch, oldloc),
			      hex_string (newrel), paddress (gdbarch, *to));
    }

  /* Write the adjusted instruction into its displaced location.  */
  append_insns (to, insn_length, buf.data ());
}


/* The maximum number of saved registers.  This should include %rip.  */
#define AMD64_NUM_SAVED_REGS	AMD64_NUM_GREGS

struct amd64_frame_cache
{
  /* Base address.  */
  CORE_ADDR base;
  int base_p;
  CORE_ADDR sp_offset;
  CORE_ADDR pc;

  /* Saved registers.  */
  CORE_ADDR saved_regs[AMD64_NUM_SAVED_REGS];
  CORE_ADDR saved_sp;
  int saved_sp_reg;

  /* Do we have a frame?  */
  int frameless_p;
};

/* Initialize a frame cache.  */

static void
amd64_init_frame_cache (struct amd64_frame_cache *cache)
{
  int i;

  /* Base address.  */
  cache->base = 0;
  cache->base_p = 0;
  cache->sp_offset = -8;
  cache->pc = 0;

  /* Saved registers.  We initialize these to -1 since zero is a valid
     offset (that's where %rbp is supposed to be stored).
     The values start out as being offsets, and are later converted to
     addresses (at which point -1 is interpreted as an address, still meaning
     "invalid").  */
  for (i = 0; i < AMD64_NUM_SAVED_REGS; i++)
    cache->saved_regs[i] = -1;
  cache->saved_sp = 0;
  cache->saved_sp_reg = -1;

  /* Frameless until proven otherwise.  */
  cache->frameless_p = 1;
}

/* Allocate and initialize a frame cache.  */

static struct amd64_frame_cache *
amd64_alloc_frame_cache (void)
{
  struct amd64_frame_cache *cache;

  cache = FRAME_OBSTACK_ZALLOC (struct amd64_frame_cache);
  amd64_init_frame_cache (cache);
  return cache;
}

/* GCC 4.4 and later, can put code in the prologue to realign the
   stack pointer.  Check whether PC points to such code, and update
   CACHE accordingly.  Return the first instruction after the code
   sequence or CURRENT_PC, whichever is smaller.  If we don't
   recognize the code, return PC.  */

static CORE_ADDR
amd64_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
			   struct amd64_frame_cache *cache)
{
  /* There are 2 code sequences to re-align stack before the frame
     gets set up:

	1. Use a caller-saved saved register:

		leaq  8(%rsp), %reg
		andq  $-XXX, %rsp
		pushq -8(%reg)

	2. Use a callee-saved saved register:

		pushq %reg
		leaq  16(%rsp), %reg
		andq  $-XXX, %rsp
		pushq -8(%reg)

     "andq $-XXX, %rsp" can be either 4 bytes or 7 bytes:
     
	0x48 0x83 0xe4 0xf0			andq $-16, %rsp
	0x48 0x81 0xe4 0x00 0xff 0xff 0xff	andq $-256, %rsp
   */

  gdb_byte buf[18];
  int reg, r;
  int offset, offset_and;

  if (target_read_code (pc, buf, sizeof buf))
    return pc;

  /* Check caller-saved saved register.  The first instruction has
     to be "leaq 8(%rsp), %reg".  */
  if ((buf[0] & 0xfb) == 0x48
      && buf[1] == 0x8d
      && buf[3] == 0x24
      && buf[4] == 0x8)
    {
      /* MOD must be binary 10 and R/M must be binary 100.  */
      if ((buf[2] & 0xc7) != 0x44)
	return pc;

      /* REG has register number.  */
      reg = (buf[2] >> 3) & 7;

      /* Check the REX.R bit.  */
      if (buf[0] == 0x4c)
	reg += 8;

      offset = 5;
    }
  else
    {
      /* Check callee-saved saved register.  The first instruction
	 has to be "pushq %reg".  */
      reg = 0;
      if ((buf[0] & 0xf8) == 0x50)
	offset = 0;
      else if ((buf[0] & 0xf6) == 0x40
	       && (buf[1] & 0xf8) == 0x50)
	{
	  /* Check the REX.B bit.  */
	  if ((buf[0] & 1) != 0)
	    reg = 8;

	  offset = 1;
	}
      else
	return pc;

      /* Get register.  */
      reg += buf[offset] & 0x7;

      offset++;

      /* The next instruction has to be "leaq 16(%rsp), %reg".  */
      if ((buf[offset] & 0xfb) != 0x48
	  || buf[offset + 1] != 0x8d
	  || buf[offset + 3] != 0x24
	  || buf[offset + 4] != 0x10)
	return pc;

      /* MOD must be binary 10 and R/M must be binary 100.  */
      if ((buf[offset + 2] & 0xc7) != 0x44)
	return pc;
      
      /* REG has register number.  */
      r = (buf[offset + 2] >> 3) & 7;

      /* Check the REX.R bit.  */
      if (buf[offset] == 0x4c)
	r += 8;

      /* Registers in pushq and leaq have to be the same.  */
      if (reg != r)
	return pc;

      offset += 5;
    }

  /* Rigister can't be %rsp nor %rbp.  */
  if (reg == 4 || reg == 5)
    return pc;

  /* The next instruction has to be "andq $-XXX, %rsp".  */
  if (buf[offset] != 0x48
      || buf[offset + 2] != 0xe4
      || (buf[offset + 1] != 0x81 && buf[offset + 1] != 0x83))
    return pc;

  offset_and = offset;
  offset += buf[offset + 1] == 0x81 ? 7 : 4;

  /* The next instruction has to be "pushq -8(%reg)".  */
  r = 0;
  if (buf[offset] == 0xff)
    offset++;
  else if ((buf[offset] & 0xf6) == 0x40
	   && buf[offset + 1] == 0xff)
    {
      /* Check the REX.B bit.  */
      if ((buf[offset] & 0x1) != 0)
	r = 8;
      offset += 2;
    }
  else
    return pc;

  /* 8bit -8 is 0xf8.  REG must be binary 110 and MOD must be binary
     01.  */
  if (buf[offset + 1] != 0xf8
      || (buf[offset] & 0xf8) != 0x70)
    return pc;

  /* R/M has register.  */
  r += buf[offset] & 7;

  /* Registers in leaq and pushq have to be the same.  */
  if (reg != r)
    return pc;

  if (current_pc > pc + offset_and)
    cache->saved_sp_reg = amd64_arch_reg_to_regnum (reg);

  return std::min (pc + offset + 2, current_pc);
}

/* Similar to amd64_analyze_stack_align for x32.  */

static CORE_ADDR
amd64_x32_analyze_stack_align (CORE_ADDR pc, CORE_ADDR current_pc,
			       struct amd64_frame_cache *cache) 
{
  /* There are 2 code sequences to re-align stack before the frame
     gets set up:

	1. Use a caller-saved saved register:

		leaq  8(%rsp), %reg
		andq  $-XXX, %rsp
		pushq -8(%reg)

	   or

		[addr32] leal  8(%rsp), %reg
		andl  $-XXX, %esp
		[addr32] pushq -8(%reg)

	2. Use a callee-saved saved register:

		pushq %reg
		leaq  16(%rsp), %reg
		andq  $-XXX, %rsp
		pushq -8(%reg)

	   or

		pushq %reg
		[addr32] leal  16(%rsp), %reg
		andl  $-XXX, %esp
		[addr32] pushq -8(%reg)

     "andq $-XXX, %rsp" can be either 4 bytes or 7 bytes:
     
	0x48 0x83 0xe4 0xf0			andq $-16, %rsp
	0x48 0x81 0xe4 0x00 0xff 0xff 0xff	andq $-256, %rsp

     "andl $-XXX, %esp" can be either 3 bytes or 6 bytes:
     
	0x83 0xe4 0xf0			andl $-16, %esp
	0x81 0xe4 0x00 0xff 0xff 0xff	andl $-256, %esp
   */

  gdb_byte buf[19];
  int reg, r;
  int offset, offset_and;

  if (target_read_memory (pc, buf, sizeof buf))
    return pc;

  /* Skip optional addr32 prefix.  */
  offset = buf[0] == 0x67 ? 1 : 0;

  /* Check caller-saved saved register.  The first instruction has
     to be "leaq 8(%rsp), %reg" or "leal 8(%rsp), %reg".  */
  if (((buf[offset] & 0xfb) == 0x48 || (buf[offset] & 0xfb) == 0x40)
      && buf[offset + 1] == 0x8d
      && buf[offset + 3] == 0x24
      && buf[offset + 4] == 0x8)
    {
      /* MOD must be binary 10 and R/M must be binary 100.  */
      if ((buf[offset + 2] & 0xc7) != 0x44)
	return pc;

      /* REG has register number.  */
      reg = (buf[offset + 2] >> 3) & 7;

      /* Check the REX.R bit.  */
      if ((buf[offset] & 0x4) != 0)
	reg += 8;

      offset += 5;
    }
  else
    {
      /* Check callee-saved saved register.  The first instruction
	 has to be "pushq %reg".  */
      reg = 0;
      if ((buf[offset] & 0xf6) == 0x40
	  && (buf[offset + 1] & 0xf8) == 0x50)
	{
	  /* Check the REX.B bit.  */
	  if ((buf[offset] & 1) != 0)
	    reg = 8;

	  offset += 1;
	}
      else if ((buf[offset] & 0xf8) != 0x50)
	return pc;

      /* Get register.  */
      reg += buf[offset] & 0x7;

      offset++;

      /* Skip optional addr32 prefix.  */
      if (buf[offset] == 0x67)
	offset++;

      /* The next instruction has to be "leaq 16(%rsp), %reg" or
	 "leal 16(%rsp), %reg".  */
      if (((buf[offset] & 0xfb) != 0x48 && (buf[offset] & 0xfb) != 0x40)
	  || buf[offset + 1] != 0x8d
	  || buf[offset + 3] != 0x24
	  || buf[offset + 4] != 0x10)
	return pc;

      /* MOD must be binary 10 and R/M must be binary 100.  */
      if ((buf[offset + 2] & 0xc7) != 0x44)
	return pc;
      
      /* REG has register number.  */
      r = (buf[offset + 2] >> 3) & 7;

      /* Check the REX.R bit.  */
      if ((buf[offset] & 0x4) != 0)
	r += 8;

      /* Registers in pushq and leaq have to be the same.  */
      if (reg != r)
	return pc;

      offset += 5;
    }

  /* Rigister can't be %rsp nor %rbp.  */
  if (reg == 4 || reg == 5)
    return pc;

  /* The next instruction may be "andq $-XXX, %rsp" or
     "andl $-XXX, %esp".  */
  if (buf[offset] != 0x48)
    offset--;

  if (buf[offset + 2] != 0xe4
      || (buf[offset + 1] != 0x81 && buf[offset + 1] != 0x83))
    return pc;

  offset_and = offset;
  offset += buf[offset + 1] == 0x81 ? 7 : 4;

  /* Skip optional addr32 prefix.  */
  if (buf[offset] == 0x67)
    offset++;

  /* The next instruction has to be "pushq -8(%reg)".  */
  r = 0;
  if (buf[offset] == 0xff)
    offset++;
  else if ((buf[offset] & 0xf6) == 0x40
	   && buf[offset + 1] == 0xff)
    {
      /* Check the REX.B bit.  */
      if ((buf[offset] & 0x1) != 0)
	r = 8;
      offset += 2;
    }
  else
    return pc;

  /* 8bit -8 is 0xf8.  REG must be binary 110 and MOD must be binary
     01.  */
  if (buf[offset + 1] != 0xf8
      || (buf[offset] & 0xf8) != 0x70)
    return pc;

  /* R/M has register.  */
  r += buf[offset] & 7;

  /* Registers in leaq and pushq have to be the same.  */
  if (reg != r)
    return pc;

  if (current_pc > pc + offset_and)
    cache->saved_sp_reg = amd64_arch_reg_to_regnum (reg);

  return std::min (pc + offset + 2, current_pc);
}

/* Do a limited analysis of the prologue at PC and update CACHE
   accordingly.  Bail out early if CURRENT_PC is reached.  Return the
   address where the analysis stopped.

   We will handle only functions beginning with:

      pushq %rbp        0x55
      movq %rsp, %rbp   0x48 0x89 0xe5 (or 0x48 0x8b 0xec)

   or (for the X32 ABI):

      pushq %rbp        0x55
      movl %esp, %ebp   0x89 0xe5 (or 0x8b 0xec)

   The `endbr64` instruction can be found before these sequences, and will be
   skipped if found.

   Any function that doesn't start with one of these sequences will be
   assumed to have no prologue and thus no valid frame pointer in
   %rbp.  */

static CORE_ADDR
amd64_analyze_prologue (struct gdbarch *gdbarch,
			CORE_ADDR pc, CORE_ADDR current_pc,
			struct amd64_frame_cache *cache)
{
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  /* The `endbr64` instruction.  */
  static const gdb_byte endbr64[4] = { 0xf3, 0x0f, 0x1e, 0xfa };
  /* There are two variations of movq %rsp, %rbp.  */
  static const gdb_byte mov_rsp_rbp_1[3] = { 0x48, 0x89, 0xe5 };
  static const gdb_byte mov_rsp_rbp_2[3] = { 0x48, 0x8b, 0xec };
  /* Ditto for movl %esp, %ebp.  */
  static const gdb_byte mov_esp_ebp_1[2] = { 0x89, 0xe5 };
  static const gdb_byte mov_esp_ebp_2[2] = { 0x8b, 0xec };

  gdb_byte buf[3];
  gdb_byte op;

  if (current_pc <= pc)
    return current_pc;

  if (gdbarch_ptr_bit (gdbarch) == 32)
    pc = amd64_x32_analyze_stack_align (pc, current_pc, cache);
  else
    pc = amd64_analyze_stack_align (pc, current_pc, cache);

  op = read_code_unsigned_integer (pc, 1, byte_order);

  /* Check for the `endbr64` instruction, skip it if found.  */
  if (op == endbr64[0])
    {
      read_code (pc + 1, buf, 3);

      if (memcmp (buf, &endbr64[1], 3) == 0)
	pc += 4;

      op = read_code_unsigned_integer (pc, 1, byte_order);
    }

  if (current_pc <= pc)
    return current_pc;

  if (op == 0x55)		/* pushq %rbp */
    {
      /* Take into account that we've executed the `pushq %rbp' that
	 starts this instruction sequence.  */
      cache->saved_regs[AMD64_RBP_REGNUM] = 0;
      cache->sp_offset += 8;

      /* If that's all, return now.  */
      if (current_pc <= pc + 1)
	return current_pc;

      read_code (pc + 1, buf, 3);

      /* Check for `movq %rsp, %rbp'.  */
      if (memcmp (buf, mov_rsp_rbp_1, 3) == 0
	  || memcmp (buf, mov_rsp_rbp_2, 3) == 0)
	{
	  /* OK, we actually have a frame.  */
	  cache->frameless_p = 0;
	  return pc + 4;
	}

      /* For X32, also check for `movl %esp, %ebp'.  */
      if (gdbarch_ptr_bit (gdbarch) == 32)
	{
	  if (memcmp (buf, mov_esp_ebp_1, 2) == 0
	      || memcmp (buf, mov_esp_ebp_2, 2) == 0)
	    {
	      /* OK, we actually have a frame.  */
	      cache->frameless_p = 0;
	      return pc + 3;
	    }
	}

      return pc + 1;
    }

  return pc;
}

/* Work around false termination of prologue - GCC PR debug/48827.

   START_PC is the first instruction of a function, PC is its minimal already
   determined advanced address.  Function returns PC if it has nothing to do.

   84 c0                test   %al,%al
   74 23                je     after
   <-- here is 0 lines advance - the false prologue end marker.
   0f 29 85 70 ff ff ff movaps %xmm0,-0x90(%rbp)
   0f 29 4d 80          movaps %xmm1,-0x80(%rbp)
   0f 29 55 90          movaps %xmm2,-0x70(%rbp)
   0f 29 5d a0          movaps %xmm3,-0x60(%rbp)
   0f 29 65 b0          movaps %xmm4,-0x50(%rbp)
   0f 29 6d c0          movaps %xmm5,-0x40(%rbp)
   0f 29 75 d0          movaps %xmm6,-0x30(%rbp)
   0f 29 7d e0          movaps %xmm7,-0x20(%rbp)
   after:  */

static CORE_ADDR
amd64_skip_xmm_prologue (CORE_ADDR pc, CORE_ADDR start_pc)
{
  struct symtab_and_line start_pc_sal, next_sal;
  gdb_byte buf[4 + 8 * 7];
  int offset, xmmreg;

  if (pc == start_pc)
    return pc;

  start_pc_sal = find_pc_sect_line (start_pc, NULL, 0);
  if (start_pc_sal.symtab == NULL
      || producer_is_gcc_ge_4 (start_pc_sal.symtab->compunit ()
			       ->producer ()) < 6
      || start_pc_sal.pc != start_pc || pc >= start_pc_sal.end)
    return pc;

  next_sal = find_pc_sect_line (start_pc_sal.end, NULL, 0);
  if (next_sal.line != start_pc_sal.line)
    return pc;

  /* START_PC can be from overlay memory, ignored here.  */
  if (target_read_code (next_sal.pc - 4, buf, sizeof (buf)) != 0)
    return pc;

  /* test %al,%al */
  if (buf[0] != 0x84 || buf[1] != 0xc0)
    return pc;
  /* je AFTER */
  if (buf[2] != 0x74)
    return pc;

  offset = 4;
  for (xmmreg = 0; xmmreg < 8; xmmreg++)
    {
      /* 0x0f 0x29 0b??000101 movaps %xmmreg?,-0x??(%rbp) */
      if (buf[offset] != 0x0f || buf[offset + 1] != 0x29
	  || (buf[offset + 2] & 0x3f) != (xmmreg << 3 | 0x5))
	return pc;

      /* 0b01?????? */
      if ((buf[offset + 2] & 0xc0) == 0x40)
	{
	  /* 8-bit displacement.  */
	  offset += 4;
	}
      /* 0b10?????? */
      else if ((buf[offset + 2] & 0xc0) == 0x80)
	{
	  /* 32-bit displacement.  */
	  offset += 7;
	}
      else
	return pc;
    }

  /* je AFTER */
  if (offset - 4 != buf[3])
    return pc;

  return next_sal.end;
}

/* Return PC of first real instruction.  */

static CORE_ADDR
amd64_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
{
  struct amd64_frame_cache cache;
  CORE_ADDR pc;
  CORE_ADDR func_addr;

  if (find_pc_partial_function (start_pc, NULL, &func_addr, NULL))
    {
      CORE_ADDR post_prologue_pc
	= skip_prologue_using_sal (gdbarch, func_addr);
      struct compunit_symtab *cust = find_pc_compunit_symtab (func_addr);

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

  amd64_init_frame_cache (&cache);
  pc = amd64_analyze_prologue (gdbarch, start_pc, 0xffffffffffffffffLL,
			       &cache);
  if (cache.frameless_p)
    return start_pc;

  return amd64_skip_xmm_prologue (pc, start_pc);
}


/* Normal frames.  */

static void
amd64_frame_cache_1 (const frame_info_ptr &this_frame,
		     struct amd64_frame_cache *cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  gdb_byte buf[8];
  int i;

  cache->pc = get_frame_func (this_frame);
  if (cache->pc != 0)
    amd64_analyze_prologue (gdbarch, cache->pc, get_frame_pc (this_frame),
			    cache);

  if (cache->frameless_p)
    {
      /* We didn't find a valid frame.  If we're at the start of a
	 function, or somewhere half-way its prologue, the function's
	 frame probably hasn't been fully setup yet.  Try to
	 reconstruct the base address for the stack frame by looking
	 at the stack pointer.  For truly "frameless" functions this
	 might work too.  */

      if (cache->saved_sp_reg != -1)
	{
	  /* Stack pointer has been saved.  */
	  get_frame_register (this_frame, cache->saved_sp_reg, buf);
	  cache->saved_sp = extract_unsigned_integer (buf, 8, byte_order);

	  /* We're halfway aligning the stack.  */
	  cache->base = ((cache->saved_sp - 8) & 0xfffffffffffffff0LL) - 8;
	  cache->saved_regs[AMD64_RIP_REGNUM] = cache->saved_sp - 8;

	  /* This will be added back below.  */
	  cache->saved_regs[AMD64_RIP_REGNUM] -= cache->base;
	}
      else
	{
	  get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
	  cache->base = extract_unsigned_integer (buf, 8, byte_order)
			+ cache->sp_offset;
	}
    }
  else
    {
      get_frame_register (this_frame, AMD64_RBP_REGNUM, buf);
      cache->base = extract_unsigned_integer (buf, 8, byte_order);
    }

  /* Now that we have the base address for the stack frame we can
     calculate the value of %rsp in the calling frame.  */
  cache->saved_sp = cache->base + 16;

  /* For normal frames, %rip is stored at 8(%rbp).  If we don't have a
     frame we find it at the same offset from the reconstructed base
     address.  If we're halfway aligning the stack, %rip is handled
     differently (see above).  */
  if (!cache->frameless_p || cache->saved_sp_reg == -1)
    cache->saved_regs[AMD64_RIP_REGNUM] = 8;

  /* Adjust all the saved registers such that they contain addresses
     instead of offsets.  */
  for (i = 0; i < AMD64_NUM_SAVED_REGS; i++)
    if (cache->saved_regs[i] != -1)
      cache->saved_regs[i] += cache->base;

  cache->base_p = 1;
}

static struct amd64_frame_cache *
amd64_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  struct amd64_frame_cache *cache;

  if (*this_cache)
    return (struct amd64_frame_cache *) *this_cache;

  cache = amd64_alloc_frame_cache ();
  *this_cache = cache;

  try
    {
      amd64_frame_cache_1 (this_frame, cache);
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error != NOT_AVAILABLE_ERROR)
	throw;
    }

  return cache;
}

static enum unwind_stop_reason
amd64_frame_unwind_stop_reason (const frame_info_ptr &this_frame,
				void **this_cache)
{
  struct amd64_frame_cache *cache =
    amd64_frame_cache (this_frame, this_cache);

  if (!cache->base_p)
    return UNWIND_UNAVAILABLE;

  /* This marks the outermost frame.  */
  if (cache->base == 0)
    return UNWIND_OUTERMOST;

  return UNWIND_NO_REASON;
}

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

  if (!cache->base_p)
    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
  else if (cache->base == 0)
    {
      /* This marks the outermost frame.  */
      return;
    }
  else
    (*this_id) = frame_id_build (cache->base + 16, cache->pc);
}

static struct value *
amd64_frame_prev_register (const frame_info_ptr &this_frame, void **this_cache,
			   int regnum)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  struct amd64_frame_cache *cache =
    amd64_frame_cache (this_frame, this_cache);

  gdb_assert (regnum >= 0);

  if (regnum == gdbarch_sp_regnum (gdbarch) && cache->saved_sp)
    return frame_unwind_got_constant (this_frame, regnum, cache->saved_sp);

  if (regnum < AMD64_NUM_SAVED_REGS && cache->saved_regs[regnum] != -1)
    return frame_unwind_got_memory (this_frame, regnum,
				    cache->saved_regs[regnum]);

  return frame_unwind_got_register (this_frame, regnum, regnum);
}

static const struct frame_unwind_legacy amd64_frame_unwind (
  "amd64 prologue",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  amd64_frame_unwind_stop_reason,
  amd64_frame_this_id,
  amd64_frame_prev_register,
  NULL,
  default_frame_sniffer
);

/* Generate a bytecode expression to get the value of the saved PC.  */

static void
amd64_gen_return_address (struct gdbarch *gdbarch,
			  struct agent_expr *ax, struct axs_value *value,
			  CORE_ADDR scope)
{
  /* The following sequence assumes the traditional use of the base
     register.  */
  ax_reg (ax, AMD64_RBP_REGNUM);
  ax_const_l (ax, 8);
  ax_simple (ax, aop_add);
  value->type = register_type (gdbarch, AMD64_RIP_REGNUM);
  value->kind = axs_lvalue_memory;
}


/* Signal trampolines.  */

/* FIXME: kettenis/20030419: Perhaps, we can unify the 32-bit and
   64-bit variants.  This would require using identical frame caches
   on both platforms.  */

static struct amd64_frame_cache *
amd64_sigtramp_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct amd64_frame_cache *cache;
  CORE_ADDR addr;
  gdb_byte buf[8];
  int i;

  if (*this_cache)
    return (struct amd64_frame_cache *) *this_cache;

  cache = amd64_alloc_frame_cache ();

  try
    {
      get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
      cache->base = extract_unsigned_integer (buf, 8, byte_order) - 8;

      addr = tdep->sigcontext_addr (this_frame);
      gdb_assert (tdep->sc_reg_offset);
      gdb_assert (tdep->sc_num_regs <= AMD64_NUM_SAVED_REGS);
      for (i = 0; i < tdep->sc_num_regs; i++)
	if (tdep->sc_reg_offset[i] != -1)
	  cache->saved_regs[i] = addr + tdep->sc_reg_offset[i];

      cache->base_p = 1;
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error != NOT_AVAILABLE_ERROR)
	throw;
    }

  *this_cache = cache;
  return cache;
}

static enum unwind_stop_reason
amd64_sigtramp_frame_unwind_stop_reason (const frame_info_ptr &this_frame,
					 void **this_cache)
{
  struct amd64_frame_cache *cache =
    amd64_sigtramp_frame_cache (this_frame, this_cache);

  if (!cache->base_p)
    return UNWIND_UNAVAILABLE;

  return UNWIND_NO_REASON;
}

static void
amd64_sigtramp_frame_this_id (const frame_info_ptr &this_frame,
			      void **this_cache, struct frame_id *this_id)
{
  struct amd64_frame_cache *cache =
    amd64_sigtramp_frame_cache (this_frame, this_cache);

  if (!cache->base_p)
    (*this_id) = frame_id_build_unavailable_stack (get_frame_pc (this_frame));
  else if (cache->base == 0)
    {
      /* This marks the outermost frame.  */
      return;
    }
  else
    (*this_id) = frame_id_build (cache->base + 16, get_frame_pc (this_frame));
}

static struct value *
amd64_sigtramp_frame_prev_register (const frame_info_ptr &this_frame,
				    void **this_cache, int regnum)
{
  /* Make sure we've initialized the cache.  */
  amd64_sigtramp_frame_cache (this_frame, this_cache);

  return amd64_frame_prev_register (this_frame, this_cache, regnum);
}

static int
amd64_sigtramp_frame_sniffer (const struct frame_unwind *self,
			      const frame_info_ptr &this_frame,
			      void **this_cache)
{
  gdbarch *arch = get_frame_arch (this_frame);
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (arch);

  /* We shouldn't even bother if we don't have a sigcontext_addr
     handler.  */
  if (tdep->sigcontext_addr == NULL)
    return 0;

  if (tdep->sigtramp_p != NULL)
    {
      if (tdep->sigtramp_p (this_frame))
	return 1;
    }

  if (tdep->sigtramp_start != 0)
    {
      CORE_ADDR pc = get_frame_pc (this_frame);

      gdb_assert (tdep->sigtramp_end != 0);
      if (pc >= tdep->sigtramp_start && pc < tdep->sigtramp_end)
	return 1;
    }

  return 0;
}

static const struct frame_unwind_legacy amd64_sigtramp_frame_unwind (
  "amd64 sigtramp",
  SIGTRAMP_FRAME,
  FRAME_UNWIND_ARCH,
  amd64_sigtramp_frame_unwind_stop_reason,
  amd64_sigtramp_frame_this_id,
  amd64_sigtramp_frame_prev_register,
  NULL,
  amd64_sigtramp_frame_sniffer
);


static CORE_ADDR
amd64_frame_base_address (const frame_info_ptr &this_frame, void **this_cache)
{
  struct amd64_frame_cache *cache =
    amd64_frame_cache (this_frame, this_cache);

  return cache->base;
}

static const struct frame_base amd64_frame_base =
{
  &amd64_frame_unwind,
  amd64_frame_base_address,
  amd64_frame_base_address,
  amd64_frame_base_address
};

/* Implement core of the stack_frame_destroyed_p gdbarch method.  */

static int
amd64_stack_frame_destroyed_p_1 (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  gdb_byte insn;

  std::optional<CORE_ADDR> epilogue = find_epilogue_using_linetable (pc);

  /* PC is pointing at the next instruction to be executed. If it is
     equal to the epilogue start, it means we're right before it starts,
     so the stack is still valid.  */
  if (epilogue)
    return pc > epilogue;

  if (target_read_memory (pc, &insn, 1))
    return 0;   /* Can't read memory at pc.  */

  if (insn != 0xc3)     /* 'ret' instruction.  */
    return 0;

  return 1;
}

/* Normal frames, but in a function epilogue.  */

/* Implement the stack_frame_destroyed_p gdbarch method.

   The epilogue is defined here as the 'ret' instruction, which will
   follow any instruction such as 'leave' or 'pop %ebp' that destroys
   the function's stack frame.  */

static int
amd64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  struct compunit_symtab *cust = find_pc_compunit_symtab (pc);

  if (cust != nullptr && cust->producer () != nullptr
      && producer_is_llvm (cust->producer ()))
    return amd64_stack_frame_destroyed_p_1 (gdbarch, pc);

  return 0;
}

static int
amd64_epilogue_frame_sniffer_1 (const struct frame_unwind *self,
				const frame_info_ptr &this_frame,
				void **this_prologue_cache, bool override_p)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  CORE_ADDR pc = get_frame_pc (this_frame);

  if (frame_relative_level (this_frame) != 0)
    /* We're not in the inner frame, so assume we're not in an epilogue.  */
    return 0;

  bool unwind_valid_p
    = compunit_epilogue_unwind_valid (find_pc_compunit_symtab (pc));
  if (override_p)
    {
      if (unwind_valid_p)
	/* Don't override the symtab unwinders, skip
	   "amd64 epilogue override".  */
	return 0;
    }
  else
    {
      if (!unwind_valid_p)
	/* "amd64 epilogue override" unwinder already ran, skip
	   "amd64 epilogue".  */
	return 0;
    }

  /* Check whether we're in an epilogue.  */
  return amd64_stack_frame_destroyed_p_1 (gdbarch, pc);
}

static int
amd64_epilogue_override_frame_sniffer (const struct frame_unwind *self,
				       const frame_info_ptr &this_frame,
				       void **this_prologue_cache)
{
  return amd64_epilogue_frame_sniffer_1 (self, this_frame, this_prologue_cache,
					 true);
}

static int
amd64_epilogue_frame_sniffer (const struct frame_unwind *self,
			      const frame_info_ptr &this_frame,
			      void **this_prologue_cache)
{
  return amd64_epilogue_frame_sniffer_1 (self, this_frame, this_prologue_cache,
					 false);
}

static struct amd64_frame_cache *
amd64_epilogue_frame_cache (const frame_info_ptr &this_frame, void **this_cache)
{
  struct gdbarch *gdbarch = get_frame_arch (this_frame);
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  struct amd64_frame_cache *cache;
  gdb_byte buf[8];

  if (*this_cache)
    return (struct amd64_frame_cache *) *this_cache;

  cache = amd64_alloc_frame_cache ();
  *this_cache = cache;

  try
    {
      /* Cache base will be %rsp plus cache->sp_offset (-8).  */
      get_frame_register (this_frame, AMD64_RSP_REGNUM, buf);
      cache->base = extract_unsigned_integer (buf, 8,
					      byte_order) + cache->sp_offset;

      /* Cache pc will be the frame func.  */
      cache->pc = get_frame_func (this_frame);

      /* The previous value of %rsp is cache->base plus 16.  */
      cache->saved_sp = cache->base + 16;

      /* The saved %rip will be at cache->base plus 8.  */
      cache->saved_regs[AMD64_RIP_REGNUM] = cache->base + 8;

      cache->base_p = 1;
    }
  catch (const gdb_exception_error &ex)
    {
      if (ex.error != NOT_AVAILABLE_ERROR)
	throw;
    }

  return cache;
}

static enum unwind_stop_reason
amd64_epilogue_frame_unwind_stop_reason (const frame_info_ptr &this_frame,
					 void **this_cache)
{
  struct amd64_frame_cache *cache
    = amd64_epilogue_frame_cache (this_frame, this_cache);

  if (!cache->base_p)
    return UNWIND_UNAVAILABLE;

  return UNWIND_NO_REASON;
}

static void
amd64_epilogue_frame_this_id (const frame_info_ptr &this_frame,
			      void **this_cache,
			      struct frame_id *this_id)
{
  struct amd64_frame_cache *cache = amd64_epilogue_frame_cache (this_frame,
							       this_cache);

  if (!cache->base_p)
    (*this_id) = frame_id_build_unavailable_stack (cache->pc);
  else
    (*this_id) = frame_id_build (cache->base + 16, cache->pc);
}

static const struct frame_unwind_legacy amd64_epilogue_override_frame_unwind (
  "amd64 epilogue override",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  amd64_epilogue_frame_unwind_stop_reason,
  amd64_epilogue_frame_this_id,
  amd64_frame_prev_register,
  NULL,
  amd64_epilogue_override_frame_sniffer
);

static const struct frame_unwind_legacy amd64_epilogue_frame_unwind (
  "amd64 epilogue",
  NORMAL_FRAME,
  FRAME_UNWIND_ARCH,
  amd64_epilogue_frame_unwind_stop_reason,
  amd64_epilogue_frame_this_id,
  amd64_frame_prev_register,
  NULL, 
  amd64_epilogue_frame_sniffer
);

static struct frame_id
amd64_dummy_id (struct gdbarch *gdbarch, const frame_info_ptr &this_frame)
{
  CORE_ADDR fp;

  fp = get_frame_register_unsigned (this_frame, AMD64_RBP_REGNUM);

  return frame_id_build (fp + 16, get_frame_pc (this_frame));
}

/* 16 byte align the SP per frame requirements.  */

static CORE_ADDR
amd64_frame_align (struct gdbarch *gdbarch, CORE_ADDR sp)
{
  return sp & -(CORE_ADDR)16;
}


/* Supply register REGNUM from the buffer specified by FPREGS and LEN
   in the floating-point register set REGSET to register cache
   REGCACHE.  If REGNUM is -1, do this for all registers in REGSET.  */

static void
amd64_supply_fpregset (const struct regset *regset, struct regcache *regcache,
		       int regnum, const void *fpregs, size_t len)
{
  struct gdbarch *gdbarch = regcache->arch ();
  const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  gdb_assert (len >= tdep->sizeof_fpregset);
  amd64_supply_fxsave (regcache, regnum, fpregs);
}

/* Collect register REGNUM from the register cache REGCACHE and store
   it in the buffer specified by FPREGS and LEN as described by the
   floating-point register set REGSET.  If REGNUM is -1, do this for
   all registers in REGSET.  */

static void
amd64_collect_fpregset (const struct regset *regset,
			const struct regcache *regcache,
			int regnum, void *fpregs, size_t len)
{
  struct gdbarch *gdbarch = regcache->arch ();
  const i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  gdb_assert (len >= tdep->sizeof_fpregset);
  amd64_collect_fxsave (regcache, regnum, fpregs);
}

const struct regset amd64_fpregset =
  {
    NULL, amd64_supply_fpregset, amd64_collect_fpregset
  };


/* Figure out where the longjmp will land.  Slurp the jmp_buf out of
   %rdi.  We expect its value to be a pointer to the jmp_buf structure
   from which we extract the address that we will land at.  This
   address is copied into PC.  This routine returns non-zero on
   success.  */

static int
amd64_get_longjmp_target (const frame_info_ptr &frame, CORE_ADDR *pc)
{
  gdb_byte buf[8];
  CORE_ADDR jb_addr;
  struct gdbarch *gdbarch = get_frame_arch (frame);
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
  int jb_pc_offset = tdep->jb_pc_offset;
  int len = builtin_type (gdbarch)->builtin_func_ptr->length ();

  /* If JB_PC_OFFSET is -1, we have no way to find out where the
     longjmp will land.	 */
  if (jb_pc_offset == -1)
    return 0;

  get_frame_register (frame, AMD64_RDI_REGNUM, buf);
  jb_addr= extract_typed_address
	    (buf, builtin_type (gdbarch)->builtin_data_ptr);
  if (target_read_memory (jb_addr + jb_pc_offset, buf, len))
    return 0;

  *pc = extract_typed_address (buf, builtin_type (gdbarch)->builtin_func_ptr);

  return 1;
}

static const int amd64_record_regmap[] =
{
  AMD64_RAX_REGNUM, AMD64_RCX_REGNUM, AMD64_RDX_REGNUM, AMD64_RBX_REGNUM,
  AMD64_RSP_REGNUM, AMD64_RBP_REGNUM, AMD64_RSI_REGNUM, AMD64_RDI_REGNUM,
  AMD64_R8_REGNUM, AMD64_R9_REGNUM, AMD64_R10_REGNUM, AMD64_R11_REGNUM,
  AMD64_R12_REGNUM, AMD64_R13_REGNUM, AMD64_R14_REGNUM, AMD64_R15_REGNUM,
  AMD64_RIP_REGNUM, AMD64_EFLAGS_REGNUM, AMD64_CS_REGNUM, AMD64_SS_REGNUM,
  AMD64_DS_REGNUM, AMD64_ES_REGNUM, AMD64_FS_REGNUM, AMD64_GS_REGNUM,
  AMD64_XMM0_REGNUM
};

/* Implement the "in_indirect_branch_thunk" gdbarch function.  */

static bool
amd64_in_indirect_branch_thunk (struct gdbarch *gdbarch, CORE_ADDR pc)
{
  return x86_in_indirect_branch_thunk (pc, amd64_register_names,
				       AMD64_RAX_REGNUM,
				       AMD64_RIP_REGNUM);
}

void
amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
		const target_desc *default_tdesc)
{
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
  const struct target_desc *tdesc = info.target_desc;
  static const char *const stap_integer_prefixes[] = { "$", NULL };
  static const char *const stap_register_prefixes[] = { "%", NULL };
  static const char *const stap_register_indirection_prefixes[] = { "(",
								    NULL };
  static const char *const stap_register_indirection_suffixes[] = { ")",
								    NULL };

  /* AMD64 generally uses `fxsave' instead of `fsave' for saving its
     floating-point registers.  */
  tdep->sizeof_fpregset = I387_SIZEOF_FXSAVE;
  tdep->fpregset = &amd64_fpregset;

  if (! tdesc_has_registers (tdesc))
    tdesc = default_tdesc;
  tdep->tdesc = tdesc;

  tdep->num_core_regs = AMD64_NUM_GREGS + I387_NUM_REGS;
  tdep->register_names = amd64_register_names;

  if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx512") != NULL)
    {
      tdep->zmmh_register_names = amd64_zmmh_names;
      tdep->k_register_names = amd64_k_names;
      tdep->xmm_avx512_register_names = amd64_xmm_avx512_names;
      tdep->ymm16h_register_names = amd64_ymmh_avx512_names;

      tdep->num_zmm_regs = 32;
      tdep->num_xmm_avx512_regs = 16;
      tdep->num_ymm_avx512_regs = 16;

      tdep->zmm0h_regnum = AMD64_ZMM0H_REGNUM;
      tdep->k0_regnum = AMD64_K0_REGNUM;
      tdep->xmm16_regnum = AMD64_XMM16_REGNUM;
      tdep->ymm16h_regnum = AMD64_YMM16H_REGNUM;
    }

  if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.avx") != NULL)
    {
      tdep->ymmh_register_names = amd64_ymmh_names;
      tdep->num_ymm_regs = 16;
      tdep->ymm0h_regnum = AMD64_YMM0H_REGNUM;
    }

  if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.segments") != NULL)
    {
      tdep->fsbase_regnum = AMD64_FSBASE_REGNUM;
    }

  if (tdesc_find_feature (tdesc, "org.gnu.gdb.i386.pkeys") != NULL)
    {
      tdep->pkeys_register_names = amd64_pkeys_names;
      tdep->pkru_regnum = AMD64_PKRU_REGNUM;
      tdep->num_pkeys_regs = 1;
    }

  tdep->num_byte_regs = 20;
  tdep->num_word_regs = 16;
  tdep->num_dword_regs = 16;
  /* Avoid wiring in the MMX registers for now.  */
  tdep->num_mmx_regs = 0;

  set_gdbarch_pseudo_register_read_value (gdbarch,
					  amd64_pseudo_register_read_value);
  set_gdbarch_pseudo_register_write (gdbarch, amd64_pseudo_register_write);
  set_gdbarch_ax_pseudo_register_collect (gdbarch,
					  amd64_ax_pseudo_register_collect);

  set_tdesc_pseudo_register_name (gdbarch, amd64_pseudo_register_name);

  /* AMD64 has an FPU and 16 SSE registers.  */
  tdep->st0_regnum = AMD64_ST0_REGNUM;
  tdep->num_xmm_regs = 16;

  /* This is what all the fuss is about.  */
  set_gdbarch_long_bit (gdbarch, 64);
  set_gdbarch_long_long_bit (gdbarch, 64);
  set_gdbarch_ptr_bit (gdbarch, 64);

  /* In contrast to the i386, on AMD64 a `long double' actually takes
     up 128 bits, even though it's still based on the i387 extended
     floating-point format which has only 80 significant bits.  */
  set_gdbarch_long_double_bit (gdbarch, 128);

  set_gdbarch_num_regs (gdbarch, AMD64_NUM_REGS);

  /* Register numbers of various important registers.  */
  set_gdbarch_sp_regnum (gdbarch, AMD64_RSP_REGNUM); /* %rsp */
  set_gdbarch_pc_regnum (gdbarch, AMD64_RIP_REGNUM); /* %rip */
  set_gdbarch_ps_regnum (gdbarch, AMD64_EFLAGS_REGNUM); /* %eflags */
  set_gdbarch_fp0_regnum (gdbarch, AMD64_ST0_REGNUM); /* %st(0) */

  /* The "default" register numbering scheme for AMD64 is referred to
     as the "DWARF Register Number Mapping" in the System V psABI.
     The preferred debugging format for all known AMD64 targets is
     actually DWARF2, and GCC doesn't seem to support DWARF (that is
     DWARF-1), but we provide the same mapping just in case.  This
     mapping is also used for stabs, which GCC does support.  */
  set_gdbarch_stab_reg_to_regnum (gdbarch, amd64_dwarf_reg_to_regnum);
  set_gdbarch_dwarf2_reg_to_regnum (gdbarch, amd64_dwarf_reg_to_regnum);

  /* We don't override SDB_REG_RO_REGNUM, since COFF doesn't seem to
     be in use on any of the supported AMD64 targets.  */

  /* Call dummy code.  */
  set_gdbarch_push_dummy_call (gdbarch, amd64_push_dummy_call);
  set_gdbarch_frame_align (gdbarch, amd64_frame_align);
  set_gdbarch_frame_red_zone_size (gdbarch, 128);

  set_gdbarch_convert_register_p (gdbarch, i387_convert_register_p);
  set_gdbarch_register_to_value (gdbarch, i387_register_to_value);
  set_gdbarch_value_to_register (gdbarch, i387_value_to_register);

  set_gdbarch_return_value_as_value (gdbarch, amd64_return_value);

  set_gdbarch_skip_prologue (gdbarch, amd64_skip_prologue);

  tdep->record_regmap = amd64_record_regmap;

  set_gdbarch_dummy_id (gdbarch, amd64_dummy_id);

  /* Hook the function epilogue frame unwinder.  This unwinder is
     appended to the list first, so that it supersedes the other
     unwinders in function epilogues.  */
  frame_unwind_prepend_unwinder (gdbarch, &amd64_epilogue_override_frame_unwind);

  frame_unwind_append_unwinder (gdbarch, &amd64_epilogue_frame_unwind);

  /* Hook the prologue-based frame unwinders.  */
  frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind);
  frame_unwind_append_unwinder (gdbarch, &amd64_frame_unwind);
  frame_base_set_default (gdbarch, &amd64_frame_base);

  set_gdbarch_get_longjmp_target (gdbarch, amd64_get_longjmp_target);

  set_gdbarch_relocate_instruction (gdbarch, amd64_relocate_instruction);

  set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address);

  set_gdbarch_stack_frame_destroyed_p (gdbarch, amd64_stack_frame_destroyed_p);

  /* SystemTap variables and functions.  */
  set_gdbarch_stap_integer_prefixes (gdbarch, stap_integer_prefixes);
  set_gdbarch_stap_register_prefixes (gdbarch, stap_register_prefixes);
  set_gdbarch_stap_register_indirection_prefixes (gdbarch,
					  stap_register_indirection_prefixes);
  set_gdbarch_stap_register_indirection_suffixes (gdbarch,
					  stap_register_indirection_suffixes);
  set_gdbarch_stap_is_single_operand (gdbarch,
				      i386_stap_is_single_operand);
  set_gdbarch_stap_parse_special_token (gdbarch,
					i386_stap_parse_special_token);
  set_gdbarch_insn_is_call (gdbarch, amd64_insn_is_call);
  set_gdbarch_insn_is_ret (gdbarch, amd64_insn_is_ret);
  set_gdbarch_insn_is_jump (gdbarch, amd64_insn_is_jump);

  set_gdbarch_in_indirect_branch_thunk (gdbarch,
					amd64_in_indirect_branch_thunk);

  register_amd64_ravenscar_ops (gdbarch);
}

/* Initialize ARCH for x86-64, no osabi.  */

static void
amd64_none_init_abi (gdbarch_info info, gdbarch *arch)
{
  amd64_init_abi (info, arch, amd64_target_description (X86_XSTATE_SSE_MASK,
							true));
}

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

  switch (regnum - tdep->eax_regnum)
    {
    case AMD64_RBP_REGNUM:	/* %ebp */
    case AMD64_RSP_REGNUM:	/* %esp */
      return builtin_type (gdbarch)->builtin_data_ptr;
    case AMD64_RIP_REGNUM:	/* %eip */
      return builtin_type (gdbarch)->builtin_func_ptr;
    }

  return i386_pseudo_register_type (gdbarch, regnum);
}

void
amd64_x32_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch,
		    const target_desc *default_tdesc)
{
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  amd64_init_abi (info, gdbarch, default_tdesc);

  tdep->num_dword_regs = 17;
  set_tdesc_pseudo_register_type (gdbarch, amd64_x32_pseudo_register_type);

  set_gdbarch_long_bit (gdbarch, 32);
  set_gdbarch_ptr_bit (gdbarch, 32);
}

/* Initialize ARCH for x64-32, no osabi.  */

static void
amd64_x32_none_init_abi (gdbarch_info info, gdbarch *arch)
{
  amd64_x32_init_abi (info, arch,
		      amd64_target_description (X86_XSTATE_SSE_MASK, true));
}

/* Return the target description for a specified XSAVE feature mask.  */

const struct target_desc *
amd64_target_description (uint64_t xcr0, bool segments)
{
  static target_desc *amd64_tdescs \
    [2/*AVX*/][2/*AVX512*/][2/*PKRU*/][2/*segments*/] = {};
  target_desc **tdesc;

  tdesc = &amd64_tdescs[(xcr0 & X86_XSTATE_AVX) ? 1 : 0]
    [(xcr0 & X86_XSTATE_AVX512) ? 1 : 0]
    [(xcr0 & X86_XSTATE_PKRU) ? 1 : 0]
    [segments ? 1 : 0];

  if (*tdesc == NULL)
    *tdesc = amd64_create_target_description (xcr0, false, false,
					      segments);

  return *tdesc;
}

#if GDB_SELF_TEST

namespace selftests {

/* Recode a vex2 instruction into a vex3 instruction.  */

static void
vex2_to_vex3 (gdb::byte_vector &vex2, gdb::byte_vector &vex3)
{
  gdb_assert (vex2.size () >= 2);
  gdb_assert (vex2[0] == 0xc5);

  unsigned char r = vex2[1] >> 7;
  unsigned char b = 0x1;
  unsigned char x = 0x1;
  unsigned char m = 0x1;
  unsigned char w = 0x0;

  vex3.resize (3);
  vex3[0] = 0xc4;
  vex3[1] = (r << 7) | (x << 6) | (b << 5) | m;
  vex3[2] = (vex2[1] & ~0x80) | (w << 7);

  std::copy (vex2.begin () + 2, vex2.end (),
	     std::back_inserter (vex3));
}

/* Test vex2 to vex3.  */

static void
test_vex2_to_vex3 (void)
{
  /* INSN: vzeroall, vex2 prefix.  */
  gdb::byte_vector vex2 = { 0xc5, 0xfc, 0x77 };

  gdb::byte_vector vex3;
  vex2_to_vex3 (vex2, vex3);

  /* INSN: vzeroall, vex3 prefix.  */
  gdb::byte_vector vex3_ref = { 0xc4, 0xe1, 0x7c, 0x77 };
  SELF_CHECK (vex3 == vex3_ref);
}

/* Test amd64_get_insn_details.  */

static void
test_amd64_get_insn_details (void)
{
  struct amd64_insn details;
  gdb::byte_vector insn, tmp;

  /* INSN: add %eax,(%rcx).  */
  insn = { 0x01, 0x01 };
  amd64_get_insn_details (insn.data (), &details);
  SELF_CHECK (details.opcode_len == 1);
  SELF_CHECK (details.enc_prefix_offset == -1);
  SELF_CHECK (details.opcode_offset == 0);
  SELF_CHECK (details.modrm_offset == 1);
  SELF_CHECK (amd64_get_used_input_int_regs (&details, false)
	      == ((1 << EAX_REG_NUM) | (1 << ECX_REG_NUM)));
  SELF_CHECK (rip_relative_offset (&details) == 0);

  /* INSN: push %rax.  This exercises the "opcode specifies register" case in
     amd64_get_used_input_int_regs.  */
  insn = { 0x50 };
  amd64_get_insn_details (insn.data (), &details);
  SELF_CHECK (details.opcode_len == 1);
  SELF_CHECK (details.enc_prefix_offset == -1);
  SELF_CHECK (details.opcode_offset == 0);
  SELF_CHECK (details.modrm_offset == -1);
  SELF_CHECK (amd64_get_used_input_int_regs (&details, false)
	      == ((1 << EAX_REG_NUM)));
  SELF_CHECK (rip_relative_offset (&details) == 0);

  /* INSN: lea 0x1e(%rip),%rdi, rex prefix.  */
  insn = { 0x48, 0x8d, 0x3d, 0x1e, 0x00, 0x00, 0x00 };
  amd64_get_insn_details (insn.data (), &details);
  SELF_CHECK (details.opcode_len == 1);
  SELF_CHECK (details.enc_prefix_offset == 0);
  SELF_CHECK (details.opcode_offset == 1);
  SELF_CHECK (details.modrm_offset == 2);
  SELF_CHECK (amd64_get_used_input_int_regs (&details, false)
	      == (1 << EDI_REG_NUM));
  SELF_CHECK (rip_relative_offset (&details) == 3);

  /* INSN: lea 0x1e(%ecx),%rdi, rex prefix.  */
  gdb::byte_vector updated_insn = { 0x48, 0x8d, 0xb9, 0x1e, 0x00, 0x00, 0x00 };
  fixup_riprel (details, insn.data (), ECX_REG_NUM);
  SELF_CHECK (insn == updated_insn);

  gdb::byte_vector vex2, vex3;

  /* INSN: vzeroall, vex2 prefix.  */
  vex2 = { 0xc5, 0xfc, 0x77 };
  amd64_get_insn_details (vex2.data (), &details);
  SELF_CHECK (details.opcode_len == 2);
  SELF_CHECK (details.enc_prefix_offset == 0);
  SELF_CHECK (details.opcode_offset == 2);
  SELF_CHECK (details.modrm_offset == -1);

  /* INSN: vzeroall, vex3 prefix.  */
  vex2_to_vex3 (vex2, vex3);
  amd64_get_insn_details (vex3.data (), &details);
  SELF_CHECK (details.opcode_len == 2);
  SELF_CHECK (details.enc_prefix_offset == 0);
  SELF_CHECK (details.opcode_offset == 3);
  SELF_CHECK (details.modrm_offset == -1);

  /* INSN: vzeroupper, vex2 prefix.  */
  vex2 = { 0xc5, 0xf8, 0x77 };
  amd64_get_insn_details (vex2.data (), &details);
  SELF_CHECK (details.opcode_len == 2);
  SELF_CHECK (details.enc_prefix_offset == 0);
  SELF_CHECK (details.opcode_offset == 2);
  SELF_CHECK (details.modrm_offset == -1);

  /* INSN: vzeroupper, vex3 prefix.  */
  vex2_to_vex3 (vex2, vex3);
  amd64_get_insn_details (vex3.data (), &details);
  SELF_CHECK (details.opcode_len == 2);
  SELF_CHECK (details.enc_prefix_offset == 0);
  SELF_CHECK (details.opcode_offset == 3);
  SELF_CHECK (details.modrm_offset == -1);

  /* INSN: vmovdqu 0x9(%rip),%ymm3, vex2 prefix.  */
  vex2 = { 0xc5, 0xfe, 0x6f, 0x1d, 0x09, 0x00, 0x00, 0x00 };
  amd64_get_insn_details (vex2.data (), &details);
  SELF_CHECK (details.opcode_len == 2);
  SELF_CHECK (details.enc_prefix_offset == 0);
  SELF_CHECK (details.opcode_offset == 2);
  SELF_CHECK (details.modrm_offset == 3);

  /* INSN: vmovdqu 0x9(%rcx),%ymm3, vex2 prefix.  */
  gdb::byte_vector updated_vex2
    = { 0xc5, 0xfe, 0x6f, 0x99, 0x09, 0x00, 0x00, 0x00 };
  tmp = vex2;
  fixup_riprel (details, tmp.data (), ECX_REG_NUM);
  SELF_CHECK (tmp == updated_vex2);

  /* INSN: vmovdqu 0x9(%rip),%ymm3, vex3 prefix.  */
  vex2_to_vex3 (vex2, vex3);
  amd64_get_insn_details (vex3.data (), &details);
  SELF_CHECK (details.opcode_len == 2);
  SELF_CHECK (details.enc_prefix_offset == 0);
  SELF_CHECK (details.opcode_offset == 3);
  SELF_CHECK (details.modrm_offset == 4);

  /* INSN: vmovdqu 0x9(%rcx),%ymm3, vex3 prefix.  */
  gdb::byte_vector updated_vex3;
  vex2_to_vex3 (updated_vex2, updated_vex3);
  tmp = vex3;
  fixup_riprel (details, tmp.data (), ECX_REG_NUM);
  SELF_CHECK (tmp == updated_vex3);

  /* INSN: lea 0x0(%eip),%r31d, rex2 prefix.  */
  insn = { 0x67, 0xd5, 0x44, 0x8d, 0x3d, 0x00, 0x00, 0x00, 0x00 };
  amd64_get_insn_details (insn.data (), &details);
  SELF_CHECK (details.opcode_len == 1);
  SELF_CHECK (details.enc_prefix_offset == 1);
  SELF_CHECK (details.opcode_offset == 3);
  SELF_CHECK (details.modrm_offset == 4);
  /* This is incorrect, r31 is used instead of rdi, but currently that doesn't
     matter.  */
  SELF_CHECK (amd64_get_used_input_int_regs (&details, false)
	      == (1 << EDI_REG_NUM));

  /* INSN: lea 0x0(%ecx),%r31d, rex2 prefix.  */
  updated_insn = { 0x67, 0xd5, 0x44, 0x8d, 0xb9, 0x00, 0x00, 0x00, 0x00 };
  fixup_riprel (details, insn.data (), ECX_REG_NUM);
  SELF_CHECK (insn == updated_insn);

  /* INSN: vmovaps -0x400(%rip),%zmm0, evex prefix.  */
  insn = { 0x62, 0xf1, 0x7c, 0x48, 0x28, 0x05, 0x00, 0xfc, 0xff, 0xff };
  amd64_get_insn_details (insn.data (), &details);
  SELF_CHECK (details.opcode_len == 2);
  SELF_CHECK (details.enc_prefix_offset == 0);
  SELF_CHECK (details.opcode_offset == 4);
  SELF_CHECK (details.modrm_offset == 5);

  /* INSN: vmovaps -0x400(%rcx),%zmm0, evex prefix.  */
  updated_insn
    = { 0x62, 0xf1, 0x7c, 0x48, 0x28, 0x81, 0x00, 0xfc, 0xff, 0xff };
  fixup_riprel (details, insn.data (), ECX_REG_NUM);
  SELF_CHECK (insn == updated_insn);
}

static void
amd64_insn_decode (void)
{
  test_vex2_to_vex3 ();
  test_amd64_get_insn_details ();
}

} // namespace selftests
#endif /* GDB_SELF_TEST */

void _initialize_amd64_tdep ();
void
_initialize_amd64_tdep ()
{
  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x86_64, GDB_OSABI_NONE,
			  amd64_none_init_abi);
  gdbarch_register_osabi (bfd_arch_i386, bfd_mach_x64_32, GDB_OSABI_NONE,
			  amd64_x32_none_init_abi);
#if GDB_SELF_TEST
  selftests::register_test ("amd64-insn-decode",
			    selftests::amd64_insn_decode);
#endif
}


/* The 64-bit FXSAVE format differs from the 32-bit format in the
   sense that the instruction pointer and data pointer are simply
   64-bit offsets into the code segment and the data segment instead
   of a selector offset pair.  The functions below store the upper 32
   bits of these pointers (instead of just the 16-bits of the segment
   selector).  */

/* Fill register REGNUM in REGCACHE with the appropriate
   floating-point or SSE register value from *FXSAVE.  If REGNUM is
   -1, do this for all registers.  This function masks off any of the
   reserved bits in *FXSAVE.  */

void
amd64_supply_fxsave (struct regcache *regcache, int regnum,
		     const void *fxsave)
{
  struct gdbarch *gdbarch = regcache->arch ();
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  i387_supply_fxsave (regcache, regnum, fxsave);

  if (fxsave
      && gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
    {
      const gdb_byte *regs = (const gdb_byte *) fxsave;

      if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
	regcache->raw_supply (I387_FISEG_REGNUM (tdep), regs + 12);
      if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
	regcache->raw_supply (I387_FOSEG_REGNUM (tdep), regs + 20);
    }
}

/* Similar to amd64_supply_fxsave, but use XSAVE extended state.  */

void
amd64_supply_xsave (struct regcache *regcache, int regnum,
		    const void *xsave)
{
  struct gdbarch *gdbarch = regcache->arch ();
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);

  i387_supply_xsave (regcache, regnum, xsave);

  if (xsave
      && gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
    {
      const gdb_byte *regs = (const gdb_byte *) xsave;
      ULONGEST clear_bv;

      clear_bv = i387_xsave_get_clear_bv (gdbarch, xsave);

      /* If the FISEG and FOSEG registers have not been initialised yet
	 (their CLEAR_BV bit is set) then their default values of zero will
	 have already been setup by I387_SUPPLY_XSAVE.  */
      if (!(clear_bv & X86_XSTATE_X87))
	{
	  if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
	    regcache->raw_supply (I387_FISEG_REGNUM (tdep), regs + 12);
	  if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
	    regcache->raw_supply (I387_FOSEG_REGNUM (tdep), regs + 20);
	}
    }
}

/* Fill register REGNUM (if it is a floating-point or SSE register) in
   *FXSAVE with the value from REGCACHE.  If REGNUM is -1, do this for
   all registers.  This function doesn't touch any of the reserved
   bits in *FXSAVE.  */

void
amd64_collect_fxsave (const struct regcache *regcache, int regnum,
		      void *fxsave)
{
  struct gdbarch *gdbarch = regcache->arch ();
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
  gdb_byte *regs = (gdb_byte *) fxsave;

  i387_collect_fxsave (regcache, regnum, fxsave);

  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
    {
      if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
	regcache->raw_collect (I387_FISEG_REGNUM (tdep), regs + 12);
      if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
	regcache->raw_collect (I387_FOSEG_REGNUM (tdep), regs + 20);
    }
}

/* Similar to amd64_collect_fxsave, but use XSAVE extended state.  */

void
amd64_collect_xsave (const struct regcache *regcache, int regnum,
		     void *xsave, int gcore)
{
  struct gdbarch *gdbarch = regcache->arch ();
  i386_gdbarch_tdep *tdep = gdbarch_tdep<i386_gdbarch_tdep> (gdbarch);
  gdb_byte *regs = (gdb_byte *) xsave;

  i387_collect_xsave (regcache, regnum, xsave, gcore);

  if (gdbarch_bfd_arch_info (gdbarch)->bits_per_word == 64)
    {
      if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep))
	regcache->raw_collect (I387_FISEG_REGNUM (tdep),
			      regs + 12);
      if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep))
	regcache->raw_collect (I387_FOSEG_REGNUM (tdep),
			      regs + 20);
    }
}
