/* Target-dependent code for AMD64.
- Copyright (C) 2001-2013 Free Software Foundation, Inc.
+ Copyright (C) 2001-2014 Free Software Foundation, Inc.
Contributed by Jiri Smid, SuSE Labs.
#include "frame-base.h"
#include "frame-unwind.h"
#include "inferior.h"
+#include "infrun.h"
#include "gdbcmd.h"
#include "gdbcore.h"
#include "objfiles.h"
#include "features/i386/amd64.c"
#include "features/i386/amd64-avx.c"
#include "features/i386/amd64-mpx.c"
+#include "features/i386/amd64-avx512.c"
+
#include "features/i386/x32.c"
#include "features/i386/x32-avx.c"
+#include "features/i386/x32-avx512.c"
#include "ax.h"
#include "ax-gdb.h"
"ymm12", "ymm13", "ymm14", "ymm15"
};
+static const char *amd64_ymm_avx512_names[] =
+{
+ "ymm16", "ymm17", "ymm18", "ymm19",
+ "ymm20", "ymm21", "ymm22", "ymm23",
+ "ymm24", "ymm25", "ymm26", "ymm27",
+ "ymm28", "ymm29", "ymm30", "ymm31"
+};
+
static const char *amd64_ymmh_names[] =
{
"ymm0h", "ymm1h", "ymm2h", "ymm3h",
"ymm12h", "ymm13h", "ymm14h", "ymm15h"
};
+static const char *amd64_ymmh_avx512_names[] =
+{
+ "ymm16h", "ymm17h", "ymm18h", "ymm19h",
+ "ymm20h", "ymm21h", "ymm22h", "ymm23h",
+ "ymm24h", "ymm25h", "ymm26h", "ymm27h",
+ "ymm28h", "ymm29h", "ymm30h", "ymm31h"
+};
+
static const char *amd64_mpx_names[] =
{
"bnd0raw", "bnd1raw", "bnd2raw", "bnd3raw", "bndcfgu", "bndstatus"
};
+static const char *amd64_k_names[] =
+{
+ "k0", "k1", "k2", "k3",
+ "k4", "k5", "k6", "k7"
+};
+
+static const char *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 *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 *amd64_xmm_avx512_names[] = {
+ "xmm16", "xmm17", "xmm18", "xmm19",
+ "xmm20", "xmm21", "xmm22", "xmm23",
+ "xmm24", "xmm25", "xmm26", "xmm27",
+ "xmm28", "xmm29", "xmm30", "xmm31"
+};
+
/* DWARF Register Number Mapping as defined in the System V psABI,
section 3.6. */
struct gdbarch_tdep *tdep = 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 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)
{
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 *buf;
+ int len, classification;
+
+ len = gdbarch_max_insn_length (gdbarch);
+ buf = alloca (len);
+
+ read_code (addr, buf, len);
+ amd64_get_insn_details (buf, &details);
+
+ 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. */
amd64_supply_fpregset (const struct regset *regset, struct regcache *regcache,
int regnum, const void *fpregs, size_t len)
{
- const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
gdb_assert (len == tdep->sizeof_fpregset);
amd64_supply_fxsave (regcache, regnum, fpregs);
const struct regcache *regcache,
int regnum, void *fpregs, size_t len)
{
- const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ const struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
gdb_assert (len == tdep->sizeof_fpregset);
amd64_collect_fxsave (regcache, regnum, fpregs);
amd64_collect_xsave (regcache, regnum, xstateregs, 1);
}
+static const struct regset amd64_fpregset =
+ {
+ NULL, amd64_supply_fpregset, amd64_collect_fpregset
+ };
+
+static const struct regset amd64_xstateregset =
+ {
+ NULL, amd64_supply_xstateregset, amd64_collect_xstateregset
+ };
+
/* Return the appropriate register set for the core section identified
by SECT_NAME and SECT_SIZE. */
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
if (strcmp (sect_name, ".reg2") == 0 && sect_size == tdep->sizeof_fpregset)
- {
- if (tdep->fpregset == NULL)
- tdep->fpregset = regset_alloc (gdbarch, amd64_supply_fpregset,
- amd64_collect_fpregset);
-
- return tdep->fpregset;
- }
+ return &amd64_fpregset;
if (strcmp (sect_name, ".reg-xstate") == 0)
- {
- if (tdep->xstateregset == NULL)
- tdep->xstateregset = regset_alloc (gdbarch,
- amd64_supply_xstateregset,
- amd64_collect_xstateregset);
-
- return tdep->xstateregset;
- }
+ return &amd64_xstateregset;
return i386_regset_from_core_section (gdbarch, sect_name, sect_size);
}
{
struct gdbarch_tdep *tdep = 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->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;
set_gdbarch_gen_return_address (gdbarch, amd64_gen_return_address);
/* SystemTap variables and functions. */
- set_gdbarch_stap_integer_prefix (gdbarch, "$");
- set_gdbarch_stap_register_prefix (gdbarch, "%");
- set_gdbarch_stap_register_indirection_prefix (gdbarch, "(");
- set_gdbarch_stap_register_indirection_suffix (gdbarch, ")");
+ 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);
}
\f
initialize_tdesc_amd64 ();
initialize_tdesc_amd64_avx ();
initialize_tdesc_amd64_mpx ();
+ initialize_tdesc_amd64_avx512 ();
+
initialize_tdesc_x32 ();
initialize_tdesc_x32_avx ();
+ initialize_tdesc_x32_avx512 ();
}
\f