Support i386 AVX.

2010-04-07  H.J. Lu  <hongjiu.lu@intel.com>

	* i386-linux-nat.c: Include "regset.h", "elf/common.h",
	<sys/uio.h> and "i386-xstate.h".
	(PTRACE_GETREGSET): New.
	(PTRACE_SETREGSET): Likewise.
	(fetch_xstateregs): Likewise.
	(store_xstateregs): Likewise.
	(GETXSTATEREGS_SUPPLIES): Likewise.
	(regmap): Include 8 upper YMM registers.
	(i386_linux_fetch_inferior_registers): Support XSAVE extended
	state.
	(i386_linux_store_inferior_registers): Likewise.
	(i386_linux_read_description): Check and enable AVX target
	descriptions.

	* i386-linux-tdep.c: Include "regset.h", "i387-tdep.h",
	"i386-xstate.h" and "features/i386/i386-avx-linux.c".
	(i386_linux_regset_sections): Add ".reg-xstate".
	(i386_linux_gregset_reg_offset): Include 8 upper YMM registers.
	(i386_linux_core_read_xcr0): New.
	(i386_linux_core_read_description): Check and enable AVX target
	description.
	(i386_linux_init_abi): Set xsave_xcr0_offset.
	(_initialize_i386_linux_tdep): Call
	initialize_tdesc_i386_avx_linux.

	* i386-linux-tdep.h (I386_LINUX_ORIG_EAX_REGNUM): Replace
	I386_SSE_NUM_REGS with I386_AVX_NUM_REGS.
	(i386_linux_core_read_xcr0): New.
	(tdesc_i386_avx_linux): Likewise.
	(I386_LINUX_XSAVE_XCR0_OFFSET): Likewise.

	* i386-tdep.c: Include "i386-xstate.h" and
	"features/i386/i386-avx.c".
	(i386_ymm_names): New.
	(i386_ymmh_names): Likewise.
	(i386_ymmh_regnum_p): Likewise.
	(i386_ymm_regnum_p): Likewise.
	(i386_xmm_regnum_p): Likewise.
	(i386_register_name): Likewise.
	(i386_ymm_type): Likewise.
	(i386_supply_xstateregset): Likewise.
	(i386_collect_xstateregset): Likewise.
	(i386_sse_regnum_p): Removed.
	(i386_pseudo_register_name): Support pseudo YMM registers.
	(i386_pseudo_register_type): Likewise.
	(i386_pseudo_register_read): Likewise.
	(i386_pseudo_register_write): Likewise.
	(i386_dbx_reg_to_regnum): Return %ymmN register number for
	%xmmN if AVX is available.
	(i386_regset_from_core_section): Support .reg-xstate section.
	(i386_register_reggroup_p): Supper upper YMM and YMM registers.
	(i386_process_record): Replace i386_sse_regnum_p with
	i386_xmm_regnum_p.
	(i386_validate_tdesc_p): Support org.gnu.gdb.i386.avx feature.
	Set ymmh_register_names, num_ymm_regs, ymm0h_regnum and xcr0.
	(i386_gdbarch_init): Set xstateregset.  Set xsave_xcr0_offset.
	Call set_gdbarch_register_name.  Replace I386_SSE_NUM_REGS with
	I386_AVX_NUM_REGS.  Set ymmh_register_names, ymm0h_regnum and
	num_ymm_regs.  Add num_ymm_regs to set_gdbarch_num_pseudo_regs.
	Set ymm0_regnum.
	(_initialize_i386_tdep): Call initialize_tdesc_i386_avx.

	* i386-tdep.h (gdbarch_tdep): Add xstateregset, ymm0_regnum,
	xcr0, xsave_xcr0_offset, ymm0h_regnum, ymmh_register_names and
	i386_ymm_type.
	(i386_regnum): Add I386_YMM0H_REGNUM, and I386_YMM7H_REGNUM.
	(I386_AVX_NUM_REGS): New.
	(i386_xmm_regnum_p): Likewise.
	(i386_ymm_regnum_p): Likewise.
	(i386_ymmh_regnum_p): Likewise.

	* common/i386-xstate.h: New.
This commit is contained in:
H.J. Lu 2010-04-07 18:43:45 +00:00
parent 98adf0f383
commit c131fcee79
7 changed files with 649 additions and 56 deletions

View file

@ -23,6 +23,7 @@
#include "frame.h"
#include "value.h"
#include "regcache.h"
#include "regset.h"
#include "inferior.h"
#include "osabi.h"
#include "reggroups.h"
@ -36,9 +37,11 @@
#include "solib-svr4.h"
#include "symtab.h"
#include "arch-utils.h"
#include "regset.h"
#include "xml-syscall.h"
#include "i387-tdep.h"
#include "i386-xstate.h"
/* The syscall's XML filename for i386. */
#define XML_SYSCALL_FILENAME_I386 "syscalls/i386-linux.xml"
@ -47,6 +50,7 @@
#include <stdint.h>
#include "features/i386/i386-linux.c"
#include "features/i386/i386-avx-linux.c"
/* Supported register note sections. */
static struct core_regset_section i386_linux_regset_sections[] =
@ -54,6 +58,7 @@ static struct core_regset_section i386_linux_regset_sections[] =
{ ".reg", 144, "general-purpose" },
{ ".reg2", 108, "floating-point" },
{ ".reg-xfp", 512, "extended floating-point" },
{ ".reg-xstate", I386_XSTATE_MAX_SIZE, "XSAVE extended state" },
{ NULL, 0 }
};
@ -533,6 +538,7 @@ static int i386_linux_gregset_reg_offset[] =
-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,
11 * 4 /* "orig_eax" */
};
@ -560,6 +566,43 @@ static int i386_linux_sc_reg_offset[] =
0 * 4 /* %gs */
};
/* Get XSAVE extended state xcr0 from core dump. */
uint64_t
i386_linux_core_read_xcr0 (struct gdbarch *gdbarch,
struct target_ops *target, bfd *abfd)
{
asection *xstate = bfd_get_section_by_name (abfd, ".reg-xstate");
uint64_t xcr0;
if (xstate)
{
size_t size = bfd_section_size (abfd, xstate);
/* Check extended state size. */
if (size < I386_XSTATE_AVX_SIZE)
xcr0 = I386_XSTATE_SSE_MASK;
else
{
char contents[8];
if (! bfd_get_section_contents (abfd, xstate, contents,
I386_LINUX_XSAVE_XCR0_OFFSET,
8))
{
warning (_("Couldn't read `xcr0' bytes from `.reg-xstate' section in core file."));
return 0;
}
xcr0 = bfd_get_64 (abfd, contents);
}
}
else
xcr0 = I386_XSTATE_SSE_MASK;
return xcr0;
}
/* Get Linux/x86 target description from core dump. */
static const struct target_desc *
@ -568,12 +611,17 @@ i386_linux_core_read_description (struct gdbarch *gdbarch,
bfd *abfd)
{
asection *section = bfd_get_section_by_name (abfd, ".reg2");
uint64_t xcr0;
if (section == NULL)
return NULL;
/* Linux/i386. */
return tdesc_i386_linux;
xcr0 = i386_linux_core_read_xcr0 (gdbarch, target, abfd);
if ((xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK)
return tdesc_i386_avx_linux;
else
return tdesc_i386_linux;
}
static void
@ -623,6 +671,8 @@ i386_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->sc_reg_offset = i386_linux_sc_reg_offset;
tdep->sc_num_regs = ARRAY_SIZE (i386_linux_sc_reg_offset);
tdep->xsave_xcr0_offset = I386_LINUX_XSAVE_XCR0_OFFSET;
set_gdbarch_process_record (gdbarch, i386_process_record);
set_gdbarch_process_record_signal (gdbarch, i386_linux_record_signal);
@ -840,4 +890,5 @@ _initialize_i386_linux_tdep (void)
/* Initialize the Linux target description */
initialize_tdesc_i386_linux ();
initialize_tdesc_i386_avx_linux ();
}