From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 8519 invoked by alias); 6 Mar 2010 22:21:31 -0000 Received: (qmail 8499 invoked by uid 22791); 6 Mar 2010 22:21:29 -0000 X-SWARE-Spam-Status: No, hits=-0.8 required=5.0 tests=AWL,BAYES_00,NO_DNS_FOR_FROM X-Spam-Check-By: sourceware.org Received: from mga05.intel.com (HELO fmsmga101.fm.intel.com) (192.55.52.89) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 06 Mar 2010 22:21:24 +0000 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by fmsmga101.fm.intel.com with ESMTP; 06 Mar 2010 14:17:58 -0800 X-ExtLoop1: 1 Received: from gnu-6.sc.intel.com ([10.3.194.107]) by fmsmga001.fm.intel.com with ESMTP; 06 Mar 2010 14:21:10 -0800 Received: by gnu-6.sc.intel.com (Postfix, from userid 500) id E8E7B81239A; Sat, 6 Mar 2010 14:21:22 -0800 (PST) Date: Sat, 06 Mar 2010 22:21:00 -0000 From: "H.J. Lu" To: GDB Subject: PATCH: 4/6 [2nd try]: Add AVX support (amd64 changes) Message-ID: <20100306222122.GE21133@intel.com> Reply-To: "H.J. Lu" References: <20100304180219.GA10826@intel.com> <20100304180408.GA10869@intel.com> <20100304180748.GC10869@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20100304180748.GC10869@intel.com> User-Agent: Mutt/1.5.20 (2009-08-17) Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-03/txt/msg00265.txt.bz2 Hi, Here are the amd64 changes to support AVX. OK to install? Thanks. H.J. ---- 2010-03-06 H.J. Lu * amd64-linux-nat.c: Include "regset.h", "elf/common.h" and . (xstate_size): New. (xstate_size_n_of_int64): Likewise. (have_ptrace_getregset): Likewise. (amd64_linux_gregset64_reg_offset): Include 16 upper YMM registers. (amd64_linux_gregset32_reg_offset): Include 8 upper YMM registers. (amd64_linux_fetch_inferior_registers): Support PTRACE_GETFPREGS. (amd64_linux_store_inferior_registers): Likewise. (amd64_linux_read_description): Check and enable AVX target descriptions. * amd64-linux-tdep.c: Include "regset.h", "i386-linux-tdep.h" and "features/i386/amd64-avx-linux.c". (amd64_linux_regset_sections): New. (amd64_linux_core_read_description): Check and enable AVX target description. (amd64_linux_init_abi): Set xsave_xcr0_offset. Call set_gdbarch_core_regset_sections. (_initialize_amd64_linux_tdep): Call initialize_tdesc_amd64_avx_linux. * amd64-linux-tdep.h (AMD64_LINUX_ORIG_RAX_REGNUM): Replace AMD64_MXCSR_REGNUM with AMD64_YMM15H_REGNUM. (tdesc_amd64_avx_linux): New. (amd64_linux_regset_sections): Likewise. * amd64-tdep.c: Include "features/i386/amd64-avx.c". (amd64_ymm_names): New. (amd64_ymmh_names): Likewise. (amd64_register_name): Likewise. (amd64_supply_xstateregset): Likewise. (amd64_collect_xstateregset): Likewise. (amd64_supply_xsave): Likewise. (amd64_collect_xsave): Likewise. (AMD64_NUM_REGS): Removed. (amd64_pseudo_register_name): Support pseudo YMM registers. (amd64_regset_from_core_section): Support .reg-xstate section. (amd64_init_abi): Set ymmh_register_names, num_ymm_regs and ymm0h_regnum. Call set_gdbarch_register_name. (amd64_init_abi): Call initialize_tdesc_amd64_avx. * amd64-tdep.h (amd64_regnum): Add AMD64_YMM0H_REGNUM and AMD64_YMM15H_REGNUM. (AMD64_NUM_REGS): New. (amd64_supply_xsave): Likewise. (amd64_collect_xsave): Likewise. (amd64_register_name): Removed. (amd64_register_type): Likewise. diff --git a/gdb/amd64-linux-nat.c b/gdb/amd64-linux-nat.c index b9d5833..4af1112 100644 --- a/gdb/amd64-linux-nat.c +++ b/gdb/amd64-linux-nat.c @@ -23,11 +23,14 @@ #include "inferior.h" #include "gdbcore.h" #include "regcache.h" +#include "regset.h" #include "linux-nat.h" #include "amd64-linux-tdep.h" #include "gdb_assert.h" #include "gdb_string.h" +#include "elf/common.h" +#include #include #include #include @@ -52,6 +55,16 @@ #include "amd64-nat.h" #include "i386-nat.h" +/* The extended state size in bytes. */ +static unsigned int xstate_size; + +/* The extended state size in unit of int64. We use array of int64 for + better alignment. */ +static unsigned int xstate_size_n_of_int64; + +/* Does the current host support PTRACE_GETREGSET? */ +static int have_ptrace_getregset = -1; + /* Mapping between the general-purpose registers in GNU/Linux x86-64 `struct user' format and GDB's register cache layout. */ @@ -73,6 +86,8 @@ static int amd64_linux_gregset64_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, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, ORIG_RAX * 8 }; @@ -99,6 +114,7 @@ static int amd64_linux_gregset32_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, + -1, -1, -1, -1, -1, -1, -1, -1, ORIG_RAX * 8 /* "orig_eax" */ }; @@ -183,10 +199,26 @@ amd64_linux_fetch_inferior_registers (struct target_ops *ops, { elf_fpregset_t fpregs; - if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) - perror_with_name (_("Couldn't get floating point status")); + if (have_ptrace_getregset) + { + unsigned long long xstateregs[xstate_size_n_of_int64]; + struct iovec iov; + + iov.iov_base = xstateregs; + iov.iov_len = xstate_size; + if (ptrace (PTRACE_GETREGSET, tid, + (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) + perror_with_name (_("Couldn't get extended state status")); - amd64_supply_fxsave (regcache, -1, &fpregs); + amd64_supply_xsave (regcache, -1, xstateregs); + } + else + { + if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) + perror_with_name (_("Couldn't get floating point status")); + + amd64_supply_fxsave (regcache, -1, &fpregs); + } } } @@ -226,15 +258,33 @@ amd64_linux_store_inferior_registers (struct target_ops *ops, { elf_fpregset_t fpregs; - if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) - perror_with_name (_("Couldn't get floating point status")); + if (have_ptrace_getregset) + { + unsigned long long xstateregs[xstate_size_n_of_int64]; + struct iovec iov; + + iov.iov_base = xstateregs; + iov.iov_len = xstate_size; + if (ptrace (PTRACE_GETREGSET, tid, + (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) + perror_with_name (_("Couldn't get extended state status")); - amd64_collect_fxsave (regcache, regnum, &fpregs); + amd64_collect_xsave (regcache, regnum, xstateregs, 0); + + if (ptrace (PTRACE_SETREGSET, tid, + (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) + perror_with_name (_("Couldn't write extended state status")); + } + else + { + if (ptrace (PTRACE_GETFPREGS, tid, 0, (long) &fpregs) < 0) + perror_with_name (_("Couldn't get floating point status")); - if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0) - perror_with_name (_("Couldn't write floating point status")); + amd64_collect_fxsave (regcache, regnum, &fpregs); - return; + if (ptrace (PTRACE_SETFPREGS, tid, 0, (long) &fpregs) < 0) + perror_with_name (_("Couldn't write floating point status")); + } } } @@ -688,6 +738,8 @@ amd64_linux_read_description (struct target_ops *ops) { unsigned long cs; int tid; + int is_64bit; + static unsigned long long xcr0; /* GNU/Linux LWP ID's are process ID's. */ tid = TIDGET (inferior_ptid); @@ -701,10 +753,53 @@ amd64_linux_read_description (struct target_ops *ops) if (errno != 0) perror_with_name (_("Couldn't get CS register")); - if (cs == AMD64_LINUX_USER64_CS) - return tdesc_amd64_linux; + is_64bit = cs == AMD64_LINUX_USER64_CS; + + if (have_ptrace_getregset == -1) + { + unsigned long long xstateregs[(I386_XSTATE_SSE_SIZE + / sizeof (long long))]; + struct iovec iov; + + iov.iov_base = xstateregs; + iov.iov_len = I386_XSTATE_SSE_SIZE; + + /* Check if PTRACE_GETREGSET works. */ + if (ptrace (PTRACE_GETREGSET, tid, + (unsigned int) NT_X86_XSTATE, (long) &iov) < 0) + have_ptrace_getregset = 0; + else + { + have_ptrace_getregset = 1; + + /* Get XCR0 from XSAVE extended state. */ + xcr0 = xstateregs[(I386_LINUX_XSAVE_XCR0_OFFSET + / sizeof (long long))]; + + xstate_size = I386_XSTATE_SIZE (xcr0); + xstate_size_n_of_int64 = xstate_size / sizeof (long long); + } + + i386_linux_update_xstateregset (amd64_linux_regset_sections, + xstate_size); + } + + /* Check the native XCR0 only if PTRACE_GETREGSET is available. */ + if (have_ptrace_getregset + && (xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK) + { + if (is_64bit) + return tdesc_amd64_avx_linux; + else + return tdesc_i386_avx_linux; + } else - return tdesc_i386_linux; + { + if (is_64bit) + return tdesc_amd64_linux; + else + return tdesc_i386_linux; + } } /* Provide a prototype to silence -Wmissing-prototypes. */ diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c index 4ad6dc9..51722bf 100644 --- a/gdb/amd64-linux-tdep.c +++ b/gdb/amd64-linux-tdep.c @@ -28,7 +28,9 @@ #include "symtab.h" #include "gdbtypes.h" #include "reggroups.h" +#include "regset.h" #include "amd64-linux-tdep.h" +#include "i386-linux-tdep.h" #include "linux-tdep.h" #include "gdb_string.h" @@ -38,6 +40,7 @@ #include "xml-syscall.h" #include "features/i386/amd64-linux.c" +#include "features/i386/amd64-avx-linux.c" /* The syscall's XML filename for i386. */ #define XML_SYSCALL_FILENAME_AMD64 "syscalls/amd64-linux.xml" @@ -45,6 +48,15 @@ #include "record.h" #include "linux-record.h" +/* Supported register note sections. */ +struct core_regset_section amd64_linux_regset_sections[] = +{ + { ".reg", 144, "general-purpose" }, + { ".reg2", 512, "floating-point" }, + { ".reg-xstate", 0, "XSAVE extended state" }, + { NULL, 0 } +}; + /* Mapping between the general-purpose registers in `struct user' format and GDB's register cache layout. */ @@ -1250,12 +1262,17 @@ amd64_linux_core_read_description (struct gdbarch *gdbarch, bfd *abfd) { asection *section = bfd_get_section_by_name (abfd, ".reg2"); + unsigned long long xcr0; if (section == NULL) return NULL; /* Linux/x86-64. */ - return tdesc_amd64_linux; + xcr0 = i386_linux_core_read_xcr0 (gdbarch, target, abfd); + if ((xcr0 & I386_XSTATE_AVX_MASK) == I386_XSTATE_AVX_MASK) + return tdesc_amd64_avx_linux; + else + return tdesc_amd64_linux; } static void @@ -1297,6 +1314,8 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) tdep->sc_reg_offset = amd64_linux_sc_reg_offset; tdep->sc_num_regs = ARRAY_SIZE (amd64_linux_sc_reg_offset); + tdep->xsave_xcr0_offset = I386_LINUX_XSAVE_XCR0_OFFSET; + /* GNU/Linux uses SVR4-style shared libraries. */ set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_lp64_fetch_link_map_offsets); @@ -1318,6 +1337,9 @@ amd64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* GNU/Linux uses SVR4-style shared libraries. */ set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target); + /* Install supported register note sections. */ + set_gdbarch_core_regset_sections (gdbarch, amd64_linux_regset_sections); + set_gdbarch_core_read_description (gdbarch, amd64_linux_core_read_description); @@ -1517,4 +1539,5 @@ _initialize_amd64_linux_tdep (void) /* Initialize the Linux target description */ initialize_tdesc_amd64_linux (); + initialize_tdesc_amd64_avx_linux (); } diff --git a/gdb/amd64-linux-tdep.h b/gdb/amd64-linux-tdep.h index 33316fb..734f117 100644 --- a/gdb/amd64-linux-tdep.h +++ b/gdb/amd64-linux-tdep.h @@ -26,13 +26,17 @@ /* Register number for the "orig_rax" register. If this register contains a value >= 0 it is interpreted as the system call number that the kernel is supposed to restart. */ -#define AMD64_LINUX_ORIG_RAX_REGNUM (AMD64_MXCSR_REGNUM + 1) +#define AMD64_LINUX_ORIG_RAX_REGNUM (AMD64_YMM15H_REGNUM + 1) /* Total number of registers for GNU/Linux. */ #define AMD64_LINUX_NUM_REGS (AMD64_LINUX_ORIG_RAX_REGNUM + 1) /* Linux target description. */ extern struct target_desc *tdesc_amd64_linux; +extern struct target_desc *tdesc_amd64_avx_linux; + +/* Supported register note sections. */ +extern struct core_regset_section amd64_linux_regset_sections[]; /* Enum that defines the syscall identifiers for amd64 linux. Used for process record/replay, these will be translated into diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c index 8c41a8a..0c93125 100644 --- a/gdb/amd64-tdep.c +++ b/gdb/amd64-tdep.c @@ -43,6 +43,7 @@ #include "i387-tdep.h" #include "features/i386/amd64.c" +#include "features/i386/amd64-avx.c" /* Note that the AMD64 architecture was previously known as x86-64. The latter is (forever) engraved into the canonical system name as @@ -71,8 +72,21 @@ static const char *amd64_register_names[] = "mxcsr", }; -/* Total number of registers. */ -#define AMD64_NUM_REGS ARRAY_SIZE (amd64_register_names) +static const char *amd64_ymm_names[] = +{ + "ymm0", "ymm1", "ymm2", "ymm3", + "ymm4", "ymm5", "ymm6", "ymm7", + "ymm8", "ymm9", "ymm10", "ymm11", + "ymm12", "ymm13", "ymm14", "ymm15" +}; + +static const char *amd64_ymmh_names[] = +{ + "ymm0h", "ymm1h", "ymm2h", "ymm3h", + "ymm4h", "ymm5h", "ymm6h", "ymm7h", + "ymm8h", "ymm9h", "ymm10h", "ymm11h", + "ymm12h", "ymm13h", "ymm14h", "ymm15h" +}; /* The registers used to pass integer arguments during a function call. */ static int amd64_dummy_call_integer_regs[] = @@ -234,6 +248,19 @@ static const char *amd64_dword_names[] = "r8d", "r9d", "r10d", "r11d", "r12d", "r13d", "r14d", "r15d" }; +/* Return the name of register REGNUM, or the empty string if it is + an anonymous register. */ + +static const char * +amd64_register_name (struct gdbarch *gdbarch, int regnum) +{ + /* Hide the upper YMM registers. */ + if (i386_ymmh_regnum_p (gdbarch, regnum)) + return ""; + + return tdesc_register_name (gdbarch, regnum); +} + /* Return the name of register REGNUM. */ static const char * @@ -242,6 +269,8 @@ amd64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) 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_ymm_regnum_p (gdbarch, regnum)) + return amd64_ymm_names[regnum - tdep->ymm0_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)) @@ -2148,6 +2177,28 @@ amd64_collect_fpregset (const struct regset *regset, amd64_collect_fxsave (regcache, regnum, fpregs); } +/* Similar to amd64_supply_fpregset, but use XSAVE extended state. */ + +static void +amd64_supply_xstateregset (const struct regset *regset, + struct regcache *regcache, int regnum, + const void *xstateregs, size_t len) +{ + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch); + amd64_supply_xsave (regcache, regnum, xstateregs); +} + +/* Similar to amd64_collect_fpregset, but use XSAVE extended state. */ + +static void +amd64_collect_xstateregset (const struct regset *regset, + const struct regcache *regcache, + int regnum, void *xstateregs, size_t len) +{ + const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch); + amd64_collect_xsave (regcache, regnum, xstateregs, 1); +} + /* Return the appropriate register set for the core section identified by SECT_NAME and SECT_SIZE. */ @@ -2166,6 +2217,16 @@ amd64_regset_from_core_section (struct gdbarch *gdbarch, return tdep->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 i386_regset_from_core_section (gdbarch, sect_name, sect_size); } @@ -2228,6 +2289,13 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) 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.avx") != NULL) + { + tdep->ymmh_register_names = amd64_ymmh_names; + tdep->num_ymm_regs = 16; + tdep->ymm0h_regnum = AMD64_YMM0H_REGNUM; + } + tdep->num_byte_regs = 16; tdep->num_word_regs = 16; tdep->num_dword_regs = 16; @@ -2241,6 +2309,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_tdesc_pseudo_register_name (gdbarch, amd64_pseudo_register_name); + set_gdbarch_register_name (gdbarch, amd64_register_name); + /* AMD64 has an FPU and 16 SSE registers. */ tdep->st0_regnum = AMD64_ST0_REGNUM; tdep->num_xmm_regs = 16; @@ -2321,6 +2391,7 @@ void _initialize_amd64_tdep (void) { initialize_tdesc_amd64 (); + initialize_tdesc_amd64_avx (); } @@ -2356,6 +2427,30 @@ amd64_supply_fxsave (struct regcache *regcache, int regnum, } } +/* 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 = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + i387_supply_xsave (regcache, regnum, xsave); + + if (xsave && gdbarch_ptr_bit (gdbarch) == 64) + { + const gdb_byte *regs = xsave; + + if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep)) + regcache_raw_supply (regcache, I387_FISEG_REGNUM (tdep), + regs + 12); + if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep)) + regcache_raw_supply (regcache, 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 @@ -2379,3 +2474,26 @@ amd64_collect_fxsave (const struct regcache *regcache, int regnum, regcache_raw_collect (regcache, I387_FOSEG_REGNUM (tdep), regs + 20); } } + +/* Similar to amd64_collect_fxsave, but but use XSAVE extended state. */ + +void +amd64_collect_xsave (const struct regcache *regcache, int regnum, + void *xsave, int gcore) +{ + struct gdbarch *gdbarch = get_regcache_arch (regcache); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + gdb_byte *regs = xsave; + + i387_collect_xsave (regcache, regnum, xsave, gcore); + + if (gdbarch_ptr_bit (gdbarch) == 64) + { + if (regnum == -1 || regnum == I387_FISEG_REGNUM (tdep)) + regcache_raw_collect (regcache, I387_FISEG_REGNUM (tdep), + regs + 12); + if (regnum == -1 || regnum == I387_FOSEG_REGNUM (tdep)) + regcache_raw_collect (regcache, I387_FOSEG_REGNUM (tdep), + regs + 20); + } +} diff --git a/gdb/amd64-tdep.h b/gdb/amd64-tdep.h index 363479c..9f07dda 100644 --- a/gdb/amd64-tdep.h +++ b/gdb/amd64-tdep.h @@ -61,12 +61,16 @@ enum amd64_regnum AMD64_FSTAT_REGNUM = AMD64_ST0_REGNUM + 9, AMD64_XMM0_REGNUM = 40, /* %xmm0 */ AMD64_XMM1_REGNUM, /* %xmm1 */ - AMD64_MXCSR_REGNUM = AMD64_XMM0_REGNUM + 16 + AMD64_MXCSR_REGNUM = AMD64_XMM0_REGNUM + 16, + AMD64_YMM0H_REGNUM, /* %ymm0h */ + AMD64_YMM15H_REGNUM = AMD64_YMM0H_REGNUM + 15 }; /* Number of general purpose registers. */ #define AMD64_NUM_GREGS 24 +#define AMD64_NUM_REGS (AMD64_YMM15H_REGNUM + 1) + extern struct displaced_step_closure *amd64_displaced_step_copy_insn (struct gdbarch *gdbarch, CORE_ADDR from, CORE_ADDR to, struct regcache *regs); @@ -77,12 +81,6 @@ extern void amd64_displaced_step_fixup (struct gdbarch *gdbarch, extern void amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); -/* Functions from amd64-tdep.c which may be needed on architectures - with extra registers. */ - -extern const char *amd64_register_name (struct gdbarch *gdbarch, int regnum); -extern struct type *amd64_register_type (struct gdbarch *gdbarch, int regnum); - /* 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 @@ -91,6 +89,10 @@ extern struct type *amd64_register_type (struct gdbarch *gdbarch, int regnum); extern void amd64_supply_fxsave (struct regcache *regcache, int regnum, const void *fxsave); +/* Similar to amd64_supply_fxsave, but use XSAVE extended state. */ +extern void amd64_supply_xsave (struct regcache *regcache, int regnum, + const void *xsave); + /* 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 @@ -99,6 +101,10 @@ extern void amd64_supply_fxsave (struct regcache *regcache, int regnum, extern void amd64_collect_fxsave (const struct regcache *regcache, int regnum, void *fxsave); +/* Similar to amd64_collect_fxsave, but but use XSAVE extended state. */ +extern void amd64_collect_xsave (const struct regcache *regcache, + int regnum, void *xsave, int gcore); + void amd64_classify (struct type *type, enum amd64_reg_class class[2]);